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: 08fb1dacdd
('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…
Reference in New Issue