Skip to content

Commit fc2d004

Browse files
Sagi Grimbergrolandd
authored andcommitted
IB/mlx4: Fix max_wqe capacity reported from query device
1. Limit the max number of WQEs per QP reported when querying the device, so that ib_create_qp() will not fail for a QP size that the device claimed to support due to additional headroom WQEs being allocated. 2. Limit qp resources accepted for ib_create_qp() to the limits reported in ib_query_device(). In kernel space, make sure that the limits returned to the caller following qp creation also lie within the reported device limits. For userspace, report as before, and do adjustment in libmlx4 (so as not to break ABI). Signed-off-by: Jack Morgenstein <[email protected]> Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Or Gerlitz <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent edc4a67 commit fc2d004

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

drivers/infiniband/hw/mlx4/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
140140
props->max_mr_size = ~0ull;
141141
props->page_size_cap = dev->dev->caps.page_size_cap;
142142
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;
144144
props->max_sge = min(dev->dev->caps.max_sq_sg,
145145
dev->dev->caps.max_rq_sg);
146146
props->max_cq = dev->dev->caps.num_cqs - dev->dev->caps.reserved_cqs;

drivers/infiniband/hw/mlx4/mlx4_ib.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@
4444
#include <linux/mlx4/device.h>
4545
#include <linux/mlx4/doorbell.h>
4646

47+
enum {
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+
4755
struct mlx4_ib_ucontext {
4856
struct ib_ucontext ibucontext;
4957
struct mlx4_uar uar;

drivers/infiniband/hw/mlx4/qp.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
310310
int is_user, int has_rq, struct mlx4_ib_qp *qp)
311311
{
312312
/* Sanity check RQ size before proceeding */
313-
if (cap->max_recv_wr > dev->dev->caps.max_wqes ||
314-
cap->max_recv_sge > dev->dev->caps.max_rq_sg)
313+
if (cap->max_recv_wr > dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE ||
314+
cap->max_recv_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg))
315315
return -EINVAL;
316316

317317
if (!has_rq) {
@@ -329,8 +329,17 @@ static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
329329
qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
330330
}
331331

332-
cap->max_recv_wr = qp->rq.max_post = qp->rq.wqe_cnt;
333-
cap->max_recv_sge = qp->rq.max_gs;
332+
/* leave userspace return values as they were, so as not to break ABI */
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+
}
334343

335344
return 0;
336345
}
@@ -341,8 +350,8 @@ static int set_kernel_sq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
341350
int s;
342351

343352
/* Sanity check SQ size before proceeding */
344-
if (cap->max_send_wr > dev->dev->caps.max_wqes ||
345-
cap->max_send_sge > dev->dev->caps.max_sq_sg ||
353+
if (cap->max_send_wr > (dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE) ||
354+
cap->max_send_sge > min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg) ||
346355
cap->max_inline_data + send_wqe_overhead(type, qp->flags) +
347356
sizeof (struct mlx4_wqe_inline_seg) > dev->dev->caps.max_sq_desc_sz)
348357
return -EINVAL;

0 commit comments

Comments
 (0)