From: Boris Brezillon <boris.brezillon@collabora.com>
To: Steven Price <steven.price@arm.com>
Cc: "Liviu Dudau" <liviu.dudau@arm.com>,
"Adrián Larumbe" <adrian.larumbe@collabora.com>,
dri-devel@lists.freedesktop.org,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Faith Ekstrand" <faith.ekstrand@collabora.com>,
kernel@collabora.com
Subject: Re: [PATCH v2 02/13] drm/prime: Provide default ::{begin,end}_cpu_access() implementations
Date: Fri, 10 Oct 2025 18:02:34 +0200 [thread overview]
Message-ID: <20251010180234.67306496@fedora> (raw)
In-Reply-To: <06087818-e5a9-437d-83c6-337ade252cb6@arm.com>
On Fri, 10 Oct 2025 16:34:14 +0100
Steven Price <steven.price@arm.com> wrote:
> On 10/10/2025 16:03, Boris Brezillon wrote:
> > On Fri, 10 Oct 2025 15:11:54 +0100
> > Steven Price <steven.price@arm.com> wrote:
> >
> >> On 10/10/2025 11:11, Boris Brezillon wrote:
> >>> Hook-up drm_gem_dmabuf_{begin,end}_cpu_access() to drm_gem_sync() so
> >>> that drivers relying on the default prime_dmabuf_ops can still have
> >>> a way to prepare for CPU accesses from outside the UMD.
> >>>
> >>> v2:
> >>> - New commit
> >>>
> >>> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
> >>> ---
> >>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++++++++++++++++++++++++++
> >>> include/drm/drm_prime.h | 5 +++++
> >>> 2 files changed, 41 insertions(+)
> >>>
> >>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> >>> index 43a10b4af43a..03c09f9ab129 100644
> >>> --- a/drivers/gpu/drm/drm_prime.c
> >>> +++ b/drivers/gpu/drm/drm_prime.c
> >>> @@ -823,6 +823,40 @@ int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
> >>> }
> >>> EXPORT_SYMBOL(drm_gem_dmabuf_mmap);
> >>>
> >>> +int drm_gem_dmabuf_begin_cpu_access(struct dma_buf *dma_buf,
> >>> + enum dma_data_direction direction)
> >>> +{
> >>> + struct drm_gem_object *obj = dma_buf->priv;
> >>> + enum drm_gem_object_access_flags access = DRM_GEM_OBJECT_CPU_ACCESS;
> >>> +
> >>> + if (direction == DMA_FROM_DEVICE)
> >>> + access |= DRM_GEM_OBJECT_READ_ACCESS;
> >>> + else if (direction == DMA_BIDIRECTIONAL)
> >>> + access |= DRM_GEM_OBJECT_RW_ACCESS;
> >>> + else
> >>> + return -EINVAL;
> >>> +
> >>> + return drm_gem_sync(obj, 0, obj->size, access);
> >>> +}
> >>> +EXPORT_SYMBOL(drm_gem_dmabuf_begin_cpu_access);
> >>> +
> >>> +int drm_gem_dmabuf_end_cpu_access(struct dma_buf *dma_buf,
> >>> + enum dma_data_direction direction)
> >>> +{
> >>> + struct drm_gem_object *obj = dma_buf->priv;
> >>> + enum drm_gem_object_access_flags access = DRM_GEM_OBJECT_DEV_ACCESS;
> >>> +
> >>> + if (direction == DMA_TO_DEVICE)
> >>> + access |= DRM_GEM_OBJECT_READ_ACCESS;
> >>> + else if (direction == DMA_BIDIRECTIONAL)
> >>> + access |= DRM_GEM_OBJECT_RW_ACCESS;
> >>> + else
> >>> + return -EINVAL;
> >>> +
> >>> + return drm_gem_sync(obj, 0, obj->size, access);
> >>> +}
> >>> +EXPORT_SYMBOL(drm_gem_dmabuf_end_cpu_access);
> >>
> >> I feel I must be missing something, but why does
> >> drm_gem_dmabuf_begin_cpu_access() reject DMA_TO_DEVICE and
> >> drm_gem_dmabuf_end_cpu_access() reject DMA_FROM_DEVICE?
> >
> > Not really sure what it means to prepare for dev access and synchronize
> > with what the device might have changed in memory. Sounds like device
> > -> device synchronization, which is not what this API is for.
> >
> > Similarly preparing for CPU access with TO_DEVICE (AKA forcing previous
> > CPU changes to be visible to the device) doesn't make sense either.
>
> Well those operations might well be no-ops, but we shouldn't return an
> error just because of that.
Fair enough.
>
> >>
> >> My understanding is that these begin/end calls should be bracketing the
> >> operation and the same direction should be specified for each.
> >
> > If [1] is correct and the begin/end_cpu_access() is based on the
> > dma_sync_ semantics, nope, that's not how it's supposed to work. The
> > way I see it, it just expresses the cache operations you want to take
> > place around your CPU access.
>
> Well that function completely ignored the direction flag. Looking at a
> caller of the APIs it seems very common to bracket the work with the
> same direction - admittedly they are all DMA_FROM_DEVICE examples I've
> found. E.g. a random FB driver:
>
> https://elixir.bootlin.com/linux/v6.17.1/source/drivers/gpu/drm/solomon/ssd130x.c#L1026
>
> > drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
>
> I have to admit I don't really know what the point of this is - and the
> error return isn't used beyond a drm_err(). But we don't want to spam
> the logs with errors!
Sure, I can return zero instead of an error.
>
> > If you read data from the CPU, you want dir=FROM_DEVICE in your
> > begin_cpu_access(), so that the CPU caches are invalidated. If you
> > write from the CPU, you want dir=TO_DEVICE in your end_cpu_access. If
> > you know you will be reading again soon, you might want to pass
> > dir=BIDIR in your end_cpu_access(), though I'm not too sure what's the
> > benefit of that to be honest.
> >
> > [1]https://elixir.bootlin.com/linux/v6.17.1/source/drivers/gpu/drm/tegra/gem.c#L684
>
> The documentation[2] states:
>
> > * - Fallback operations in the kernel, for example when a device is connected
> > * over USB and the kernel needs to shuffle the data around first before
> > * sending it away. Cache coherency is handled by bracketing any transactions
> > * with calls to dma_buf_begin_cpu_access() and dma_buf_end_cpu_access()
> > * access.
>
> So I guess the purpose is where it's not "cache coherency" as such, but
> actually having to shuffle the data between different memories.
The fact it's using the same flags that are used for dma_sync_ ops
makes it so confusing :face_palm:. I wish these were separate R/W
flags instead encoding what the CPU intends to do, and that the API
would make it clear that the same flags should be passed on both begin
and end. Anyway, I guess returning 0 instead of an error fixes the
problem, so I'll do that.
next prev parent reply other threads:[~2025-10-10 16:02 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-10 10:11 [PATCH v2 00/13] drm/panfrost, panthor: Cached maps and explicit flushing Boris Brezillon
2025-10-10 10:11 ` [PATCH v2 01/13] drm/gem: Add a drm_gem_object_funcs::sync() and a drm_gem_sync() helper Boris Brezillon
2025-10-10 10:11 ` [PATCH v2 02/13] drm/prime: Provide default ::{begin, end}_cpu_access() implementations Boris Brezillon
2025-10-10 14:11 ` [PATCH v2 02/13] drm/prime: Provide default ::{begin,end}_cpu_access() implementations Steven Price
2025-10-10 15:03 ` Boris Brezillon
2025-10-10 15:34 ` Steven Price
2025-10-10 16:02 ` Boris Brezillon [this message]
2025-10-10 10:11 ` [PATCH v2 03/13] drm/shmem: Add a drm_gem_shmem_sync() helper Boris Brezillon
2025-10-10 10:11 ` [PATCH v2 04/13] drm/panthor: Expose the selected coherency protocol to the UMD Boris Brezillon
2025-10-10 14:22 ` Steven Price
2025-10-10 15:08 ` Boris Brezillon
2025-10-10 15:36 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 05/13] drm/panthor: Add a PANTHOR_BO_SYNC ioctl Boris Brezillon
2025-10-10 14:31 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 06/13] drm/panthor: Add an ioctl to query BO flags Boris Brezillon
2025-10-10 14:31 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 07/13] drm/panthor: Add flag to map GEM object Write-Back Cacheable Boris Brezillon
2025-10-10 14:41 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 08/13] drm/panthor: Bump the driver version to 1.6 Boris Brezillon
2025-10-10 14:41 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 09/13] drm/panfrost: Expose the selected coherency protocol to the UMD Boris Brezillon
2025-10-10 14:50 ` Steven Price
2025-10-15 11:41 ` Boris Brezillon
2025-10-15 13:18 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 10/13] drm/panfrost: Add a PANFROST_SYNC_BO ioctl Boris Brezillon
2025-10-10 14:57 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 11/13] drm/panfrost: Add an ioctl to query BO flags Boris Brezillon
2025-10-10 15:00 ` Steven Price
2025-10-10 10:11 ` [PATCH v2 12/13] drm/panfrost: Add flag to map GEM object Write-Back Cacheable Boris Brezillon
2025-10-10 15:00 ` Steven Price
2025-10-10 16:31 ` Boris Brezillon
2025-10-10 10:11 ` [PATCH v2 13/13] drm/panfrost: Bump the driver version to 1.6 Boris Brezillon
2025-10-10 15:01 ` Steven Price
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=20251010180234.67306496@fedora \
--to=boris.brezillon@collabora.com \
--cc=adrian.larumbe@collabora.com \
--cc=airlied@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=faith.ekstrand@collabora.com \
--cc=kernel@collabora.com \
--cc=liviu.dudau@arm.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=simona@ffwll.ch \
--cc=steven.price@arm.com \
--cc=tzimmermann@suse.de \
/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.