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);
|
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++)
|
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)
|
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);
|
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||||
int channel_ix = fallback(dev, skb);
|
int channel_ix = fallback(dev, skb);
|
||||||
int up = (netdev_get_num_tc(dev) && skb_vlan_tag_present(skb)) ?
|
int up = 0;
|
||||||
skb->vlan_tci >> VLAN_PRIO_SHIFT : 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];
|
return priv->channeltc_to_txq_map[channel_ix][up];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue