aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaeed Mahameed <saeedm@mellanox.com>2016-08-28 18:13:42 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-28 23:24:15 -0400
commitfe4c988bdd1cc60402a4e3ca3976a686ea991b5a (patch)
treed003855813fc889c189d2e44f13db431afbec16b
parent9dbeea7f08f3784b152d9fb3b86beb34aad77c72 (diff)
net/mlx5e: Limit UMR length to the device's limitation
ConnectX-4 UMR (User Memory Region) MTT translation table offset in WQE is limited to U16_MAX, before this patch we ignored that limitation and requested the maximum possible UMR translation length that the netdev might need (MAX channels * MAX pages per channel). In case of a system with #cores > 32 and when linear WQE allocation fails, falling back to using UMR WQEs will cause the RQ (Receive Queue) to get stuck. Here we limit UMR length to min(U16_MAX, max required pages) (while considering the required alignments) on driver load, by default U16_MAX is sufficient since the default RX rings value guarantees that we are in range, dynamically (on set_ringparam/set_channels) we will check if the new required UMR length (num mtts) is still in range, if not, fail the request. Fixes: bc77b240b3c5 ('net/mlx5e: Add fragmented memory support for RX multi packet WQE') Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rx.c12
4 files changed, 40 insertions, 16 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 1b495efa7490..d63a1b8f9c13 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -73,8 +73,12 @@
73#define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) 73#define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER)
74#define MLX5_MPWRQ_STRIDES_PER_PAGE (MLX5_MPWRQ_NUM_STRIDES >> \ 74#define MLX5_MPWRQ_STRIDES_PER_PAGE (MLX5_MPWRQ_NUM_STRIDES >> \
75 MLX5_MPWRQ_WQE_PAGE_ORDER) 75 MLX5_MPWRQ_WQE_PAGE_ORDER)
76#define MLX5_CHANNEL_MAX_NUM_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8) * \ 76
77 BIT(MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW)) 77#define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2)
78#define MLX5E_REQUIRED_MTTS(rqs, wqes)\
79 (rqs * wqes * ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8))
80#define MLX5E_VALID_NUM_MTTS(num_mtts) (MLX5_MTT_OCTW(num_mtts) <= U16_MAX)
81
78#define MLX5_UMR_ALIGN (2048) 82#define MLX5_UMR_ALIGN (2048)
79#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128) 83#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128)
80 84
@@ -304,6 +308,7 @@ struct mlx5e_rq {
304 308
305 unsigned long state; 309 unsigned long state;
306 int ix; 310 int ix;
311 u32 mpwqe_mtt_offset;
307 312
308 struct mlx5e_rx_am am; /* Adaptive Moderation */ 313 struct mlx5e_rx_am am; /* Adaptive Moderation */
309 314
@@ -814,11 +819,6 @@ static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
814 MLX5E_MAX_NUM_CHANNELS); 819 MLX5E_MAX_NUM_CHANNELS);
815} 820}
816 821
817static inline int mlx5e_get_mtt_octw(int npages)
818{
819 return ALIGN(npages, 8) / 2;
820}
821
822extern const struct ethtool_ops mlx5e_ethtool_ops; 822extern const struct ethtool_ops mlx5e_ethtool_ops;
823#ifdef CONFIG_MLX5_CORE_EN_DCB 823#ifdef CONFIG_MLX5_CORE_EN_DCB
824extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops; 824extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 4a3757e60441..9cfe4088d008 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -373,6 +373,7 @@ static int mlx5e_set_ringparam(struct net_device *dev,
373 u16 min_rx_wqes; 373 u16 min_rx_wqes;
374 u8 log_rq_size; 374 u8 log_rq_size;
375 u8 log_sq_size; 375 u8 log_sq_size;
376 u32 num_mtts;
376 int err = 0; 377 int err = 0;
377 378
378 if (param->rx_jumbo_pending) { 379 if (param->rx_jumbo_pending) {
@@ -397,6 +398,15 @@ static int mlx5e_set_ringparam(struct net_device *dev,
397 1 << mlx5_max_log_rq_size(rq_wq_type)); 398 1 << mlx5_max_log_rq_size(rq_wq_type));
398 return -EINVAL; 399 return -EINVAL;
399 } 400 }
401
402 num_mtts = MLX5E_REQUIRED_MTTS(priv->params.num_channels, param->rx_pending);
403 if (priv->params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ &&
404 !MLX5E_VALID_NUM_MTTS(num_mtts)) {
405 netdev_info(dev, "%s: rx_pending (%d) request can't be satisfied, try to reduce.\n",
406 __func__, param->rx_pending);
407 return -EINVAL;
408 }
409
400 if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) { 410 if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
401 netdev_info(dev, "%s: tx_pending (%d) < min (%d)\n", 411 netdev_info(dev, "%s: tx_pending (%d) < min (%d)\n",
402 __func__, param->tx_pending, 412 __func__, param->tx_pending,
@@ -454,6 +464,7 @@ static int mlx5e_set_channels(struct net_device *dev,
454 unsigned int count = ch->combined_count; 464 unsigned int count = ch->combined_count;
455 bool arfs_enabled; 465 bool arfs_enabled;
456 bool was_opened; 466 bool was_opened;
467 u32 num_mtts;
457 int err = 0; 468 int err = 0;
458 469
459 if (!count) { 470 if (!count) {
@@ -472,6 +483,14 @@ static int mlx5e_set_channels(struct net_device *dev,
472 return -EINVAL; 483 return -EINVAL;
473 } 484 }
474 485
486 num_mtts = MLX5E_REQUIRED_MTTS(count, BIT(priv->params.log_rq_size));
487 if (priv->params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ &&
488 !MLX5E_VALID_NUM_MTTS(num_mtts)) {
489 netdev_info(dev, "%s: rx count (%d) request can't be satisfied, try to reduce.\n",
490 __func__, count);
491 return -EINVAL;
492 }
493
475 if (priv->params.num_channels == count) 494 if (priv->params.num_channels == count)
476 return 0; 495 return 0;
477 496
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 03d944c0077e..65360b1f6ee3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -340,6 +340,9 @@ static int mlx5e_create_rq(struct mlx5e_channel *c,
340 rq->alloc_wqe = mlx5e_alloc_rx_mpwqe; 340 rq->alloc_wqe = mlx5e_alloc_rx_mpwqe;
341 rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe; 341 rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe;
342 342
343 rq->mpwqe_mtt_offset = c->ix *
344 MLX5E_REQUIRED_MTTS(1, BIT(priv->params.log_rq_size));
345
343 rq->mpwqe_stride_sz = BIT(priv->params.mpwqe_log_stride_sz); 346 rq->mpwqe_stride_sz = BIT(priv->params.mpwqe_log_stride_sz);
344 rq->mpwqe_num_strides = BIT(priv->params.mpwqe_log_num_strides); 347 rq->mpwqe_num_strides = BIT(priv->params.mpwqe_log_num_strides);
345 rq->wqe_sz = rq->mpwqe_stride_sz * rq->mpwqe_num_strides; 348 rq->wqe_sz = rq->mpwqe_stride_sz * rq->mpwqe_num_strides;
@@ -3233,8 +3236,8 @@ static int mlx5e_create_umr_mkey(struct mlx5e_priv *priv)
3233 struct mlx5_create_mkey_mbox_in *in; 3236 struct mlx5_create_mkey_mbox_in *in;
3234 struct mlx5_mkey_seg *mkc; 3237 struct mlx5_mkey_seg *mkc;
3235 int inlen = sizeof(*in); 3238 int inlen = sizeof(*in);
3236 u64 npages = 3239 u64 npages = MLX5E_REQUIRED_MTTS(priv->profile->max_nch(mdev),
3237 priv->profile->max_nch(mdev) * MLX5_CHANNEL_MAX_NUM_MTTS; 3240 BIT(MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW));
3238 int err; 3241 int err;
3239 3242
3240 in = mlx5_vzalloc(inlen); 3243 in = mlx5_vzalloc(inlen);
@@ -3248,10 +3251,12 @@ static int mlx5e_create_umr_mkey(struct mlx5e_priv *priv)
3248 MLX5_PERM_LOCAL_WRITE | 3251 MLX5_PERM_LOCAL_WRITE |
3249 MLX5_ACCESS_MODE_MTT; 3252 MLX5_ACCESS_MODE_MTT;
3250 3253
3254 npages = min_t(u32, ALIGN(U16_MAX, 4) * 2, npages);
3255
3251 mkc->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); 3256 mkc->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
3252 mkc->flags_pd = cpu_to_be32(mdev->mlx5e_res.pdn); 3257 mkc->flags_pd = cpu_to_be32(mdev->mlx5e_res.pdn);
3253 mkc->len = cpu_to_be64(npages << PAGE_SHIFT); 3258 mkc->len = cpu_to_be64(npages << PAGE_SHIFT);
3254 mkc->xlt_oct_size = cpu_to_be32(mlx5e_get_mtt_octw(npages)); 3259 mkc->xlt_oct_size = cpu_to_be32(MLX5_MTT_OCTW(npages));
3255 mkc->log2_page_size = PAGE_SHIFT; 3260 mkc->log2_page_size = PAGE_SHIFT;
3256 3261
3257 err = mlx5_core_create_mkey(mdev, &priv->umr_mkey, in, inlen, NULL, 3262 err = mlx5_core_create_mkey(mdev, &priv->umr_mkey, in, inlen, NULL,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 9f2a16a507e0..bdc9e33a06e4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -324,9 +324,9 @@ mlx5e_copy_skb_header_fragmented_mpwqe(struct device *pdev,
324 } 324 }
325} 325}
326 326
327static u16 mlx5e_get_wqe_mtt_offset(u16 rq_ix, u16 wqe_ix) 327static u32 mlx5e_get_wqe_mtt_offset(struct mlx5e_rq *rq, u16 wqe_ix)
328{ 328{
329 return rq_ix * MLX5_CHANNEL_MAX_NUM_MTTS + 329 return rq->mpwqe_mtt_offset +
330 wqe_ix * ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8); 330 wqe_ix * ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8);
331} 331}
332 332
@@ -340,7 +340,7 @@ static void mlx5e_build_umr_wqe(struct mlx5e_rq *rq,
340 struct mlx5_wqe_data_seg *dseg = &wqe->data; 340 struct mlx5_wqe_data_seg *dseg = &wqe->data;
341 struct mlx5e_mpw_info *wi = &rq->wqe_info[ix]; 341 struct mlx5e_mpw_info *wi = &rq->wqe_info[ix];
342 u8 ds_cnt = DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS); 342 u8 ds_cnt = DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS);
343 u16 umr_wqe_mtt_offset = mlx5e_get_wqe_mtt_offset(rq->ix, ix); 343 u32 umr_wqe_mtt_offset = mlx5e_get_wqe_mtt_offset(rq, ix);
344 344
345 memset(wqe, 0, sizeof(*wqe)); 345 memset(wqe, 0, sizeof(*wqe));
346 cseg->opmod_idx_opcode = 346 cseg->opmod_idx_opcode =
@@ -353,9 +353,9 @@ static void mlx5e_build_umr_wqe(struct mlx5e_rq *rq,
353 353
354 ucseg->flags = MLX5_UMR_TRANSLATION_OFFSET_EN; 354 ucseg->flags = MLX5_UMR_TRANSLATION_OFFSET_EN;
355 ucseg->klm_octowords = 355 ucseg->klm_octowords =
356 cpu_to_be16(mlx5e_get_mtt_octw(MLX5_MPWRQ_PAGES_PER_WQE)); 356 cpu_to_be16(MLX5_MTT_OCTW(MLX5_MPWRQ_PAGES_PER_WQE));
357 ucseg->bsf_octowords = 357 ucseg->bsf_octowords =
358 cpu_to_be16(mlx5e_get_mtt_octw(umr_wqe_mtt_offset)); 358 cpu_to_be16(MLX5_MTT_OCTW(umr_wqe_mtt_offset));
359 ucseg->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE); 359 ucseg->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE);
360 360
361 dseg->lkey = sq->mkey_be; 361 dseg->lkey = sq->mkey_be;
@@ -423,7 +423,7 @@ static int mlx5e_alloc_rx_fragmented_mpwqe(struct mlx5e_rq *rq,
423{ 423{
424 struct mlx5e_mpw_info *wi = &rq->wqe_info[ix]; 424 struct mlx5e_mpw_info *wi = &rq->wqe_info[ix];
425 int mtt_sz = mlx5e_get_wqe_mtt_sz(); 425 int mtt_sz = mlx5e_get_wqe_mtt_sz();
426 u32 dma_offset = mlx5e_get_wqe_mtt_offset(rq->ix, ix) << PAGE_SHIFT; 426 u64 dma_offset = (u64)mlx5e_get_wqe_mtt_offset(rq, ix) << PAGE_SHIFT;
427 int i; 427 int i;
428 428
429 wi->umr.dma_info = kmalloc(sizeof(*wi->umr.dma_info) * 429 wi->umr.dma_info = kmalloc(sizeof(*wi->umr.dma_info) *