Skip to content

Commit bc77b24

Browse files
Tariq Toukandavem330
Tariq Toukan
authored andcommitted
net/mlx5e: Add fragmented memory support for RX multi packet WQE
If the allocation of a linear (physically continuous) MPWQE fails, we allocate a fragmented MPWQE. This is implemented via device's UMR (User Memory Registration) which allows to register multiple memory fragments into ConnectX hardware as a continuous buffer. UMR registration is an asynchronous operation and is done via ICO SQs. Signed-off-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d3c9bc2 commit bc77b24

File tree

5 files changed

+514
-68
lines changed

5 files changed

+514
-68
lines changed

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

+73-11
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@
7272
#define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER)
7373
#define MLX5_MPWRQ_STRIDES_PER_PAGE (MLX5_MPWRQ_NUM_STRIDES >> \
7474
MLX5_MPWRQ_WQE_PAGE_ORDER)
75+
#define MLX5_CHANNEL_MAX_NUM_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8) * \
76+
BIT(MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW))
77+
#define MLX5_UMR_ALIGN (2048)
7578
#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128)
7679

7780
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
@@ -134,6 +137,13 @@ struct mlx5e_rx_wqe {
134137
struct mlx5_wqe_data_seg data;
135138
};
136139

140+
struct mlx5e_umr_wqe {
141+
struct mlx5_wqe_ctrl_seg ctrl;
142+
struct mlx5_wqe_umr_ctrl_seg uctrl;
143+
struct mlx5_mkey_seg mkc;
144+
struct mlx5_wqe_data_seg data;
145+
};
146+
137147
#ifdef CONFIG_MLX5_CORE_EN_DCB
138148
#define MLX5E_MAX_BW_ALLOC 100 /* Max percentage of BW allocation */
139149
#define MLX5E_MIN_BW_ALLOC 1 /* Min percentage of BW allocation */
@@ -179,6 +189,7 @@ static const char vport_strings[][ETH_GSTRING_LEN] = {
179189
"tx_queue_dropped",
180190
"rx_wqe_err",
181191
"rx_mpwqe_filler",
192+
"rx_mpwqe_frag",
182193
};
183194

184195
struct mlx5e_vport_stats {
@@ -221,8 +232,9 @@ struct mlx5e_vport_stats {
221232
u64 tx_queue_dropped;
222233
u64 rx_wqe_err;
223234
u64 rx_mpwqe_filler;
235+
u64 rx_mpwqe_frag;
224236

225-
#define NUM_VPORT_COUNTERS 36
237+
#define NUM_VPORT_COUNTERS 37
226238
};
227239

228240
static const char pport_strings[][ETH_GSTRING_LEN] = {
@@ -317,6 +329,7 @@ static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
317329
"lro_bytes",
318330
"wqe_err",
319331
"mpwqe_filler",
332+
"mpwqe_frag",
320333
};
321334

322335
struct mlx5e_rq_stats {
@@ -328,7 +341,8 @@ struct mlx5e_rq_stats {
328341
u64 lro_bytes;
329342
u64 wqe_err;
330343
u64 mpwqe_filler;
331-
#define NUM_RQ_STATS 8
344+
u64 mpwqe_frag;
345+
#define NUM_RQ_STATS 9
332346
};
333347

334348
static const char sq_stats_strings[][ETH_GSTRING_LEN] = {
@@ -407,6 +421,7 @@ struct mlx5e_tstamp {
407421

408422
enum {
409423
MLX5E_RQ_STATE_POST_WQES_ENABLE,
424+
MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS,
410425
};
411426

412427
struct mlx5e_cq {
@@ -434,18 +449,14 @@ struct mlx5e_dma_info {
434449
dma_addr_t addr;
435450
};
436451

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-
443452
struct mlx5e_rq {
444453
/* data path */
445454
struct mlx5_wq_ll wq;
446455
u32 wqe_sz;
447456
struct sk_buff **skb;
448457
struct mlx5e_mpw_info *wqe_info;
458+
__be32 mkey_be;
459+
__be32 umr_mkey_be;
449460

450461
struct device *pdev;
451462
struct net_device *netdev;
@@ -466,6 +477,36 @@ struct mlx5e_rq {
466477
struct mlx5e_priv *priv;
467478
} ____cacheline_aligned_in_smp;
468479

480+
struct mlx5e_umr_dma_info {
481+
__be64 *mtt;
482+
__be64 *mtt_no_align;
483+
dma_addr_t mtt_addr;
484+
struct mlx5e_dma_info *dma_info;
485+
};
486+
487+
struct mlx5e_mpw_info {
488+
union {
489+
struct mlx5e_dma_info dma_info;
490+
struct mlx5e_umr_dma_info umr;
491+
};
492+
u16 consumed_strides;
493+
u16 skbs_frags[MLX5_MPWRQ_PAGES_PER_WQE];
494+
495+
void (*dma_pre_sync)(struct device *pdev,
496+
struct mlx5e_mpw_info *wi,
497+
u32 wqe_offset, u32 len);
498+
void (*add_skb_frag)(struct device *pdev,
499+
struct sk_buff *skb,
500+
struct mlx5e_mpw_info *wi,
501+
u32 page_idx, u32 frag_offset, u32 len);
502+
void (*copy_skb_header)(struct device *pdev,
503+
struct sk_buff *skb,
504+
struct mlx5e_mpw_info *wi,
505+
u32 page_idx, u32 offset,
506+
u32 headlen);
507+
void (*free_wqe)(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi);
508+
};
509+
469510
struct mlx5e_tx_wqe_info {
470511
u32 num_bytes;
471512
u8 num_wqebbs;
@@ -658,6 +699,7 @@ struct mlx5e_priv {
658699
u32 pdn;
659700
u32 tdn;
660701
struct mlx5_core_mkey mkey;
702+
struct mlx5_core_mkey umr_mkey;
661703
struct mlx5e_rq drop_rq;
662704

663705
struct mlx5e_channel **channel;
@@ -730,6 +772,21 @@ void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
730772
bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq);
731773
int mlx5e_alloc_rx_wqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
732774
int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, struct mlx5e_rx_wqe *wqe, u16 ix);
775+
void mlx5e_post_rx_fragmented_mpwqe(struct mlx5e_rq *rq);
776+
void mlx5e_complete_rx_linear_mpwqe(struct mlx5e_rq *rq,
777+
struct mlx5_cqe64 *cqe,
778+
u16 byte_cnt,
779+
struct mlx5e_mpw_info *wi,
780+
struct sk_buff *skb);
781+
void mlx5e_complete_rx_fragmented_mpwqe(struct mlx5e_rq *rq,
782+
struct mlx5_cqe64 *cqe,
783+
u16 byte_cnt,
784+
struct mlx5e_mpw_info *wi,
785+
struct sk_buff *skb);
786+
void mlx5e_free_rx_linear_mpwqe(struct mlx5e_rq *rq,
787+
struct mlx5e_mpw_info *wi);
788+
void mlx5e_free_rx_fragmented_mpwqe(struct mlx5e_rq *rq,
789+
struct mlx5e_mpw_info *wi);
733790
struct mlx5_cqe64 *mlx5e_get_cqe(struct mlx5e_cq *cq);
734791

735792
void mlx5e_update_stats(struct mlx5e_priv *priv);
@@ -763,7 +820,7 @@ void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
763820
int num_channels);
764821

765822
static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
766-
struct mlx5e_tx_wqe *wqe, int bf_sz)
823+
struct mlx5_wqe_ctrl_seg *ctrl, int bf_sz)
767824
{
768825
u16 ofst = MLX5_BF_OFFSET + sq->bf_offset;
769826

@@ -777,9 +834,9 @@ static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
777834
*/
778835
wmb();
779836
if (bf_sz)
780-
__iowrite64_copy(sq->uar_map + ofst, &wqe->ctrl, bf_sz);
837+
__iowrite64_copy(sq->uar_map + ofst, ctrl, bf_sz);
781838
else
782-
mlx5_write64((__be32 *)&wqe->ctrl, sq->uar_map + ofst, NULL);
839+
mlx5_write64((__be32 *)ctrl, sq->uar_map + ofst, NULL);
783840
/* flush the write-combining mapped buffer */
784841
wmb();
785842

@@ -800,6 +857,11 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
800857
MLX5E_MAX_NUM_CHANNELS);
801858
}
802859

860+
static inline int mlx5e_get_mtt_octw(int npages)
861+
{
862+
return ALIGN(npages, 8) / 2;
863+
}
864+
803865
extern const struct ethtool_ops mlx5e_ethtool_ops;
804866
#ifdef CONFIG_MLX5_CORE_EN_DCB
805867
extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops;

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

+60-4
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
179179
s->rx_csum_sw = 0;
180180
s->rx_wqe_err = 0;
181181
s->rx_mpwqe_filler = 0;
182+
s->rx_mpwqe_frag = 0;
182183
for (i = 0; i < priv->params.num_channels; i++) {
183184
rq_stats = &priv->channel[i]->rq.stats;
184185

@@ -190,6 +191,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
190191
s->rx_csum_sw += rq_stats->csum_sw;
191192
s->rx_wqe_err += rq_stats->wqe_err;
192193
s->rx_mpwqe_filler += rq_stats->mpwqe_filler;
194+
s->rx_mpwqe_frag += rq_stats->mpwqe_frag;
193195

194196
for (j = 0; j < priv->params.num_tc; j++) {
195197
sq_stats = &priv->channel[i]->sq[j].stats;
@@ -379,7 +381,6 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
379381
for (i = 0; i < wq_sz; i++) {
380382
struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(&rq->wq, i);
381383

382-
wqe->data.lkey = c->mkey_be;
383384
wqe->data.byte_count = cpu_to_be32(byte_count);
384385
}
385386

@@ -390,6 +391,8 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
390391
rq->channel = c;
391392
rq->ix = c->ix;
392393
rq->priv = c->priv;
394+
rq->mkey_be = c->mkey_be;
395+
rq->umr_mkey_be = cpu_to_be32(c->priv->umr_mkey.key);
393396

394397
return 0;
395398

@@ -1256,14 +1259,15 @@ static void mlx5e_build_icosq_param(struct mlx5e_priv *priv,
12561259
mlx5e_build_sq_param_common(priv, param);
12571260

12581261
MLX5_SET(wq, wq, log_wq_sz, log_wq_size);
1262+
MLX5_SET(sqc, sqc, reg_umr, MLX5_CAP_ETH(priv->mdev, reg_umr_sq));
12591263

12601264
param->icosq = true;
12611265
}
12621266

12631267
static void mlx5e_build_channel_param(struct mlx5e_priv *priv,
12641268
struct mlx5e_channel_param *cparam)
12651269
{
1266-
u8 icosq_log_wq_sz = 0;
1270+
u8 icosq_log_wq_sz = MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
12671271

12681272
memset(cparam, 0, sizeof(*cparam));
12691273

@@ -2458,6 +2462,13 @@ void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
24582462
indirection_rqt[i] = i % num_channels;
24592463
}
24602464

2465+
static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
2466+
{
2467+
return MLX5_CAP_GEN(mdev, striding_rq) &&
2468+
MLX5_CAP_GEN(mdev, umr_ptr_rlky) &&
2469+
MLX5_CAP_ETH(mdev, reg_umr_sq);
2470+
}
2471+
24612472
static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
24622473
struct net_device *netdev,
24632474
int num_channels)
@@ -2466,7 +2477,7 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
24662477

24672478
priv->params.log_sq_size =
24682479
MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
2469-
priv->params.rq_wq_type = MLX5_CAP_GEN(mdev, striding_rq) ?
2480+
priv->params.rq_wq_type = mlx5e_check_fragmented_striding_rq_cap(mdev) ?
24702481
MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ :
24712482
MLX5_WQ_TYPE_LINKED_LIST;
24722483

@@ -2639,6 +2650,41 @@ static void mlx5e_destroy_q_counter(struct mlx5e_priv *priv)
26392650
mlx5_core_dealloc_q_counter(priv->mdev, priv->q_counter);
26402651
}
26412652

2653+
static int mlx5e_create_umr_mkey(struct mlx5e_priv *priv)
2654+
{
2655+
struct mlx5_core_dev *mdev = priv->mdev;
2656+
struct mlx5_create_mkey_mbox_in *in;
2657+
struct mlx5_mkey_seg *mkc;
2658+
int inlen = sizeof(*in);
2659+
u64 npages =
2660+
mlx5e_get_max_num_channels(mdev) * MLX5_CHANNEL_MAX_NUM_MTTS;
2661+
int err;
2662+
2663+
in = mlx5_vzalloc(inlen);
2664+
if (!in)
2665+
return -ENOMEM;
2666+
2667+
mkc = &in->seg;
2668+
mkc->status = MLX5_MKEY_STATUS_FREE;
2669+
mkc->flags = MLX5_PERM_UMR_EN |
2670+
MLX5_PERM_LOCAL_READ |
2671+
MLX5_PERM_LOCAL_WRITE |
2672+
MLX5_ACCESS_MODE_MTT;
2673+
2674+
mkc->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
2675+
mkc->flags_pd = cpu_to_be32(priv->pdn);
2676+
mkc->len = cpu_to_be64(npages << PAGE_SHIFT);
2677+
mkc->xlt_oct_size = cpu_to_be32(mlx5e_get_mtt_octw(npages));
2678+
mkc->log2_page_size = PAGE_SHIFT;
2679+
2680+
err = mlx5_core_create_mkey(mdev, &priv->umr_mkey, in, inlen, NULL,
2681+
NULL, NULL);
2682+
2683+
kvfree(in);
2684+
2685+
return err;
2686+
}
2687+
26422688
static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
26432689
{
26442690
struct net_device *netdev;
@@ -2688,10 +2734,16 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
26882734
goto err_dealloc_transport_domain;
26892735
}
26902736

2737+
err = mlx5e_create_umr_mkey(priv);
2738+
if (err) {
2739+
mlx5_core_err(mdev, "create umr mkey failed, %d\n", err);
2740+
goto err_destroy_mkey;
2741+
}
2742+
26912743
err = mlx5e_create_tises(priv);
26922744
if (err) {
26932745
mlx5_core_warn(mdev, "create tises failed, %d\n", err);
2694-
goto err_destroy_mkey;
2746+
goto err_destroy_umr_mkey;
26952747
}
26962748

26972749
err = mlx5e_open_drop_rq(priv);
@@ -2774,6 +2826,9 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
27742826
err_destroy_tises:
27752827
mlx5e_destroy_tises(priv);
27762828

2829+
err_destroy_umr_mkey:
2830+
mlx5_core_destroy_mkey(mdev, &priv->umr_mkey);
2831+
27772832
err_destroy_mkey:
27782833
mlx5_core_destroy_mkey(mdev, &priv->mkey);
27792834

@@ -2812,6 +2867,7 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
28122867
mlx5e_destroy_rqt(priv, MLX5E_INDIRECTION_RQT);
28132868
mlx5e_close_drop_rq(priv);
28142869
mlx5e_destroy_tises(priv);
2870+
mlx5_core_destroy_mkey(priv->mdev, &priv->umr_mkey);
28152871
mlx5_core_destroy_mkey(priv->mdev, &priv->mkey);
28162872
mlx5_core_dealloc_transport_domain(priv->mdev, priv->tdn);
28172873
mlx5_core_dealloc_pd(priv->mdev, priv->pdn);

0 commit comments

Comments
 (0)