All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: Leon Romanovsky <leon@kernel.org>
Cc: "Bjorn Helgaas" <bhelgaas@google.com>,
	"Logan Gunthorpe" <logang@deltatee.com>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Shuah Khan" <skhan@linuxfoundation.org>,
	"Christian König" <christian.koenig@amd.com>,
	"Sumit Semwal" <sumit.semwal@linaro.org>,
	linux-pci@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
	dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org
Subject: Re: [Linaro-mm-sig] [PATCH 2/2] dma-buf: Document how exporters and importers agree on mapping lifetime
Date: Mon, 31 Aug 2026 08:39:01 +0200	[thread overview]
Message-ID: <8276d124012e7a335c299b20f6578fc9f751e713.camel@linux.intel.com> (raw)
In-Reply-To: <20260830075828.GA24140@unreal>

On Sun, 2026-08-30 at 10:58 +0300, Leon Romanovsky wrote:
> On Thu, Aug 27, 2026 at 09:18:29PM +0200, Thomas Hellström wrote:
> > Hi,
> > 
> > Some comments below:
> > 
> > On Tue, 2026-08-25 at 09:28 +0300, Leon Romanovsky wrote:
> > > 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.
> > 
> > Perhaps add "even temporarily to locations that are not available
> > for
> > DMA".
> 
> I don't know. "Not available for DMA" defeats the whole purpose of
> dma-buf,
> which is intended to expose DMA-capable memory to other peers. I
> imagine
> that "everything is optional dmabuf world" this is possible, but it
> looks to me like a partial version of revoked flow.

Not permanently revoked. In practice this would be, for example, a GPU-
exported dma-buf which is only available for p2p access which gets
evicted, or a system memory exported dma-buf that gets hit by a
shrinker and moved to swap. The exporter calls invalidate_mappings() to
notify importers that storage is going away. Importers need to call
map_attachment() to bring it back.

> 
> > 
> > > + *
> > > + * 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.
> > 
> > Hear I would want to see the exporter being allowed to force unmap
> > the
> > dma mappings and reclaim thestorage when the fences mentioned above
> > have signaled, but the importer has not yet called
> > dma_buf_unmap_attachment(). That would allow importers to call
> > dma_buf_unmap_attachment() lazily, just before the next
> > map_attachment,
> > which would allow simplifying importer implementations. 
> 
> How? It will move one piece of code as is to another place. In
> addition,
> both exporter and importer need to stop HW access to same region.

A typical GPU example: A GPU importer receives invalidate_mappings() on
an imported dma-buf. The dma-buf is still accessed by the GPU and thus
has a couple of dma-fences attached. The importer can't immediately
call dma_buf_unmap_attachment(). In fact, typically the easiest thing
for the importer is to call dma_buf_unmap_attachment() on the next gpu
command submission immediately followed by a dma_buf_map_attachment(),
but it can't guarantee that would happen within bounded time.

A well behaved importer would therefore currently have to schedule an
async worker or similar to wait for its dma-fences to signal and then
grab the resv lock from worker context and call
dma_buf_unmap_attachment().

A well-behaved exporter on the other hand, would have to wait for all
dma-fences to signal, then wait for all unmap_attachment() calls before
reclaiming.

TBH I'm not sure what the best solution is here, but the importer flow
doesn't fit well in a typical gpu command submission model IMO.

Thanks,
Thomas




> 
> > More of a related idea than something that needs fixing for this
> > patch.
> > 
> > >  It need not stop the hardware, because access runs until the
> > > + *   importer's &dma_buf.resv fences retire. Map again before
> > > the
> > > next DMA.
> > 
> > A successful map will mean the exporter has placed the data in
> > storage
> > compatible with what was agreed during attachment?
> 
> Yes.
> 
> > 
> > Thanks,
> > Thomas
> > 

  reply	other threads:[~2026-08-31  6:39 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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:29   ` sashiko-bot
2026-08-25 20:05   ` Logan Gunthorpe
2026-08-26 11:50   ` Christian König
2026-09-03 20:34   ` Bjorn Helgaas
2026-09-04  6:40     ` Leon Romanovsky
2026-08-25  6:28 ` [PATCH 2/2] dma-buf: Document how exporters and importers agree on mapping lifetime Leon Romanovsky
2026-08-25  6:31   ` sashiko-bot
2026-08-26 11:41   ` Christian König
2026-08-26 12:43     ` Leon Romanovsky
2026-08-26 13:06       ` Christian König
2026-08-26 14:02         ` Leon Romanovsky
2026-08-31  9:22           ` Christian König
2026-09-01 14:08             ` Jason Gunthorpe
2026-08-27 19:18   ` [Linaro-mm-sig] " Thomas Hellström
2026-08-30  7:58     ` Leon Romanovsky
2026-08-31  6:39       ` Thomas Hellström [this message]
2026-08-31  8:56       ` Christian König

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=8276d124012e7a335c299b20f6578fc9f751e713.camel@linux.intel.com \
    --to=thomas.hellstrom@linux.intel.com \
    --cc=bhelgaas@google.com \
    --cc=christian.koenig@amd.com \
    --cc=corbet@lwn.net \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=leon@kernel.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=logang@deltatee.com \
    --cc=skhan@linuxfoundation.org \
    --cc=sumit.semwal@linaro.org \
    /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.