Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 461017c

Browse files
Tariq Toukandavem330
authored andcommitted
net/mlx5e: Support RX multi-packet WQE (Striding RQ)
Introduce the feature of multi-packet WQE (RX Work Queue Element) referred to as (MPWQE or Striding RQ), in which WQEs are larger and serve multiple packets each. Every WQE consists of many strides of the same size, every received packet is aligned to a beginning of a stride and is written to consecutive strides within a WQE. In the regular approach, each regular WQE is big enough to be capable of serving one received packet of any size up to MTU or 64K in case of device LRO is enabled, making it very wasteful when dealing with small packets or device LRO is enabled. For its flexibility, MPWQE allows a better memory utilization (implying improvements in CPU utilization and packet rate) as packets consume strides according to their size, preserving the rest of the WQE to be available for other packets. MPWQE default configuration: Num of WQEs = 16 Strides Per WQE = 2048 Stride Size = 64 byte The default WQEs memory footprint went from 1024*mtu (~1.5MB) to 16 * 2048 * 64 = 2MB per ring. However, HW LRO can now be supported at no additional cost in memory footprint, and hence we turn it on by default and get an even better performance. Performance tested on ConnectX4-Lx 50G. To isolate the feature under test, the numbers below were measured with HW LRO turned off. We verified that the performance just improves when LRO is turned back on. * Netperf single TCP stream: - BW raised by 10-15% for representative packet sizes: default, 64B, 1024B, 1478B, 65536B. * Netperf multi TCP stream: - No degradation, line rate reached. * Pktgen: packet rate raised by 2-10% for traffic of different message sizes: 64B, 128B, 256B, 1024B, and 1500B. * Pktgen: packet loss in bursts of small messages (64byte), single stream: - | num packets | packets loss before | packets loss after | 2K | ~ 1K | 0 | 8K | ~ 6K | 0 | 16K | ~13K | 0 | 32K | ~28K | 0 | 64K | ~57K | ~24K As expected as the driver can receive as many small packets (<=64B) as the number of total strides in the ring (default = 2048 * 16) vs. 1024 (default ring size regardless of packets size) before this feature. Signed-off-by: Tariq Toukan <[email protected]> Signed-off-by: Achiad Shochat <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2f48af1 commit 461017c

File tree

5 files changed

+349
-44
lines changed

5 files changed

+349
-44
lines changed

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

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,30 @@
5757
#define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE 0xa
5858
#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE 0xd
5959

60+
#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW 0x1
61+
#define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW 0x4
62+
#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW 0x6
63+
64+
#define MLX5_MPWRQ_LOG_NUM_STRIDES 11 /* >= 9, HW restriction */
65+
#define MLX5_MPWRQ_LOG_STRIDE_SIZE 6 /* >= 6, HW restriction */
66+
#define MLX5_MPWRQ_NUM_STRIDES BIT(MLX5_MPWRQ_LOG_NUM_STRIDES)
67+
#define MLX5_MPWRQ_STRIDE_SIZE BIT(MLX5_MPWRQ_LOG_STRIDE_SIZE)
68+
#define MLX5_MPWRQ_LOG_WQE_SZ (MLX5_MPWRQ_LOG_NUM_STRIDES +\
69+
MLX5_MPWRQ_LOG_STRIDE_SIZE)
70+
#define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \
71+
MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT : 0)
72+
#define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER)
73+
#define MLX5_MPWRQ_STRIDES_PER_PAGE (MLX5_MPWRQ_NUM_STRIDES >> \
74+
MLX5_MPWRQ_WQE_PAGE_ORDER)
75+
#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128)
76+
6077
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
6178
#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC 0x10
6279
#define MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS 0x20
6380
#define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC 0x10
6481
#define MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS 0x20
6582
#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES 0x80
83+
#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW 0x2
6684

6785
#define MLX5E_LOG_INDIR_RQT_SIZE 0x7
6886
#define MLX5E_INDIR_RQT_SIZE BIT(MLX5E_LOG_INDIR_RQT_SIZE)
@@ -74,6 +92,38 @@
7492
#define MLX5E_NUM_MAIN_GROUPS 9
7593
#define MLX5E_NET_IP_ALIGN 2
7694

95+
static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
96+
{
97+
switch (wq_type) {
98+
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
99+
return min_t(u16, MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW,
100+
wq_size / 2);
101+
default:
102+
return min_t(u16, MLX5E_PARAMS_DEFAULT_MIN_RX_WQES,
103+
wq_size / 2);
104+
}
105+
}
106+
107+
static inline int mlx5_min_log_rq_size(int wq_type)
108+
{
109+
switch (wq_type) {
110+
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
111+
return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW;
112+
default:
113+
return MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
114+
}
115+
}
116+
117+
static inline int mlx5_max_log_rq_size(int wq_type)
118+
{
119+
switch (wq_type) {
120+
case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
121+
return MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW;
122+
default:
123+
return MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
124+
}
125+
}
126+
77127
struct mlx5e_tx_wqe {
78128
struct mlx5_wqe_ctrl_seg ctrl;
79129
struct mlx5_wqe_eth_seg eth;
@@ -128,6 +178,7 @@ static const char vport_strings[][ETH_GSTRING_LEN] = {
128178
"tx_queue_wake",
129179
"tx_queue_dropped",
130180
"rx_wqe_err",
181+
"rx_mpwqe_filler",
131182
};
132183

133184
struct mlx5e_vport_stats {
@@ -169,8 +220,9 @@ struct mlx5e_vport_stats {
169220
u64 tx_queue_wake;
170221
u64 tx_queue_dropped;
171222
u64 rx_wqe_err;
223+
u64 rx_mpwqe_filler;
172224

173-
#define NUM_VPORT_COUNTERS 35
225+
#define NUM_VPORT_COUNTERS 36
174226
};
175227

176228
static const char pport_strings[][ETH_GSTRING_LEN] = {
@@ -263,7 +315,8 @@ static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
263315
"csum_sw",
264316
"lro_packets",
265317
"lro_bytes",
266-
"wqe_err"
318+
"wqe_err",
319+
"mpwqe_filler",
267320
};
268321

269322
struct mlx5e_rq_stats {
@@ -274,7 +327,8 @@ struct mlx5e_rq_stats {
274327
u64 lro_packets;
275328
u64 lro_bytes;
276329
u64 wqe_err;
277-
#define NUM_RQ_STATS 7
330+
u64 mpwqe_filler;
331+
#define NUM_RQ_STATS 8
278332
};
279333

280334
static const char sq_stats_strings[][ETH_GSTRING_LEN] = {
@@ -318,6 +372,7 @@ struct mlx5e_stats {
318372

319373
struct mlx5e_params {
320374
u8 log_sq_size;
375+
u8 rq_wq_type;
321376
u8 log_rq_size;
322377
u16 num_channels;
323378
u8 num_tc;
@@ -374,11 +429,23 @@ typedef void (*mlx5e_fp_handle_rx_cqe)(struct mlx5e_rq *rq,
374429
typedef int (*mlx5e_fp_alloc_wqe)(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe,
375430
u16 ix);
376431

432+
struct mlx5e_dma_info {
433+
struct page *page;
434+
dma_addr_t addr;
435+
};
436+
437+
struct mlx5e_mpw_info {
438+
struct mlx5e_dma_info dma_info;
439+
u16 consumed_strides;
440+
u16 skbs_frags[MLX5_MPWRQ_PAGES_PER_WQE];
441+
};
442+
377443
struct mlx5e_rq {
378444
/* data path */
379445
struct mlx5_wq_ll wq;
380446
u32 wqe_sz;
381447
struct sk_buff **skb;
448+
struct mlx5e_mpw_info *wqe_info;
382449

383450
struct device *pdev;
384451
struct net_device *netdev;
@@ -393,6 +460,7 @@ struct mlx5e_rq {
393460

394461
/* control */
395462
struct mlx5_wq_ctrl wq_ctrl;
463+
u8 wq_type;
396464
u32 rqn;
397465
struct mlx5e_channel *channel;
398466
struct mlx5e_priv *priv;
@@ -649,9 +717,12 @@ void mlx5e_cq_error_event(struct mlx5_core_cq *mcq, enum mlx5_event event);
649717
int mlx5e_napi_poll(struct napi_struct *napi, int budget);
650718
bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
651719
int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget);
720+
652721
void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
722+
void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
653723
bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq);
654724
int mlx5e_alloc_rx_wqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
725+
int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
655726
struct mlx5_cqe64 *mlx5e_get_cqe(struct mlx5e_cq *cq);
656727

657728
void mlx5e_update_stats(struct mlx5e_priv *priv);

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,9 @@ static void mlx5e_get_ringparam(struct net_device *dev,
273273
struct ethtool_ringparam *param)
274274
{
275275
struct mlx5e_priv *priv = netdev_priv(dev);
276+
int rq_wq_type = priv->params.rq_wq_type;
276277

277-
param->rx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE;
278+
param->rx_max_pending = 1 << mlx5_max_log_rq_size(rq_wq_type);
278279
param->tx_max_pending = 1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE;
279280
param->rx_pending = 1 << priv->params.log_rq_size;
280281
param->tx_pending = 1 << priv->params.log_sq_size;
@@ -285,6 +286,7 @@ static int mlx5e_set_ringparam(struct net_device *dev,
285286
{
286287
struct mlx5e_priv *priv = netdev_priv(dev);
287288
bool was_opened;
289+
int rq_wq_type = priv->params.rq_wq_type;
288290
u16 min_rx_wqes;
289291
u8 log_rq_size;
290292
u8 log_sq_size;
@@ -300,16 +302,16 @@ static int mlx5e_set_ringparam(struct net_device *dev,
300302
__func__);
301303
return -EINVAL;
302304
}
303-
if (param->rx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)) {
305+
if (param->rx_pending < (1 << mlx5_min_log_rq_size(rq_wq_type))) {
304306
netdev_info(dev, "%s: rx_pending (%d) < min (%d)\n",
305307
__func__, param->rx_pending,
306-
1 << MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE);
308+
1 << mlx5_min_log_rq_size(rq_wq_type));
307309
return -EINVAL;
308310
}
309-
if (param->rx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE)) {
311+
if (param->rx_pending > (1 << mlx5_max_log_rq_size(rq_wq_type))) {
310312
netdev_info(dev, "%s: rx_pending (%d) > max (%d)\n",
311313
__func__, param->rx_pending,
312-
1 << MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE);
314+
1 << mlx5_max_log_rq_size(rq_wq_type));
313315
return -EINVAL;
314316
}
315317
if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
@@ -327,8 +329,7 @@ static int mlx5e_set_ringparam(struct net_device *dev,
327329

328330
log_rq_size = order_base_2(param->rx_pending);
329331
log_sq_size = order_base_2(param->tx_pending);
330-
min_rx_wqes = min_t(u16, param->rx_pending - 1,
331-
MLX5E_PARAMS_DEFAULT_MIN_RX_WQES);
332+
min_rx_wqes = mlx5_min_rx_wqes(rq_wq_type, param->rx_pending);
332333

333334
if (log_rq_size == priv->params.log_rq_size &&
334335
log_sq_size == priv->params.log_sq_size &&

0 commit comments

Comments
 (0)