aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mlx4/main.c2
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h8
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c21
3 files changed, 24 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 8afea12c8d44..3530c41fcd1f 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -140,7 +140,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
140 props->max_mr_size = ~0ull; 140 props->max_mr_size = ~0ull;
141 props->page_size_cap = dev->dev->caps.page_size_cap; 141 props->page_size_cap = dev->dev->caps.page_size_cap;
142 props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps; 142 props->max_qp = dev->dev->caps.num_qps - dev->dev->caps.reserved_qps;
143 props->max_qp_wr = dev->dev->caps.max_wqes; 143 props->max_qp_wr = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE;
144 props->max_sge = min(dev->dev->caps.max_sq_sg, 144 props->max_sge = min(dev->dev->caps.max_sq_sg,
145 dev->dev->caps.max_rq_sg); 145 dev->dev->caps.max_rq_sg);
146 props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs; 146 props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs;
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index e62297cc77cc..ff36655d23d3 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -44,6 +44,14 @@
44#include <linux/mlx4/device.h> 44#include <linux/mlx4/device.h>
45#include <linux/mlx4/doorbell.h> 45#include <linux/mlx4/doorbell.h>
46 46
47enum {
48 MLX4_IB_SQ_MIN_WQE_SHIFT = 6,
49 MLX4_IB_MAX_HEADROOM = 2048
50};
51
52#define MLX4_IB_SQ_HEADROOM(shift) ((MLX4_IB_MAX_HEADROOM >> (shift)) + 1)
53#define MLX4_IB_SQ_MAX_SPARE (MLX4_IB_SQ_HEADROOM(MLX4_IB_SQ_MIN_WQE_SHIFT))
54
47struct mlx4_ib_ucontext { 55struct mlx4_ib_ucontext {
48 struct ib_ucontext ibucontext; 56 struct ib_ucontext ibucontext;
49 struct mlx4_uar uar; 57 struct mlx4_uar uar;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index ceb33327091a..8d4ed24aef93 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -310,8 +310,8 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
310 int is_user, int has_rq, struct mlx4_ib_qp *qp) 310 int is_user, int has_rq, struct mlx4_ib_qp *qp)
311{ 311{
312 /* Sanity check RQ size before proceeding */ 312 /* Sanity check RQ size before proceeding */
313 if (cap->max_recv_wr > dev->dev->caps.max_wqes || 313 if (cap->max_recv_wr > dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE ||
314 cap->max_recv_sge > dev->dev->caps.max_rq_sg) 314 cap->max_recv_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg))
315 return -EINVAL; 315 return -EINVAL;
316 316
317 if (!has_rq) { 317 if (!has_rq) {
@@ -329,8 +329,17 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
329 qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg)); 329 qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
330 } 330 }
331 331
332 cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt; 332 /* leave userspace return values as they were, so as not to break ABI */
333 cap->max_recv_sge = qp->rq.max_gs; 333 if (is_user) {
334 cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt;
335 cap->max_recv_sge = qp->rq.max_gs;
336 } else {
337 cap->max_recv_wr = qp->rq.max_post =
338 min(dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE, qp->rq.wqe_cnt);
339 cap->max_recv_sge = min(qp->rq.max_gs,
340 min(dev->dev->caps.max_sq_sg,
341 dev->dev->caps.max_rq_sg));
342 }
334 343
335 return 0; 344 return 0;
336} 345}
@@ -341,8 +350,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
341 int s; 350 int s;
342 351
343 /* Sanity check SQ size before proceeding */ 352 /* Sanity check SQ size before proceeding */
344 if (cap->max_send_wr > dev->dev->caps.max_wqes || 353 if (cap->max_send_wr > (dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE) ||
345 cap->max_send_sge > dev->dev->caps.max_sq_sg || 354 cap->max_send_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg) ||
346 cap->max_inline_data + send_wqe_overhead(type, qp->flags) + 355 cap->max_inline_data + send_wqe_overhead(type, qp->flags) +
347 sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz) 356 sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz)
348 return -EINVAL; 357 return -EINVAL;