Skip to content

Commit

Permalink
net/mlx5e: Fix select queue callback
Browse files Browse the repository at this point in the history
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: 08fb1da ('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>
  • Loading branch information
Rana Shahout authored and davem330 committed Jul 1, 2016
1 parent e3a19b5 commit 7ccdd08
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
5 changes: 4 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 14 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down

0 comments on commit 7ccdd08

Please sign in to comment.