Commit 5283af89 authored by Rana Shahout's avatar Rana Shahout Committed by David S. Miller

net/mlx5e: Avoid accessing NULL pointer at ndo_select_queue

To avoid multiply/division operations on the data path,
we hold a {channel, tc}==>txq mapping table.
We held this mapping table inside the channel object that is
being destroyed upon some configuration operations (e.g MTU change).
So in case ndo_select_queue occurs during such a configuration operation,
it may access a NULL channel pointer, resulting in kernel panic.
To fix this issue we moved the {channel, tc}==>txq mapping table
outside the channel object so that it will be available also
during such configuration operations.
Signed-off-by: default avatarRana Shahout <ranas@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 94c10f0e
...@@ -405,7 +405,6 @@ struct mlx5e_channel { ...@@ -405,7 +405,6 @@ struct mlx5e_channel {
__be32 mkey_be; __be32 mkey_be;
u8 num_tc; u8 num_tc;
unsigned long flags; unsigned long flags;
int tc_to_txq_map[MLX5E_MAX_NUM_TC];
/* control */ /* control */
struct mlx5e_priv *priv; struct mlx5e_priv *priv;
...@@ -475,6 +474,7 @@ struct mlx5e_priv { ...@@ -475,6 +474,7 @@ struct mlx5e_priv {
/* priv data path fields - start */ /* priv data path fields - start */
int default_vlan_prio; int default_vlan_prio;
struct mlx5e_sq **txq_to_sq_map; struct mlx5e_sq **txq_to_sq_map;
int channeltc_to_txq_map[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
/* priv data path fields - end */ /* priv data path fields - end */
unsigned long state; unsigned long state;
......
...@@ -949,13 +949,13 @@ static void mlx5e_close_sqs(struct mlx5e_channel *c) ...@@ -949,13 +949,13 @@ static void mlx5e_close_sqs(struct mlx5e_channel *c)
mlx5e_close_sq(&c->sq[tc]); mlx5e_close_sq(&c->sq[tc]);
} }
static void mlx5e_build_tc_to_txq_map(struct mlx5e_channel *c, static void mlx5e_build_channeltc_to_txq_map(struct mlx5e_priv *priv, int ix)
int num_channels)
{ {
int i; int i;
for (i = 0; i < MLX5E_MAX_NUM_TC; i++) for (i = 0; i < MLX5E_MAX_NUM_TC; i++)
c->tc_to_txq_map[i] = c->ix + i * num_channels; priv->channeltc_to_txq_map[ix][i] =
ix + i * priv->params.num_channels;
} }
static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
...@@ -979,7 +979,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, ...@@ -979,7 +979,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
c->mkey_be = cpu_to_be32(priv->mr.key); c->mkey_be = cpu_to_be32(priv->mr.key);
c->num_tc = priv->params.num_tc; c->num_tc = priv->params.num_tc;
mlx5e_build_tc_to_txq_map(c, priv->params.num_channels); mlx5e_build_channeltc_to_txq_map(priv, ix);
netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64); netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64);
......
...@@ -106,7 +106,7 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb, ...@@ -106,7 +106,7 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
priv->default_vlan_prio; priv->default_vlan_prio;
int tc = netdev_get_prio_tc_map(dev, up); int tc = netdev_get_prio_tc_map(dev, up);
return priv->channel[channel_ix]->tc_to_txq_map[tc]; return priv->channeltc_to_txq_map[channel_ix][tc];
} }
static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq, static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment