diff options
author | Eli Cohen <eli@mellanox.com> | 2016-10-27 09:36:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-26 02:24:34 -0500 |
commit | dae9f4f144119229e4218f92ec0876549460ed45 (patch) | |
tree | 7d54ce2aa649728a72548c500e1da0b6c2170f90 | |
parent | 4db097fe49ea9dc608e614fbf46bc7463be0eb76 (diff) |
IB/mlx5: Fix reported max SGE calculation
commit 288c01b746aab484651391ca6d64b585d3eb5ec6 upstream.
Add the 512 bytes limit of RDMA READ and the size of remote
address to the max SGE calculation.
Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters')
Signed-off-by: Eli Cohen <eli@mellanox.com>
Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/infiniband/hw/mlx5/main.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/qp.c | 29 |
2 files changed, 33 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 32b09f059c84..4cab29ea394c 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -496,6 +496,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, | |||
496 | struct mlx5_ib_dev *dev = to_mdev(ibdev); | 496 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
497 | struct mlx5_core_dev *mdev = dev->mdev; | 497 | struct mlx5_core_dev *mdev = dev->mdev; |
498 | int err = -ENOMEM; | 498 | int err = -ENOMEM; |
499 | int max_sq_desc; | ||
499 | int max_rq_sg; | 500 | int max_rq_sg; |
500 | int max_sq_sg; | 501 | int max_sq_sg; |
501 | u64 min_page_size = 1ull << MLX5_CAP_GEN(mdev, log_pg_sz); | 502 | u64 min_page_size = 1ull << MLX5_CAP_GEN(mdev, log_pg_sz); |
@@ -618,9 +619,10 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, | |||
618 | props->max_qp_wr = 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz); | 619 | props->max_qp_wr = 1 << MLX5_CAP_GEN(mdev, log_max_qp_sz); |
619 | max_rq_sg = MLX5_CAP_GEN(mdev, max_wqe_sz_rq) / | 620 | max_rq_sg = MLX5_CAP_GEN(mdev, max_wqe_sz_rq) / |
620 | sizeof(struct mlx5_wqe_data_seg); | 621 | sizeof(struct mlx5_wqe_data_seg); |
621 | max_sq_sg = (MLX5_CAP_GEN(mdev, max_wqe_sz_sq) - | 622 | max_sq_desc = min_t(int, MLX5_CAP_GEN(mdev, max_wqe_sz_sq), 512); |
622 | sizeof(struct mlx5_wqe_ctrl_seg)) / | 623 | max_sq_sg = (max_sq_desc - sizeof(struct mlx5_wqe_ctrl_seg) - |
623 | sizeof(struct mlx5_wqe_data_seg); | 624 | sizeof(struct mlx5_wqe_raddr_seg)) / |
625 | sizeof(struct mlx5_wqe_data_seg); | ||
624 | props->max_sge = min(max_rq_sg, max_sq_sg); | 626 | props->max_sge = min(max_rq_sg, max_sq_sg); |
625 | props->max_sge_rd = MLX5_MAX_SGE_RD; | 627 | props->max_sge_rd = MLX5_MAX_SGE_RD; |
626 | props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq); | 628 | props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq); |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index d1e921816bfe..aee3942ec68d 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
@@ -351,6 +351,29 @@ static int calc_send_wqe(struct ib_qp_init_attr *attr) | |||
351 | return ALIGN(max_t(int, inl_size, size), MLX5_SEND_WQE_BB); | 351 | return ALIGN(max_t(int, inl_size, size), MLX5_SEND_WQE_BB); |
352 | } | 352 | } |
353 | 353 | ||
354 | static int get_send_sge(struct ib_qp_init_attr *attr, int wqe_size) | ||
355 | { | ||
356 | int max_sge; | ||
357 | |||
358 | if (attr->qp_type == IB_QPT_RC) | ||
359 | max_sge = (min_t(int, wqe_size, 512) - | ||
360 | sizeof(struct mlx5_wqe_ctrl_seg) - | ||
361 | sizeof(struct mlx5_wqe_raddr_seg)) / | ||
362 | sizeof(struct mlx5_wqe_data_seg); | ||
363 | else if (attr->qp_type == IB_QPT_XRC_INI) | ||
364 | max_sge = (min_t(int, wqe_size, 512) - | ||
365 | sizeof(struct mlx5_wqe_ctrl_seg) - | ||
366 | sizeof(struct mlx5_wqe_xrc_seg) - | ||
367 | sizeof(struct mlx5_wqe_raddr_seg)) / | ||
368 | sizeof(struct mlx5_wqe_data_seg); | ||
369 | else | ||
370 | max_sge = (wqe_size - sq_overhead(attr)) / | ||
371 | sizeof(struct mlx5_wqe_data_seg); | ||
372 | |||
373 | return min_t(int, max_sge, wqe_size - sq_overhead(attr) / | ||
374 | sizeof(struct mlx5_wqe_data_seg)); | ||
375 | } | ||
376 | |||
354 | static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr, | 377 | static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr, |
355 | struct mlx5_ib_qp *qp) | 378 | struct mlx5_ib_qp *qp) |
356 | { | 379 | { |
@@ -387,7 +410,11 @@ static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr, | |||
387 | return -ENOMEM; | 410 | return -ENOMEM; |
388 | } | 411 | } |
389 | qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB); | 412 | qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB); |
390 | qp->sq.max_gs = attr->cap.max_send_sge; | 413 | qp->sq.max_gs = get_send_sge(attr, wqe_size); |
414 | if (qp->sq.max_gs < attr->cap.max_send_sge) | ||
415 | return -ENOMEM; | ||
416 | |||
417 | attr->cap.max_send_sge = qp->sq.max_gs; | ||
391 | qp->sq.max_post = wq_size / wqe_size; | 418 | qp->sq.max_post = wq_size / wqe_size; |
392 | attr->cap.max_send_wr = qp->sq.max_post; | 419 | attr->cap.max_send_wr = qp->sq.max_post; |
393 | 420 | ||