From: Jiri Pirko Date: Fri, 29 May 2026 13:43:06 +0000 (+0200) Subject: RDMA/mlx4: Use ib_umem_get_cq_buf() for user CQ buffer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0a94fecec37765fb7e5c31d4e7986a1a23ce697;p=thirdparty%2Fkernel%2Fstable.git RDMA/mlx4: Use ib_umem_get_cq_buf() for user CQ buffer Pin the user CQ buffer with ib_umem_get_cq_buf() and take ownership of the umem in the driver; fall back to ib_umem_get_va() for the legacy UHW VA path. Apply the same ownership pattern to the resize path. Link: https://patch.msgid.link/r/20260529134312.2836341-11-jiri@resnulli.us Signed-off-by: Jiri Pirko Signed-off-by: Jason Gunthorpe --- diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index f9ec6917d9c9..887912469742 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -173,32 +173,40 @@ int mlx4_ib_create_user_cq(struct ib_cq *ibcq, if (err) goto err_cq; - if (ibcq->umem && - (dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SW_CQ_INIT)) - return -EOPNOTSUPP; - - buf_addr = (void *)(unsigned long)ucmd.buf_addr; - - if (!ibcq->umem) - ibcq->umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr, - entries * cqe_size, - IB_ACCESS_LOCAL_WRITE); - if (IS_ERR(ibcq->umem)) { - err = PTR_ERR(ibcq->umem); + cq->umem = ib_umem_get_cq_buf(&dev->ib_dev, attrs, entries * cqe_size, + IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(cq->umem)) { + err = PTR_ERR(cq->umem); goto err_cq; } + if (cq->umem) { + if (dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SW_CQ_INIT) { + err = -EOPNOTSUPP; + goto err_umem; + } + } else { + cq->umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr, + entries * cqe_size, + IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(cq->umem)) { + err = PTR_ERR(cq->umem); + goto err_cq; + } + } - shift = mlx4_ib_umem_calc_optimal_mtt_size(cq->ibcq.umem, 0, &n); + buf_addr = (void *)(unsigned long)ucmd.buf_addr; + + shift = mlx4_ib_umem_calc_optimal_mtt_size(cq->umem, 0, &n); if (shift < 0) { err = shift; - goto err_cq; + goto err_umem; } err = mlx4_mtt_init(dev->dev, n, shift, &cq->buf.mtt); if (err) - goto err_cq; + goto err_umem; - err = mlx4_ib_umem_write_mtt(dev, &cq->buf.mtt, cq->ibcq.umem); + err = mlx4_ib_umem_write_mtt(dev, &cq->buf.mtt, cq->umem); if (err) goto err_mtt; @@ -235,7 +243,9 @@ err_dbmap: err_mtt: mlx4_mtt_cleanup(dev->dev, &cq->buf.mtt); - /* UMEM is released by ib_core */ + +err_umem: + ib_umem_release(cq->umem); err_cq: return err; @@ -472,8 +482,8 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, unsigned int entries, if (ibcq->uobject) { cq->buf = cq->resize_buf->buf; cq->ibcq.cqe = cq->resize_buf->cqe; - ib_umem_release(cq->ibcq.umem); - cq->ibcq.umem = cq->resize_umem; + ib_umem_release(cq->umem); + cq->umem = cq->resize_umem; kfree(cq->resize_buf); cq->resize_buf = NULL; @@ -533,7 +543,7 @@ int mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata) struct mlx4_ib_ucontext, ibucontext), &mcq->db); - /* UMEM is released by ib_core */ + ib_umem_release(mcq->umem); } else { mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe); mlx4_db_free(dev->dev, &mcq->db); diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 5a799d6df93e..598954dd0613 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -121,6 +121,7 @@ struct mlx4_ib_cq { struct mlx4_db db; spinlock_t lock; struct mutex resize_mutex; + struct ib_umem *umem; struct ib_umem *resize_umem; /* List of qps that it serves.*/ struct list_head send_qp_list;