Linux Documentation
 help / color / mirror / Atom feed
* [PATCH 0/2] Document the DMA-buf mapping lifetime negotiation
@ 2026-08-25  6:28 Leon Romanovsky
  2026-08-25  6:28 ` [PATCH 1/2] PCI/P2PDMA: Update DMABUF lifecycle docs after move_notify() rename Leon Romanovsky
  2026-08-25  6:28 ` [PATCH 2/2] dma-buf: Document how exporters and importers agree on mapping lifetime Leon Romanovsky
  0 siblings, 2 replies; 3+ messages in thread
From: Leon Romanovsky @ 2026-08-25  6:28 UTC (permalink / raw)
  To: Bjorn Helgaas, Logan Gunthorpe, Jonathan Corbet, Shuah Khan,
	Christian König, Leon Romanovsky, Sumit Semwal
  Cc: linux-pci, linux-doc, linux-kernel, linux-media, dri-devel,
	linaro-mm-sig

DMA-buf lets an exporter pin, move or revoke the backing storage under
an importer, and which of the three applies is decided by the optional
callbacks each side implements and by whether dma_buf_pin() succeeds.
Nothing in Documentation/ describes that, and the single reference to
the mechanism still names move_notify(), removed in v7.1.

Thanks

Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
Leon Romanovsky (2):
      PCI/P2PDMA: Update DMABUF lifecycle docs after move_notify() rename
      dma-buf: Document how exporters and importers agree on mapping lifetime

 Documentation/driver-api/dma-buf.rst    |  6 +++
 Documentation/driver-api/pci/p2pdma.rst |  6 ++-
 drivers/dma-buf/dma-buf.c               | 85 ++++++++++++++++++++++++++++++++-
 3 files changed, 94 insertions(+), 3 deletions(-)
---
base-commit: 8049741ac93acd3a590dac070e12571fddf0e294
change-id: 20260820-document-dma-buf-3f8b41e32f57

Best regards,
--  
Leon Romanovsky <leonro@nvidia.com>


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] PCI/P2PDMA: Update DMABUF lifecycle docs after move_notify() rename
  2026-08-25  6:28 [PATCH 0/2] Document the DMA-buf mapping lifetime negotiation Leon Romanovsky
@ 2026-08-25  6:28 ` Leon Romanovsky
  2026-08-25  6:28 ` [PATCH 2/2] dma-buf: Document how exporters and importers agree on mapping lifetime Leon Romanovsky
  1 sibling, 0 replies; 3+ messages in thread
From: Leon Romanovsky @ 2026-08-25  6:28 UTC (permalink / raw)
  To: Bjorn Helgaas, Logan Gunthorpe, Jonathan Corbet, Shuah Khan,
	Christian König, Leon Romanovsky, Sumit Semwal
  Cc: linux-pci, linux-doc, linux-kernel, linux-media, dri-devel,
	linaro-mm-sig

From: Leon Romanovsky <leonro@nvidia.com>

Commit 95308225e5ba ("dma-buf: Rename dma_buf_move_notify() to
dma_buf_invalidate_mappings()") left the DMABUF section of the P2PDMA
documentation pointing at move_notify(), a symbol that no longer
exists. Readers grepping for it find nothing, and this is the only
place in Documentation/ describing the revocation requirement.

Name the current function and record that importers which cannot unmap
within bounded time have to be rejected at attach time, which is what
makes the synchronous unmap on remove() achievable.

Fixes: 95308225e5ba ("dma-buf: Rename dma_buf_move_notify() to dma_buf_invalidate_mappings()")
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
 Documentation/driver-api/pci/p2pdma.rst | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/driver-api/pci/p2pdma.rst b/Documentation/driver-api/pci/p2pdma.rst
index d3f406cca694..63cff9e4d2c9 100644
--- a/Documentation/driver-api/pci/p2pdma.rst
+++ b/Documentation/driver-api/pci/p2pdma.rst
@@ -167,9 +167,11 @@ In this case the initiator and target pci_devices are known and the P2P subsyste
 is used to determine the mapping type. The phys_addr_t-based DMA API is used to
 establish the dma_addr_t.
 
-Lifecycle is controlled by DMABUF move_notify(). When the exporting driver wants
+Lifecycle is controlled by DMABUF revocation. When the exporting driver wants
 to remove() it must deliver an invalidation shutdown to all DMABUF importing
-drivers through move_notify() and synchronously DMA unmap all the MMIO.
+drivers through dma_buf_invalidate_mappings() and synchronously DMA unmap all
+the MMIO. Importers unable to complete that unmap within bounded time have to
+be rejected when they attach, which dma_buf_attach_revocable() checks for.
 
 No importing driver can continue to have a DMA map to the MMIO after the
 exporting driver has destroyed its p2p_provider.

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] dma-buf: Document how exporters and importers agree on mapping lifetime
  2026-08-25  6:28 [PATCH 0/2] Document the DMA-buf mapping lifetime negotiation Leon Romanovsky
  2026-08-25  6:28 ` [PATCH 1/2] PCI/P2PDMA: Update DMABUF lifecycle docs after move_notify() rename Leon Romanovsky
@ 2026-08-25  6:28 ` Leon Romanovsky
  1 sibling, 0 replies; 3+ messages in thread
From: Leon Romanovsky @ 2026-08-25  6:28 UTC (permalink / raw)
  To: Bjorn Helgaas, Logan Gunthorpe, Jonathan Corbet, Shuah Khan,
	Christian König, Leon Romanovsky, Sumit Semwal
  Cc: linux-pci, linux-doc, linux-kernel, linux-media, dri-devel,
	linaro-mm-sig

From: Leon Romanovsky <leonro@nvidia.com>

Pinned, revoked and movable mappings are selected by which optional
callbacks each side implements and by whether dma_buf_pin() succeeds,
not by any flag or enum. Nothing in Documentation/ says so, and the
rules are spread over the kdoc of dma_buf_ops.pin,
dma_buf_attach_ops.invalidate_mappings and dma_buf_invalidate_mappings(),
so a driver author has to know the symbol names before finding them.

Name, per flow, the callbacks both sides have to implement to end up in
it, describe dma_buf_pin() as the runtime negotiation, and record that
the pin is what tells a revoke from a move.

Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
 Documentation/driver-api/dma-buf.rst |  6 +++
 drivers/dma-buf/dma-buf.c            | 85 +++++++++++++++++++++++++++++++++++-
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst
index 2f36c21d9948..39c201f38aa6 100644
--- a/Documentation/driver-api/dma-buf.rst
+++ b/Documentation/driver-api/dma-buf.rst
@@ -113,6 +113,12 @@ Basic Operation and Device DMA Access
 .. kernel-doc:: drivers/dma-buf/dma-buf.c
    :doc: dma buf device access
 
+Mapping Lifetime Negotiation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: drivers/dma-buf/dma-buf.c
+   :doc: mapping lifetime negotiation
+
 CPU Access to DMA Buffer Objects
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index d504c636dc29..30afec7365bc 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -684,7 +684,90 @@ static struct file *dma_buf_getfile(size_t size, int flags)
  *    reference acquired with dma_buf_get() by calling dma_buf_put().
  *
  * For the detailed semantics exporters are expected to implement see
- * &dma_buf_ops.
+ * &dma_buf_ops. Whether the exporter may still move or destroy the backing
+ * storage after step 3 depends on what exporter and importer implement, see
+ * the mapping lifetime negotiation section below.
+ */
+
+/**
+ * DOC: mapping lifetime negotiation
+ *
+ * No flag or enum says whether the exporter may move or take away the backing
+ * storage while an importer holds a mapping. Each side implements a set of
+ * optional callbacks, and dma_buf_pin() settles the result at runtime. Three
+ * flows come out of it:
+ *
+ * - Pinned: the storage never moves and is never taken away.
+ * - Revoked: the storage never moves, but the exporter may take it away.
+ * - Movable: the exporter may relocate the storage at any time.
+ *
+ * Every exporter implements &dma_buf_ops.map_dma_buf,
+ * &dma_buf_ops.unmap_dma_buf and &dma_buf_ops.release. dma_buf_export()
+ * rejects an exporter missing any of them.
+ *
+ * An importer reaches its flow like this:
+ *
+ * 1. Attach with dma_buf_dynamic_attach(). Leaving
+ *    &dma_buf_attach_ops.invalidate_mappings NULL rules out everything but the
+ *    pinned flow, because the importer can then never be told anything.
+ * 2. Call dma_buf_pin() under the reservation lock.
+ * 3. On failure run the movable flow, or give up.
+ * 4. On success the storage stays put. Whether the exporter may still take it
+ *    away, which makes this the revoked flow instead of the pinned one, is the
+ *    exporter's choice and is not reported back.
+ *
+ * dma_buf_attach() is the shorthand for an importer which only ever wants the
+ * pinned flow. It passes no &dma_buf_attach_ops, and DMA-buf then pins around
+ * every dma_buf_map_attachment() and waits for the DMA_RESV_USAGE_KERNEL
+ * fences on the importer's behalf. Peer to peer needs
+ * dma_buf_dynamic_attach(), because &dma_buf_attach_ops.allow_peer2peer lives
+ * in the attach ops.
+ *
+ * Pinned flow:
+ *
+ * - Exporter: implement &dma_buf_ops.pin and &dma_buf_ops.unpin to hold the
+ *   storage still on request. An exporter whose storage never moves implements
+ *   neither, and dma_buf_pin() then succeeds on its own. An exporter which
+ *   refuses to be pinned implements &dma_buf_ops.pin and fails it.
+ * - Importer: nothing more. The mapping stays valid until it unmaps.
+ *
+ * Revoked flow:
+ *
+ * - Exporter: answer dma_buf_pin() as above. Call
+ *   dma_buf_invalidate_mappings() when the storage goes away and fail
+ *   &dma_buf_ops.map_dma_buf while it is gone. The two waits which complete a
+ *   revocation are described in dma_buf_invalidate_mappings().
+ * - Importer: &dma_buf_attach_ops.invalidate_mappings has to unmap within
+ *   bounded time and drop the pin.
+ *
+ * Movable flow:
+ *
+ * - Exporter: call dma_buf_invalidate_mappings() before each move, then wait
+ *   for the &dma_buf.resv fences. &dma_buf_ops.pin and &dma_buf_ops.unpin play
+ *   no part here.
+ * - Importer: hold no pin. &dma_buf_attach_ops.invalidate_mappings drops the
+ *   cached mapping and has to lead to dma_buf_unmap_attachment() within
+ *   bounded time. It need not stop the hardware, because access runs until the
+ *   importer's &dma_buf.resv fences retire. Map again before the next DMA.
+ *
+ * The pin tells a revoke from a move.
+ * &dma_buf_attach_ops.invalidate_mappings carries no reason, and both flows
+ * ask for the same unmap. An importer holding a pin can only be seeing a
+ * revoke, because the exporter promised not to move. An importer without a pin
+ * treats every call as a move and maps again.
+ *
+ * A revoke need not be forever. An exporter revoking around a temporary loss
+ * of access takes mappings again afterwards. Giving up for good is the
+ * importer's own choice, so an exporter must not wait for one to come back.
+ *
+ * &dma_buf_ops.attach is the only place where an exporter can turn an importer
+ * away. An exporter which revokes rejects the importers for which
+ * dma_buf_attach_revocable() returns false. An exporter of memory without
+ * struct page rejects the importers which left
+ * &dma_buf_attach_ops.allow_peer2peer clear.
+ *
+ * Userspace sees none of this. The two drivers negotiate the flow between
+ * themselves, and the DMA-buf file descriptor shows no trace of the result.
  */
 
 /**

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-25  6:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-25  6:28 [PATCH 0/2] Document the DMA-buf mapping lifetime negotiation Leon Romanovsky
2026-08-25  6:28 ` [PATCH 1/2] PCI/P2PDMA: Update DMABUF lifecycle docs after move_notify() rename Leon Romanovsky
2026-08-25  6:28 ` [PATCH 2/2] dma-buf: Document how exporters and importers agree on mapping lifetime Leon Romanovsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox