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>
This commit is contained in:
Jiri Pirko 2026-05-29 15:43:06 +02:00 committed by Jason Gunthorpe
parent c1837879e4
commit c0a94fecec
2 changed files with 31 additions and 20 deletions

View File

@ -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;
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;
}
}
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);
goto err_cq;
}
shift = mlx4_ib_umem_calc_optimal_mtt_size(cq->ibcq.umem, 0, &n);
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 @@ int mlx4_ib_create_user_cq(struct ib_cq *ibcq,
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);

View File

@ -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;