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: Rana Shahout <ranas@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
94c10f0ea3
commit
5283af899a
@ -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 {
|
|||||||
/* 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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user