From: Jacob Moroni <jmoroni@google.com>
To: tatyana.e.nikolova@intel.com, jgg@ziepe.ca, leon@kernel.org
Cc: linux-rdma@vger.kernel.org, Jacob Moroni <jmoroni@google.com>
Subject: [PATCH rdma-next 4/4] RDMA/irdma: Add refcounting to user ring MRs
Date: Thu, 18 Jun 2026 20:14:58 +0000 [thread overview]
Message-ID: <20260618201458.875740-5-jmoroni@google.com> (raw)
In-Reply-To: <20260618201458.875740-1-jmoroni@google.com>
Prevent userspace from deregistering the MRs that back QP/CQ/SRQ rings
by bumping the MR's refcount upon association.
Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
Signed-off-by: Jacob Moroni <jmoroni@google.com>
---
drivers/infiniband/hw/irdma/utils.c | 6 ++++
drivers/infiniband/hw/irdma/verbs.c | 45 +++++++++++++++++++++++++++--
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
index e4037d5ef..290ad02ed 100644
--- a/drivers/infiniband/hw/irdma/utils.c
+++ b/drivers/infiniband/hw/irdma/utils.c
@@ -1168,6 +1168,12 @@ void irdma_free_qp_rsrc(struct irdma_qp *iwqp)
iwqp->kqp.dma_mem.va = NULL;
kfree(iwqp->kqp.sq_wrid_mem);
kfree(iwqp->kqp.rq_wrid_mem);
+
+ if (iwqp->user_mode && iwqp->iwpbl) {
+ struct irdma_mr *iwmr = iwqp->iwpbl->iwmr;
+
+ refcount_dec(&iwmr->user_ring_refs);
+ }
}
/**
diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index dccecff3c..70201e1e2 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -464,6 +464,9 @@ static struct irdma_pbl *irdma_get_pbl(unsigned long va,
list_for_each_entry (iwpbl, pbl_list, list) {
if (iwpbl->user_base == va) {
+ struct irdma_mr *iwmr = iwpbl->iwmr;
+
+ refcount_inc(&iwmr->user_ring_refs);
list_del(&iwpbl->list);
iwpbl->on_list = false;
return iwpbl;
@@ -1881,6 +1884,11 @@ static void irdma_srq_free_rsrc(struct irdma_pci_f *rf, struct irdma_srq *iwsrq)
dma_free_coherent(rf->sc_dev.hw->device, iwsrq->kmem.size,
iwsrq->kmem.va, iwsrq->kmem.pa);
iwsrq->kmem.va = NULL;
+ } else {
+ /* Not called in any failure path, so iwpbl is valid. */
+ struct irdma_mr *iwmr = iwsrq->iwpbl->iwmr;
+
+ refcount_dec(&iwmr->user_ring_refs);
}
irdma_free_rsrc(rf, rf->allocated_srqs, srq->srq_uk.srq_id);
@@ -1903,6 +1911,21 @@ static void irdma_cq_free_rsrc(struct irdma_pci_f *rf, struct irdma_cq *iwcq)
iwcq->kmem_shadow.size,
iwcq->kmem_shadow.va, iwcq->kmem_shadow.pa);
iwcq->kmem_shadow.va = NULL;
+ } else {
+ struct irdma_mr *iwmr;
+
+ /* May be called in a failure path before iwpbl is valid. */
+ if (iwcq->iwpbl) {
+ iwmr = iwcq->iwpbl->iwmr;
+
+ refcount_dec(&iwmr->user_ring_refs);
+ }
+
+ if (iwcq->iwpbl_shadow) {
+ iwmr = iwcq->iwpbl_shadow->iwmr;
+
+ refcount_dec(&iwmr->user_ring_refs);
+ }
}
irdma_free_rsrc(rf, rf->allocated_cqs, cq->cq_uk.cq_id);
@@ -2018,7 +2041,7 @@ static int irdma_resize_cq(struct ib_cq *ibcq, unsigned int entries,
struct irdma_modify_cq_info info = {};
struct irdma_dma_mem kmem_buf;
struct irdma_cq_mr *cqmr_buf;
- struct irdma_pbl *iwpbl_buf;
+ struct irdma_pbl *iwpbl_buf = NULL;
struct irdma_device *iwdev;
struct irdma_pci_f *rf;
struct irdma_cq_buf *cq_buf = NULL;
@@ -2129,11 +2152,19 @@ static int irdma_resize_cq(struct ib_cq *ibcq, unsigned int entries,
goto error;
spin_lock_irqsave(&iwcq->lock, flags);
- if (udata)
+ if (udata) {
+ struct irdma_pbl *old_iwpbl = iwcq->iwpbl;
+
/* Only update if the resize was successful. Otherwise, HW is
* still pointing to the old PBL.
*/
iwcq->iwpbl = iwpbl_buf;
+ if (old_iwpbl) {
+ struct irdma_mr *old_iwmr = old_iwpbl->iwmr;
+
+ refcount_dec(&old_iwmr->user_ring_refs);
+ }
+ }
if (cq_buf) {
cq_buf->kmem_buf = iwcq->kmem;
cq_buf->hw = dev->hw;
@@ -2149,6 +2180,11 @@ static int irdma_resize_cq(struct ib_cq *ibcq, unsigned int entries,
return 0;
error:
+ if (iwpbl_buf) {
+ struct irdma_mr *iwmr = iwpbl_buf->iwmr;
+
+ refcount_dec(&iwmr->user_ring_refs);
+ }
if (!udata) {
dma_free_coherent(dev->hw->device, kmem_buf.size, kmem_buf.va,
kmem_buf.pa);
@@ -2425,6 +2461,11 @@ static int irdma_create_srq(struct ib_srq *ibsrq,
dma_free_coherent(rf->hw.device, iwsrq->kmem.size,
iwsrq->kmem.va, iwsrq->kmem.pa);
free_rsrc:
+ if (iwsrq->user_mode && iwsrq->iwpbl) {
+ struct irdma_mr *iwmr = iwsrq->iwpbl->iwmr;
+
+ refcount_dec(&iwmr->user_ring_refs);
+ }
irdma_free_rsrc(rf, rf->allocated_srqs, iwsrq->srq_num);
return err_code;
}
--
2.55.0.rc0.738.g0c8ab3ebcc-goog
prev parent reply other threads:[~2026-06-18 20:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-18 20:14 [PATCH rdma-next 0/4] RDMA/irdma: Prevent premature deregistration of user ring MRs Jacob Moroni
2026-06-18 20:14 ` [PATCH rdma-next 1/4] RDMA/irdma: Deduplicate the irdma_del_memlist logic Jacob Moroni
2026-06-18 20:14 ` [PATCH rdma-next 2/4] RDMA/irdma: Add a refcount to track user ring MR associations Jacob Moroni
2026-06-18 20:14 ` [PATCH rdma-next 3/4] RDMA/irdma: Add irdma_cq fields to track pbl allocations Jacob Moroni
2026-06-18 20:14 ` Jacob Moroni [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260618201458.875740-5-jmoroni@google.com \
--to=jmoroni@google.com \
--cc=jgg@ziepe.ca \
--cc=leon@kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=tatyana.e.nikolova@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.