summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Pirko <jiri@nvidia.com>2026-05-29 15:43:06 +0200
committerJason Gunthorpe <jgg@nvidia.com>2026-05-29 20:19:59 -0300
commitc0a94fecec37765fb7e5c31d4e7986a1a23ce697 (patch)
tree791f77fd3f2031a916ab7ef60382fbb9061cd284
parentc1837879e4443c89805569778d82a3693d278696 (diff)
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 <jiri@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c50
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h1
2 files changed, 31 insertions, 20 deletions
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;