public inbox for linux-rdma@vger.kernel.org
 help / color / mirror / Atom feed
From: Jacob Moroni <jmoroni@google.com>
To: tatyana.e.nikolova@intel.com, krzysztof.czurylo@intel.com,
	jgg@ziepe.ca,  leon@kernel.org
Cc: linux-rdma@vger.kernel.org, Jacob Moroni <jmoroni@google.com>
Subject: [RFC] RDMA/irdma: Add support for revocable dmabuf import
Date: Tue, 17 Feb 2026 18:21:15 +0000	[thread overview]
Message-ID: <20260217182116.1726438-1-jmoroni@google.com> (raw)

In order to import a dmabuf from VFIO, the importer must support
revocation. This is achieved by providing a move_notify callback
that will cause the region to be invalidated in hardware prior to
calling ib_umem_dmabuf_unmap_pages. The mkey and data structures
are not freed until the user explicitly deregisters the region,
but the HW will no longer access the memory (any attempt would
result in an AE for the QP just like a normal dereg mr).

Tested with VFIO by triggering a VFIO_DEVICE_RESET while the
region is registered to ensure the callback is executed.

Signed-off-by: Jacob Moroni <jmoroni@google.com>
---
 drivers/infiniband/hw/irdma/verbs.c | 78 ++++++++++++++++++++++++++---
 1 file changed, 71 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index cf8d19150..157e1413d 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
 /* Copyright (c) 2015 - 2021 Intel Corporation */
 #include "main.h"
+#include <linux/dma-buf.h>
+#include <linux/dma-resv.h>
 
 /**
  * irdma_query_device - get device attributes
@@ -3590,6 +3592,44 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
 	return ERR_PTR(err);
 }
 
+static int irdma_hwdereg_mr(struct ib_mr *ib_mr);
+
+static void irdma_dmabuf_invalidate_cb(struct dma_buf_attachment *attach)
+{
+	struct ib_umem_dmabuf *umem_dmabuf = attach->importer_priv;
+	struct irdma_mr *iwmr = umem_dmabuf->private;
+	int err;
+
+	dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
+
+	if (!iwmr)
+		return;
+
+	/* Invalidate the region in hardware, but do not release the key yet.
+	 * This will either invalidate the region or issue a reset. Either way,
+	 * the HW will no longer touch the region after. If successful, the
+	 * region is marked as invalidated so that the real dereg MR later ends
+	 * up skipping the HW request.
+	 */
+	err = irdma_hwdereg_mr(&iwmr->ibmr);
+	if (err) {
+		struct irdma_device *iwdev = to_iwdev(iwmr->ibmr.device);
+
+		ibdev_err(&iwdev->ibdev, "dmabuf mr invalidate failed %d", err);
+		if (!iwdev->rf->reset) {
+			iwdev->rf->reset = true;
+			iwdev->rf->gen_ops.request_reset(iwdev->rf);
+		}
+	}
+
+	ib_umem_dmabuf_unmap_pages(umem_dmabuf);
+}
+
+static struct dma_buf_attach_ops irdma_dmabuf_attach_ops = {
+	.allow_peer2peer = 1,
+	.move_notify = irdma_dmabuf_invalidate_cb,
+};
+
 static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start,
 					      u64 len, u64 virt,
 					      int fd, int access,
@@ -3599,7 +3639,7 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start,
 	struct irdma_device *iwdev = to_iwdev(pd->device);
 	struct ib_umem_dmabuf *umem_dmabuf;
 	struct irdma_mr *iwmr;
-	int err;
+	int err = -1;
 
 	if (dmah)
 		return ERR_PTR(-EOPNOTSUPP);
@@ -3607,31 +3647,43 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start,
 	if (len > iwdev->rf->sc_dev.hw_attrs.max_mr_size)
 		return ERR_PTR(-EINVAL);
 
-	umem_dmabuf = ib_umem_dmabuf_get_pinned(pd->device, start, len, fd, access);
+	umem_dmabuf = ib_umem_dmabuf_get(pd->device, start, len, fd, access,
+					 &irdma_dmabuf_attach_ops);
 	if (IS_ERR(umem_dmabuf)) {
 		ibdev_dbg(&iwdev->ibdev, "Failed to get dmabuf umem[%pe]\n",
 			  umem_dmabuf);
 		return ERR_CAST(umem_dmabuf);
 	}
 
+	dma_resv_lock(umem_dmabuf->attach->dmabuf->resv, NULL);
+
+	err = ib_umem_dmabuf_map_pages(umem_dmabuf);
+	if (err)
+		goto err_map;
+
 	iwmr = irdma_alloc_iwmr(&umem_dmabuf->umem, pd, virt, IRDMA_MEMREG_TYPE_MEM);
 	if (IS_ERR(iwmr)) {
 		err = PTR_ERR(iwmr);
-		goto err_release;
+		goto err_alloc;
 	}
 
 	err = irdma_reg_user_mr_type_mem(iwmr, access, true);
 	if (err)
 		goto err_iwmr;
 
+	umem_dmabuf->private = iwmr;
+
+	dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
+
 	return &iwmr->ibmr;
 
 err_iwmr:
 	irdma_free_iwmr(iwmr);
-
-err_release:
+err_alloc:
+	ib_umem_dmabuf_unmap_pages(umem_dmabuf);
+err_map:
+	dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv);
 	ib_umem_release(&umem_dmabuf->umem);
-
 	return ERR_PTR(err);
 }
 
@@ -3923,7 +3975,19 @@ static int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata)
 		goto done;
 	}
 
-	ret = irdma_hwdereg_mr(ib_mr);
+	if (iwmr->region && iwmr->region->is_dmabuf) {
+		struct ib_umem_dmabuf *udb = to_ib_umem_dmabuf(iwmr->region);
+
+		dma_resv_lock(udb->attach->dmabuf->resv, NULL);
+		/* Could have already been invalidated, but it's okay. */
+		ret = irdma_hwdereg_mr(ib_mr);
+		ib_umem_dmabuf_unmap_pages(udb);
+		udb->private = NULL;
+		dma_resv_unlock(udb->attach->dmabuf->resv);
+	} else {
+		ret = irdma_hwdereg_mr(ib_mr);
+	}
+
 	if (ret)
 		return ret;
 
-- 
2.53.0.310.g728cabbaf7-goog


             reply	other threads:[~2026-02-17 18:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-17 18:21 Jacob Moroni [this message]
2026-02-17 18:45 ` [RFC] RDMA/irdma: Add support for revocable dmabuf import Jason Gunthorpe
2026-02-17 23:08   ` Jacob Moroni
2026-02-17 23:21     ` Jason Gunthorpe
2026-02-18  9:05       ` Leon Romanovsky
2026-02-18 15:24         ` Jacob Moroni

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=20260217182116.1726438-1-jmoroni@google.com \
    --to=jmoroni@google.com \
    --cc=jgg@ziepe.ca \
    --cc=krzysztof.czurylo@intel.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox