History

net/mlx5e: Avoid unbounded peer devices when unpairing TC hairpin rules

If the peer device was already unbound, then do not attempt to modify it's resources, otherwise we will crash on dereferencing non-existing device.

Alaa Hleihel committed 8 years ago

Commit 4d8fcf21 parent 43955a46 files · +71 −3Browse files

Unified · Split

6 files
  1. drivers/net/ethernet/mellanox/mlx5/core/en.h +1 −0
  2. drivers/net/ethernet/mellanox/mlx5/core/en/fs.h +2 −0
  3. drivers/net/ethernet/mellanox/mlx5/core/en_main.c +1 −1
  4. drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +61 −1
  5. drivers/net/ethernet/mellanox/mlx5/core/transobj.c +4 −1
  6. include/linux/mlx5/transobj.h +2 −0
drivers/net/ethernet/mellanox/mlx5/core/en.h+1−0
@@ -54,6 +54,7 @@ · 53 unmodified lines
54#include "en_stats.h"54#include "en_stats.h"
55#include "en/fs.h"55#include "en/fs.h"
56 56
57extern const struct net_device_ops mlx5e_netdev_ops;
57struct page_pool;58struct page_pool;
58 59
59#define MLX5E_METADATA_ETHER_TYPE (0x8CE4)60#define MLX5E_METADATA_ETHER_TYPE (0x8CE4)
drivers/net/ethernet/mellanox/mlx5/core/en/fs.h+2−0
@@ -16,6 +16,8 @@ struct mlx5e_tc_table { · 15 unmodified lines
16 16
17 DECLARE_HASHTABLE(mod_hdr_tbl, 8);17 DECLARE_HASHTABLE(mod_hdr_tbl, 8);
18 DECLARE_HASHTABLE(hairpin_tbl, 8);18 DECLARE_HASHTABLE(hairpin_tbl, 8);
19
20 struct notifier_block netdevice_nb;
19};21};
20 22
21struct mlx5e_flow_table {23struct mlx5e_flow_table {
drivers/net/ethernet/mellanox/mlx5/core/en_main.c+1−1
@@ -4315,7 +4315,7 @@ static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp) · 4314 unmodified lines
4315 }4315 }
4316}4316}
4317 4317
4318static const struct net_device_ops mlx5e_netdev_ops = {4318const struct net_device_ops mlx5e_netdev_ops = {
4319 .ndo_open = mlx5e_open,4319 .ndo_open = mlx5e_open,
4320 .ndo_stop = mlx5e_close,4320 .ndo_stop = mlx5e_close,
4321 .ndo_start_xmit = mlx5e_xmit,4321 .ndo_start_xmit = mlx5e_xmit,
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c+61−1
@@ -2946,14 +2946,71 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv, · 2945 unmodified lines
2946 return 0;2946 return 0;
2947}2947}
2948 2948
2949static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,
2950 struct mlx5e_priv *peer_priv)
2951{
2952 struct mlx5_core_dev *peer_mdev = peer_priv->mdev;
2953 struct mlx5e_hairpin_entry *hpe;
2954 u16 peer_vhca_id;
2955 int bkt;
2956
2957 if (!same_hw_devs(priv, peer_priv))
2958 return;
2959
2960 peer_vhca_id = MLX5_CAP_GEN(peer_mdev, vhca_id);
2961
2962 hash_for_each(priv->fs.tc.hairpin_tbl, bkt, hpe, hairpin_hlist) {
2963 if (hpe->peer_vhca_id == peer_vhca_id)
2964 hpe->hp->pair->peer_gone = true;
2965 }
2966}
2967
2968static int mlx5e_tc_netdev_event(struct notifier_block *this,
2969 unsigned long event, void *ptr)
2970{
2971 struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
2972 struct mlx5e_flow_steering *fs;
2973 struct mlx5e_priv *peer_priv;
2974 struct mlx5e_tc_table *tc;
2975 struct mlx5e_priv *priv;
2976
2977 if (ndev->netdev_ops != &mlx5e_netdev_ops ||
2978 event != NETDEV_UNREGISTER ||
2979 ndev->reg_state == NETREG_REGISTERED)
2980 return NOTIFY_DONE;
2981
2982 tc = container_of(this, struct mlx5e_tc_table, netdevice_nb);
2983 fs = container_of(tc, struct mlx5e_flow_steering, tc);
2984 priv = container_of(fs, struct mlx5e_priv, fs);
2985 peer_priv = netdev_priv(ndev);
2986 if (priv == peer_priv ||
2987 !(priv->netdev->features & NETIF_F_HW_TC))
2988 return NOTIFY_DONE;
2989
2990 mlx5e_tc_hairpin_update_dead_peer(priv, peer_priv);
2991
2992 return NOTIFY_DONE;
2993}
2994
2949int mlx5e_tc_nic_init(struct mlx5e_priv *priv)2995int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
2950{2996{
2951 struct mlx5e_tc_table *tc = &priv->fs.tc;2997 struct mlx5e_tc_table *tc = &priv->fs.tc;
2998 int err;
2952 2999
2953 hash_init(tc->mod_hdr_tbl);3000 hash_init(tc->mod_hdr_tbl);
2954 hash_init(tc->hairpin_tbl);3001 hash_init(tc->hairpin_tbl);
2955 3002
2956 return rhashtable_init(&tc->ht, &tc_ht_params);3003 err = rhashtable_init(&tc->ht, &tc_ht_params);
3004 if (err)
3005 return err;
3006
3007 tc->netdevice_nb.notifier_call = mlx5e_tc_netdev_event;
3008 if (register_netdevice_notifier(&tc->netdevice_nb)) {
3009 tc->netdevice_nb.notifier_call = NULL;
3010 mlx5_core_warn(priv->mdev, "Failed to register netdev notifier\n");
3011 }
3012
3013 return err;
2957}3014}
2958 3015
2959static void _mlx5e_tc_del_flow(void *ptr, void *arg)3016static void _mlx5e_tc_del_flow(void *ptr, void *arg)
@@ -2969,6 +3026,9 @@ void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) · 9 unmodified lines
2969{3026{
2970 struct mlx5e_tc_table *tc = &priv->fs.tc;3027 struct mlx5e_tc_table *tc = &priv->fs.tc;
2971 3028
3029 if (tc->netdevice_nb.notifier_call)
3030 unregister_netdevice_notifier(&tc->netdevice_nb);
3031
2972 rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL);3032 rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL);
2973 3033
2974 if (!IS_ERR_OR_NULL(tc->t)) {3034 if (!IS_ERR_OR_NULL(tc->t)) {
drivers/net/ethernet/mellanox/mlx5/core/transobj.c+4−1
@@ -475,7 +475,8 @@ static void mlx5_hairpin_destroy_queues(struct mlx5_hairpin *hp) · 474 unmodified lines
475 475
476 for (i = 0; i < hp->num_channels; i++) {476 for (i = 0; i < hp->num_channels; i++) {
477 mlx5_core_destroy_rq(hp->func_mdev, hp->rqn[i]);477 mlx5_core_destroy_rq(hp->func_mdev, hp->rqn[i]);
478 mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]);478 if (!hp->peer_gone)
479 mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]);
479 }480 }
480}481}
481 482
@@ -567,6 +568,8 @@ static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp) · 85 unmodified lines
567 MLX5_RQC_STATE_RST, 0, 0);568 MLX5_RQC_STATE_RST, 0, 0);
568 569
569 /* unset peer SQs */570 /* unset peer SQs */
571 if (hp->peer_gone)
572 return;
570 for (i = 0; i < hp->num_channels; i++)573 for (i = 0; i < hp->num_channels; i++)
571 mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY,574 mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY,
572 MLX5_SQC_STATE_RST, 0, 0);575 MLX5_SQC_STATE_RST, 0, 0);
include/linux/mlx5/transobj.h+2−0
@@ -90,6 +90,8 @@ struct mlx5_hairpin { · 89 unmodified lines
90 90
91 u32 *rqn;91 u32 *rqn;
92 u32 *sqn;92 u32 *sqn;
93
94 bool peer_gone;
93};95};
94 96
95struct mlx5_hairpin *97struct mlx5_hairpin *

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t