mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-15 09:34:17 +00:00
net/mlx5e: Fix select queue callback
The default fallback function used by mlx5e select queue can return any TX queues in range [0..dev->num_real_tx_queues). The current implementation assumes that the fallback function returns a number in the range [0.. number of channels). Actually dev->num_real_tx_queues = (number of channels) * dev->num_tc; which is more than the expected range if num_tc is configured and could lead to crashes. To fix this we test if num_tc is not configured we can safely return the fallback suggestion, if not we will reciprocal_scale the fallback result and normalize it to the desired range. Fixes: 08fb1dacdd76 ('net/mlx5e: Support DCBNL IEEE ETS') Signed-off-by: Rana Shahout <ranas@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Reported-by: Doug Ledford <dledford@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e3a19b53cb
commit
7ccdd0841b
@ -1707,8 +1707,11 @@ static void mlx5e_netdev_set_tcs(struct net_device *netdev)
|
||||
|
||||
netdev_set_num_tc(netdev, ntc);
|
||||
|
||||
/* Map netdev TCs to offset 0
|
||||
* We have our own UP to TXQ mapping for QoS
|
||||
*/
|
||||
for (tc = 0; tc < ntc; tc++)
|
||||
netdev_set_tc_queue(netdev, tc, nch, tc * nch);
|
||||
netdev_set_tc_queue(netdev, tc, nch, 0);
|
||||
}
|
||||
|
||||
int mlx5e_open_locked(struct net_device *netdev)
|
||||
|
@ -110,8 +110,20 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
int channel_ix = fallback(dev, skb);
|
||||
int up = (netdev_get_num_tc(dev) && skb_vlan_tag_present(skb)) ?
|
||||
skb->vlan_tci >> VLAN_PRIO_SHIFT : 0;
|
||||
int up = 0;
|
||||
|
||||
if (!netdev_get_num_tc(dev))
|
||||
return channel_ix;
|
||||
|
||||
if (skb_vlan_tag_present(skb))
|
||||
up = skb->vlan_tci >> VLAN_PRIO_SHIFT;
|
||||
|
||||
/* channel_ix can be larger than num_channels since
|
||||
* dev->num_real_tx_queues = num_channels * num_tc
|
||||
*/
|
||||
if (channel_ix >= priv->params.num_channels)
|
||||
channel_ix = reciprocal_scale(channel_ix,
|
||||
priv->params.num_channels);
|
||||
|
||||
return priv->channeltc_to_txq_map[channel_ix][up];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user