Skip to content

Commit 5af75c7

Browse files
Maxim MikityanskiySaeed Mahameed
authored andcommitted
net/mlx5e: Enhanced TX MPWQE for SKBs
This commit adds support for Enhanced TX MPWQE feature in the regular (SKB) data path. A MPWQE (multi-packet work queue element) can serve multiple packets, reducing the PCI bandwidth on control traffic. Two new stats (tx*_mpwqe_blks and tx*_mpwqe_pkts) are added. The feature is on by default and controlled by the skb_tx_mpwqe private flag. In a MPWQE, eseg is shared among all packets, so eseg-based offloads (IPSEC, GENEVE, checksum) run on a separate eseg that is compared to the eseg of the current MPWQE session to decide if the new packet can be added to the same session. MPWQE is not compatible with certain offloads and features, such as TLS offload, TSO, nonlinear SKBs. If such incompatible features are in use, the driver gracefully falls back to non-MPWQE. This change has no performance impact in TCP single stream test and XDP_TX single stream test. UDP pktgen, 64-byte packets, single stream, MPWQE off: Packet rate: 16.96 Mpps (±0.12 Mpps) -> 17.01 Mpps (±0.20 Mpps) Instructions per packet: 421 -> 429 Cycles per packet: 156 -> 161 Instructions per cycle: 2.70 -> 2.67 UDP pktgen, 64-byte packets, single stream, MPWQE on: Packet rate: 16.96 Mpps (±0.12 Mpps) -> 20.94 Mpps (±0.33 Mpps) Instructions per packet: 421 -> 329 Cycles per packet: 156 -> 123 Instructions per cycle: 2.70 -> 2.67 Enabling MPWQE can reduce PCI bandwidth: PCI Gen2, pktgen at fixed rate of 36864000 pps on 24 CPU cores: Inbound PCI utilization with MPWQE off: 80.3% Inbound PCI utilization with MPWQE on: 59.0% PCI Gen3, pktgen at fixed rate of 56064000 pps on 24 CPU cores: Inbound PCI utilization with MPWQE off: 65.4% Inbound PCI utilization with MPWQE on: 49.3% Enabling MPWQE can also reduce CPU load, increasing the packet rate in case of CPU bottleneck: PCI Gen2, pktgen at full rate on 24 CPU cores: Packet rate with MPWQE off: 37.5 Mpps Packet rate with MPWQE on: 49.0 Mpps PCI Gen3, pktgen at full rate on 24 CPU cores: Packet rate with MPWQE off: 57.0 Mpps Packet rate with MPWQE on: 66.8 Mpps Burst size in all pktgen tests is 32. CPU: Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz (x86_64) NIC: Mellanox ConnectX-6 Dx GCC 10.2.0 Signed-off-by: Maxim Mikityanskiy <[email protected]> Reviewed-by: Tariq Toukan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 67044a8 commit 5af75c7

File tree

11 files changed

+240
-18
lines changed

11 files changed

+240
-18
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ enum mlx5e_priv_flag {
221221
MLX5E_PFLAG_RX_STRIDING_RQ,
222222
MLX5E_PFLAG_RX_NO_CSUM_COMPLETE,
223223
MLX5E_PFLAG_XDP_TX_MPWQE,
224+
MLX5E_PFLAG_SKB_TX_MPWQE,
224225
MLX5E_NUM_PFLAGS, /* Keep last */
225226
};
226227

@@ -305,6 +306,7 @@ struct mlx5e_sq_dma {
305306

306307
enum {
307308
MLX5E_SQ_STATE_ENABLED,
309+
MLX5E_SQ_STATE_MPWQE,
308310
MLX5E_SQ_STATE_RECOVERING,
309311
MLX5E_SQ_STATE_IPSEC,
310312
MLX5E_SQ_STATE_AM,
@@ -316,6 +318,7 @@ enum {
316318
struct mlx5e_tx_mpwqe {
317319
/* Current MPWQE session */
318320
struct mlx5e_tx_wqe *wqe;
321+
u32 bytes_count;
319322
u8 ds_count;
320323
u8 pkt_count;
321324
u8 inline_on;
@@ -334,6 +337,7 @@ struct mlx5e_txqsq {
334337
u16 pc ____cacheline_aligned_in_smp;
335338
u16 skb_fifo_pc;
336339
u32 dma_fifo_pc;
340+
struct mlx5e_tx_mpwqe mpwqe;
337341

338342
struct mlx5e_cq cq;
339343

drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ mlx5e_tx_dma_unmap(struct device *pdev, struct mlx5e_sq_dma *dma)
278278
}
279279

280280
void mlx5e_sq_xmit_simple(struct mlx5e_txqsq *sq, struct sk_buff *skb, bool xmit_more);
281+
void mlx5e_tx_mpwqe_ensure_complete(struct mlx5e_txqsq *sq);
281282

282283
static inline bool mlx5e_tx_mpwqe_is_full(struct mlx5e_tx_mpwqe *session)
283284
{

drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ static void mlx5e_xdp_mpwqe_session_start(struct mlx5e_xdpsq *sq)
205205

206206
*session = (struct mlx5e_tx_mpwqe) {
207207
.wqe = wqe,
208+
.bytes_count = 0,
208209
.ds_count = MLX5E_TX_WQE_EMPTY_DS_COUNT,
209210
.pkt_count = 0,
210211
.inline_on = mlx5e_xdp_get_inline_state(sq, session->inline_on),

drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ mlx5e_xdp_mpwqe_add_dseg(struct mlx5e_xdpsq *sq,
147147
u32 dma_len = xdptxd->len;
148148

149149
session->pkt_count++;
150+
session->bytes_count += dma_len;
150151

151152
if (session->inline_on && dma_len <= MLX5E_XDP_INLINE_WQE_SZ_THRSD) {
152153
struct mlx5_wqe_inline_seg *inline_dseg =

drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,31 +128,38 @@ static inline bool mlx5e_accel_tx_begin(struct net_device *dev,
128128
return true;
129129
}
130130

131-
static inline bool mlx5e_accel_tx_finish(struct mlx5e_priv *priv,
132-
struct mlx5e_txqsq *sq,
133-
struct sk_buff *skb,
134-
struct mlx5e_tx_wqe *wqe,
135-
struct mlx5e_accel_tx_state *state)
136-
{
137-
#ifdef CONFIG_MLX5_EN_TLS
138-
mlx5e_tls_handle_tx_wqe(sq, &wqe->ctrl, &state->tls);
139-
#endif
131+
/* Part of the eseg touched by TX offloads */
132+
#define MLX5E_ACCEL_ESEG_LEN offsetof(struct mlx5_wqe_eth_seg, mss)
140133

134+
static inline bool mlx5e_accel_tx_eseg(struct mlx5e_priv *priv,
135+
struct mlx5e_txqsq *sq,
136+
struct sk_buff *skb,
137+
struct mlx5_wqe_eth_seg *eseg)
138+
{
141139
#ifdef CONFIG_MLX5_EN_IPSEC
142140
if (test_bit(MLX5E_SQ_STATE_IPSEC, &sq->state)) {
143-
if (unlikely(!mlx5e_ipsec_handle_tx_skb(priv, &wqe->eth, skb)))
141+
if (unlikely(!mlx5e_ipsec_handle_tx_skb(priv, eseg, skb)))
144142
return false;
145143
}
146144
#endif
147145

148146
#if IS_ENABLED(CONFIG_GENEVE)
149147
if (skb->encapsulation)
150-
mlx5e_tx_tunnel_accel(skb, &wqe->eth);
148+
mlx5e_tx_tunnel_accel(skb, eseg);
151149
#endif
152150

153151
return true;
154152
}
155153

154+
static inline void mlx5e_accel_tx_finish(struct mlx5e_txqsq *sq,
155+
struct mlx5e_tx_wqe *wqe,
156+
struct mlx5e_accel_tx_state *state)
157+
{
158+
#ifdef CONFIG_MLX5_EN_TLS
159+
mlx5e_tls_handle_tx_wqe(sq, &wqe->ctrl, &state->tls);
160+
#endif
161+
}
162+
156163
static inline int mlx5e_accel_init_rx(struct mlx5e_priv *priv)
157164
{
158165
return mlx5e_ktls_init_rx(priv);

drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ bool mlx5e_tls_handle_tx_skb(struct net_device *netdev, struct mlx5e_txqsq *sq,
270270
if (!datalen)
271271
return true;
272272

273+
mlx5e_tx_mpwqe_ensure_complete(sq);
274+
273275
tls_ctx = tls_get_ctx(skb->sk);
274276
if (WARN_ON_ONCE(tls_ctx->netdev != netdev))
275277
goto err_out;

drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,7 @@ static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
19081908
return 0;
19091909
}
19101910

1911-
static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
1911+
static int set_pflag_tx_mpwqe_common(struct net_device *netdev, u32 flag, bool enable)
19121912
{
19131913
struct mlx5e_priv *priv = netdev_priv(netdev);
19141914
struct mlx5_core_dev *mdev = priv->mdev;
@@ -1920,7 +1920,7 @@ static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
19201920

19211921
new_channels.params = priv->channels.params;
19221922

1923-
MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_XDP_TX_MPWQE, enable);
1923+
MLX5E_SET_PFLAG(&new_channels.params, flag, enable);
19241924

19251925
if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
19261926
priv->channels.params = new_channels.params;
@@ -1931,13 +1931,24 @@ static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
19311931
return err;
19321932
}
19331933

1934+
static int set_pflag_xdp_tx_mpwqe(struct net_device *netdev, bool enable)
1935+
{
1936+
return set_pflag_tx_mpwqe_common(netdev, MLX5E_PFLAG_XDP_TX_MPWQE, enable);
1937+
}
1938+
1939+
static int set_pflag_skb_tx_mpwqe(struct net_device *netdev, bool enable)
1940+
{
1941+
return set_pflag_tx_mpwqe_common(netdev, MLX5E_PFLAG_SKB_TX_MPWQE, enable);
1942+
}
1943+
19341944
static const struct pflag_desc mlx5e_priv_flags[MLX5E_NUM_PFLAGS] = {
19351945
{ "rx_cqe_moder", set_pflag_rx_cqe_based_moder },
19361946
{ "tx_cqe_moder", set_pflag_tx_cqe_based_moder },
19371947
{ "rx_cqe_compress", set_pflag_rx_cqe_compress },
19381948
{ "rx_striding_rq", set_pflag_rx_striding_rq },
19391949
{ "rx_no_csum_complete", set_pflag_rx_no_csum_complete },
19401950
{ "xdp_tx_mpwqe", set_pflag_xdp_tx_mpwqe },
1951+
{ "skb_tx_mpwqe", set_pflag_skb_tx_mpwqe },
19411952
};
19421953

19431954
static int mlx5e_handle_pflag(struct net_device *netdev,

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,12 @@ static int mlx5e_calc_sq_stop_room(struct mlx5e_txqsq *sq, u8 log_sq_size)
10821082

10831083
sq->stop_room = mlx5e_tls_get_stop_room(sq);
10841084
sq->stop_room += mlx5e_stop_room_for_wqe(MLX5_SEND_WQE_MAX_WQEBBS);
1085+
if (test_bit(MLX5E_SQ_STATE_MPWQE, &sq->state))
1086+
/* A MPWQE can take up to the maximum-sized WQE + all the normal
1087+
* stop room can be taken if a new packet breaks the active
1088+
* MPWQE session and allocates its WQEs right away.
1089+
*/
1090+
sq->stop_room += mlx5e_stop_room_for_wqe(MLX5_SEND_WQE_MAX_WQEBBS);
10851091

10861092
if (WARN_ON(sq->stop_room >= sq_size)) {
10871093
netdev_err(sq->channel->netdev, "Stop room %hu is bigger than the SQ size %d\n",
@@ -1123,6 +1129,8 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
11231129
set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
11241130
if (mlx5_accel_is_tls_device(c->priv->mdev))
11251131
set_bit(MLX5E_SQ_STATE_TLS, &sq->state);
1132+
if (param->is_mpw)
1133+
set_bit(MLX5E_SQ_STATE_MPWQE, &sq->state);
11261134
err = mlx5e_calc_sq_stop_room(sq, params->log_sq_size);
11271135
if (err)
11281136
return err;
@@ -2175,6 +2183,7 @@ static void mlx5e_build_sq_param(struct mlx5e_priv *priv,
21752183
mlx5e_build_sq_param_common(priv, param);
21762184
MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size);
21772185
MLX5_SET(sqc, sqc, allow_swp, allow_swp);
2186+
param->is_mpw = MLX5E_GET_PFLAG(params, MLX5E_PFLAG_SKB_TX_MPWQE);
21782187
mlx5e_build_tx_cq_param(priv, params, &param->cqp);
21792188
}
21802189

@@ -4731,6 +4740,8 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv,
47314740
params->log_sq_size = is_kdump_kernel() ?
47324741
MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE :
47334742
MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
4743+
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_SKB_TX_MPWQE,
4744+
MLX5_CAP_ETH(mdev, enhanced_multi_pkt_send_wqe));
47344745

47354746
/* XDP SQ */
47364747
MLX5E_SET_PFLAG(params, MLX5E_PFLAG_XDP_TX_MPWQE,

drivers/net/ethernet/mellanox/mlx5/core/en_stats.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ static const struct counter_desc sw_stats_desc[] = {
9898
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_inner_bytes) },
9999
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_added_vlan_packets) },
100100
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_nop) },
101+
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_mpwqe_blks) },
102+
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_mpwqe_pkts) },
101103

102104
#ifdef CONFIG_MLX5_EN_TLS
103105
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_encrypted_packets) },
@@ -353,6 +355,8 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw)
353355
s->tx_tso_inner_bytes += sq_stats->tso_inner_bytes;
354356
s->tx_added_vlan_packets += sq_stats->added_vlan_packets;
355357
s->tx_nop += sq_stats->nop;
358+
s->tx_mpwqe_blks += sq_stats->mpwqe_blks;
359+
s->tx_mpwqe_pkts += sq_stats->mpwqe_pkts;
356360
s->tx_queue_stopped += sq_stats->stopped;
357361
s->tx_queue_wake += sq_stats->wake;
358362
s->tx_queue_dropped += sq_stats->dropped;
@@ -1556,6 +1560,8 @@ static const struct counter_desc sq_stats_desc[] = {
15561560
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) },
15571561
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, added_vlan_packets) },
15581562
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, nop) },
1563+
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, mpwqe_blks) },
1564+
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, mpwqe_pkts) },
15591565
#ifdef CONFIG_MLX5_EN_TLS
15601566
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_encrypted_packets) },
15611567
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_encrypted_bytes) },

drivers/net/ethernet/mellanox/mlx5/core/en_stats.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ struct mlx5e_sw_stats {
120120
u64 tx_tso_inner_bytes;
121121
u64 tx_added_vlan_packets;
122122
u64 tx_nop;
123+
u64 tx_mpwqe_blks;
124+
u64 tx_mpwqe_pkts;
123125
u64 rx_lro_packets;
124126
u64 rx_lro_bytes;
125127
u64 rx_ecn_mark;
@@ -348,6 +350,8 @@ struct mlx5e_sq_stats {
348350
u64 csum_partial_inner;
349351
u64 added_vlan_packets;
350352
u64 nop;
353+
u64 mpwqe_blks;
354+
u64 mpwqe_pkts;
351355
#ifdef CONFIG_MLX5_EN_TLS
352356
u64 tls_encrypted_packets;
353357
u64 tls_encrypted_bytes;

0 commit comments

Comments
 (0)