aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Cohen <eli@mellanox.com>2016-10-27 09:36:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-26 02:24:34 -0500
commitdae9f4f144119229e4218f92ec0876549460ed45 (patch)
tree7d54ce2aa649728a72548c500e1da0b6c2170f90
parent4db097fe49ea9dc608e614fbf46bc7463be0eb76 (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.c8
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c29
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
354static 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
354static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr, 377static 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