net/mlx5e: Replace reciprocal_scale in TX select queue function
authorShay Agroskin <shayag@mellanox.com>
Sun, 28 Apr 2019 07:14:23 +0000 (10:14 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 7 Jun 2019 21:40:37 +0000 (14:40 -0700)
The TX queue index returned by the fallback function ranges
between [0,NUM CHANNELS - 1] if QoS isn't set and
[0, (NUM CHANNELS)*(NUM TCs) -1] otherwise.

Our HW uses different TC mapping than the fallback function
(which is denoted as 'up', user priority) so we only need to extract
a channel number out of the returned value.

Since (NUM CHANNELS)*(NUM TCs) is a relatively small number, using
reciprocal scale almost always returns zero.
We instead access the 'txq2sq' table to extract the sq (and with it the
channel number) associated with the tx queue, thus getting
a more evenly distributed channel number.

Perf:

Rx/Tx side with Intel(R) Xeon(R) Silver 4108 CPU @ 1.80GHz and ConnectX-5.
Used 'iperf' UDP traffic, 10 threads, and priority 5.

Before: 0.566Mpps
After:  2.37Mpps

As expected, releasing the existing bottleneck of steering all traffic
to TX queue zero significantly improves transmission rates.

Fixes: 7ccdd0841b30 ("net/mlx5e: Fix select queue callback")
Signed-off-by: Shay Agroskin <shayag@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c

index ab027f57725c9630951a04ed748448e3a80c0350..cc6797e24571d76d680e871f955cdf233aabba02 100644 (file)
@@ -385,6 +385,7 @@ struct mlx5e_txqsq {
        /* control path */
        struct mlx5_wq_ctrl        wq_ctrl;
        struct mlx5e_channel      *channel;
+       int                        ch_ix;
        int                        txq_ix;
        u32                        rate_limit;
        struct work_struct         recover_work;
index cd490ae330d877cc04cd22c03c509b00030d64db..564692227c16b239bc0520599922e83123b17d86 100644 (file)
@@ -1082,6 +1082,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
        sq->clock     = &mdev->clock;
        sq->mkey_be   = c->mkey_be;
        sq->channel   = c;
+       sq->ch_ix     = c->ix;
        sq->txq_ix    = txq_ix;
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
        sq->min_inline_mode = params->tx_min_inline_mode;
index 195a7d903cecbb18bf14047b670bfb4552b27f52..701e5dc75bb05d61d442ad635de540f93ee4d87e 100644 (file)
@@ -113,13 +113,13 @@ static inline int mlx5e_get_dscp_up(struct mlx5e_priv *priv, struct sk_buff *skb
 u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
                       struct net_device *sb_dev)
 {
-       int channel_ix = netdev_pick_tx(dev, skb, NULL);
+       int txq_ix = netdev_pick_tx(dev, skb, NULL);
        struct mlx5e_priv *priv = netdev_priv(dev);
        u16 num_channels;
        int up = 0;
 
        if (!netdev_get_num_tc(dev))
-               return channel_ix;
+               return txq_ix;
 
 #ifdef CONFIG_MLX5_CORE_EN_DCB
        if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP)
@@ -129,14 +129,14 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
                if (skb_vlan_tag_present(skb))
                        up = skb_vlan_tag_get_prio(skb);
 
-       /* channel_ix can be larger than num_channels since
+       /* txq_ix can be larger than num_channels since
         * dev->num_real_tx_queues = num_channels * num_tc
         */
        num_channels = priv->channels.params.num_channels;
-       if (channel_ix >= num_channels)
-               channel_ix = reciprocal_scale(channel_ix, num_channels);
+       if (txq_ix >= num_channels)
+               txq_ix = priv->txq2sq[txq_ix]->ch_ix;
 
-       return priv->channel_tc2txq[channel_ix][up];
+       return priv->channel_tc2txq[txq_ix][up];
 }
 
 static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)