* [PATCH v2 1/4] drm/rcar-du: Use drm_gem_dma_get_sg_table() helper to get scatter gather table
2026-03-17 6:40 [PATCH v2 0/4] drm: Support DMA per allocation kernel mappings Chen-Yu Tsai
@ 2026-03-17 6:40 ` Chen-Yu Tsai
2026-03-18 16:02 ` Laurent Pinchart
2026-03-17 6:40 ` [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag Chen-Yu Tsai
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-17 6:40 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter
Cc: Rob Herring, Laurent Pinchart, Chen-Yu Tsai, dri-devel,
linux-kernel, linux-arm-kernel, asahi
The rcar-du driver is directly calling dma_get_sgtable() on a
drm_gem_dma_object. Not passing the dma_attrs field in may cause
problems when DMA_ATTR_NO_KERNEL_MAPPING is added to the GEM DMA
helpers gain support later.
Instead, use the drm_gem_dma_get_sg_table() helper to get the scatter
gather table.
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
Changes since v1:
- new patch
Not sure if we should add a helper like drm_fb_dma_get_gem_addr(). This
seems to be the only driver that is using a scatter gather table to pass
DMA addresses.
---
drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
index 94c22d2db197..6a62608ee3a9 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
@@ -291,10 +291,16 @@ int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
dst = sg_next(dst);
}
} else {
- ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr,
- gem->dma_addr, gem->base.size);
- if (ret)
+ struct sg_table *ret_sgt;
+
+ ret_sgt = drm_gem_dma_get_sg_table(gem);
+ if (IS_ERR(ret_sgt)) {
+ ret = PTR_ERR(ret_sgt);
goto fail;
+ }
+
+ memcpy(sgt, ret_sgt, sizeof(*sgt));
+ kfree(ret_sgt);
}
ret = vsp1_du_map_sg(vsp->vsp, sgt);
--
2.53.0.851.ga537e3e6e9-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 1/4] drm/rcar-du: Use drm_gem_dma_get_sg_table() helper to get scatter gather table
2026-03-17 6:40 ` [PATCH v2 1/4] drm/rcar-du: Use drm_gem_dma_get_sg_table() helper to get scatter gather table Chen-Yu Tsai
@ 2026-03-18 16:02 ` Laurent Pinchart
2026-03-18 16:21 ` Chen-Yu Tsai
0 siblings, 1 reply; 13+ messages in thread
From: Laurent Pinchart @ 2026-03-18 16:02 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, dri-devel, linux-kernel,
linux-arm-kernel, asahi
Hi Chen-Yu,
Thank you for the patch.
On Tue, Mar 17, 2026 at 02:40:43PM +0800, Chen-Yu Tsai wrote:
> The rcar-du driver is directly calling dma_get_sgtable() on a
> drm_gem_dma_object. Not passing the dma_attrs field in may cause
> problems when DMA_ATTR_NO_KERNEL_MAPPING is added to the GEM DMA
> helpers gain support later.
>
> Instead, use the drm_gem_dma_get_sg_table() helper to get the scatter
> gather table.
>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> Changes since v1:
> - new patch
>
> Not sure if we should add a helper like drm_fb_dma_get_gem_addr(). This
> seems to be the only driver that is using a scatter gather table to pass
> DMA addresses.
The DU can't access memory directly (at least on Gen3 and newer), and
goes through a separate device called VSP that acts as an external DMA
engine (*) and compositor. This is why buffers need to be mapped
manually to the VSP, the GEM helpers would otherwise use the DU struct
device, which isn't correct. I can't use drm_device.dma_dev as the DMA
initiator can be different per CRTC.
I don't think a separate helper with a single user would be very useful
here, especially given that part of the logic in
drm_fb_dma_get_gem_addr() is in the separate vsp1 driver. Refactoring
may get messy, for little benefit.
* And in some cases the VSP further delegates memory access to the FCP,
which is yet another DMA initiator from an IOMMU point of view.
> ---
> drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> index 94c22d2db197..6a62608ee3a9 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> @@ -291,10 +291,16 @@ int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
> dst = sg_next(dst);
> }
> } else {
> - ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr,
> - gem->dma_addr, gem->base.size);
Did you compile the patch ? The rcdu variable is now unused. Apart from
that, it compiles fine and seems to operate as expected.
> - if (ret)
> + struct sg_table *ret_sgt;
> +
> + ret_sgt = drm_gem_dma_get_sg_table(gem);
> + if (IS_ERR(ret_sgt)) {
> + ret = PTR_ERR(ret_sgt);
> goto fail;
> + }
> +
> + memcpy(sgt, ret_sgt, sizeof(*sgt));
> + kfree(ret_sgt);
It's a bit of a shame to kmalloc() a new sg_table and free it right
after :-/ Would it be that bad to switch to dma_get_sgtable_attrs()
here, and pass gem->dma_attrs to the function ?
> }
>
> ret = vsp1_du_map_sg(vsp->vsp, sgt);
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 1/4] drm/rcar-du: Use drm_gem_dma_get_sg_table() helper to get scatter gather table
2026-03-18 16:02 ` Laurent Pinchart
@ 2026-03-18 16:21 ` Chen-Yu Tsai
2026-03-18 16:27 ` Laurent Pinchart
0 siblings, 1 reply; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-18 16:21 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Chen-Yu Tsai, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Rob Herring, dri-devel, linux-kernel,
linux-arm-kernel, asahi
On Thu, Mar 19, 2026 at 12:02 AM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Chen-Yu,
>
> Thank you for the patch.
>
> On Tue, Mar 17, 2026 at 02:40:43PM +0800, Chen-Yu Tsai wrote:
> > The rcar-du driver is directly calling dma_get_sgtable() on a
> > drm_gem_dma_object. Not passing the dma_attrs field in may cause
> > problems when DMA_ATTR_NO_KERNEL_MAPPING is added to the GEM DMA
> > helpers gain support later.
> >
> > Instead, use the drm_gem_dma_get_sg_table() helper to get the scatter
> > gather table.
> >
> > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> > ---
> > Changes since v1:
> > - new patch
> >
> > Not sure if we should add a helper like drm_fb_dma_get_gem_addr(). This
> > seems to be the only driver that is using a scatter gather table to pass
> > DMA addresses.
>
> The DU can't access memory directly (at least on Gen3 and newer), and
> goes through a separate device called VSP that acts as an external DMA
> engine (*) and compositor. This is why buffers need to be mapped
> manually to the VSP, the GEM helpers would otherwise use the DU struct
> device, which isn't correct. I can't use drm_device.dma_dev as the DMA
> initiator can be different per CRTC.
>
> I don't think a separate helper with a single user would be very useful
> here, especially given that part of the logic in
> drm_fb_dma_get_gem_addr() is in the separate vsp1 driver. Refactoring
> may get messy, for little benefit.
>
> * And in some cases the VSP further delegates memory access to the FCP,
> which is yet another DMA initiator from an IOMMU point of view.
I see. That's probably the most complicated hardware I've seen so far.
> > ---
> > drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c | 12 +++++++++---
> > 1 file changed, 9 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> > index 94c22d2db197..6a62608ee3a9 100644
> > --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> > +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> > @@ -291,10 +291,16 @@ int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
> > dst = sg_next(dst);
> > }
> > } else {
> > - ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr,
> > - gem->dma_addr, gem->base.size);
>
> Did you compile the patch ? The rcdu variable is now unused. Apart from
> that, it compiles fine and seems to operate as expected.
I probably missed it in the logs. Thanks for catching it.
> > - if (ret)
> > + struct sg_table *ret_sgt;
> > +
> > + ret_sgt = drm_gem_dma_get_sg_table(gem);
> > + if (IS_ERR(ret_sgt)) {
> > + ret = PTR_ERR(ret_sgt);
> > goto fail;
> > + }
> > +
> > + memcpy(sgt, ret_sgt, sizeof(*sgt));
> > + kfree(ret_sgt);
>
> It's a bit of a shame to kmalloc() a new sg_table and free it right
> after :-/ Would it be that bad to switch to dma_get_sgtable_attrs()
> here, and pass gem->dma_attrs to the function ?
That's another option. I was trying to isolate the DMA API calls to
just the GEM DMA helpers, but as you said, it's a bit wasteful.
I'll just switch to dma_get_sgtable_attrs() and squash the change into
the other dma_*_attrs() conversion patch.
Thanks
ChenYu
> > }
> >
> > ret = vsp1_du_map_sg(vsp->vsp, sgt);
>
> --
> Regards,
>
> Laurent Pinchart
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 1/4] drm/rcar-du: Use drm_gem_dma_get_sg_table() helper to get scatter gather table
2026-03-18 16:21 ` Chen-Yu Tsai
@ 2026-03-18 16:27 ` Laurent Pinchart
0 siblings, 0 replies; 13+ messages in thread
From: Laurent Pinchart @ 2026-03-18 16:27 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Chen-Yu Tsai, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Rob Herring, dri-devel, linux-kernel,
linux-arm-kernel, asahi
On Thu, Mar 19, 2026 at 12:21:49AM +0800, Chen-Yu Tsai wrote:
> On Thu, Mar 19, 2026 at 12:02 AM Laurent Pinchart wrote:
> > On Tue, Mar 17, 2026 at 02:40:43PM +0800, Chen-Yu Tsai wrote:
> > > The rcar-du driver is directly calling dma_get_sgtable() on a
> > > drm_gem_dma_object. Not passing the dma_attrs field in may cause
> > > problems when DMA_ATTR_NO_KERNEL_MAPPING is added to the GEM DMA
> > > helpers gain support later.
> > >
> > > Instead, use the drm_gem_dma_get_sg_table() helper to get the scatter
> > > gather table.
> > >
> > > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> > > ---
> > > Changes since v1:
> > > - new patch
> > >
> > > Not sure if we should add a helper like drm_fb_dma_get_gem_addr(). This
> > > seems to be the only driver that is using a scatter gather table to pass
> > > DMA addresses.
> >
> > The DU can't access memory directly (at least on Gen3 and newer), and
> > goes through a separate device called VSP that acts as an external DMA
> > engine (*) and compositor. This is why buffers need to be mapped
> > manually to the VSP, the GEM helpers would otherwise use the DU struct
> > device, which isn't correct. I can't use drm_device.dma_dev as the DMA
> > initiator can be different per CRTC.
> >
> > I don't think a separate helper with a single user would be very useful
> > here, especially given that part of the logic in
> > drm_fb_dma_get_gem_addr() is in the separate vsp1 driver. Refactoring
> > may get messy, for little benefit.
> >
> > * And in some cases the VSP further delegates memory access to the FCP,
> > which is yet another DMA initiator from an IOMMU point of view.
>
> I see. That's probably the most complicated hardware I've seen so far.
I felt similar when I found out Gen3 dropped the DMA engines and
compositor previously part of the DU :-)
> > > ---
> > > drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c | 12 +++++++++---
> > > 1 file changed, 9 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> > > index 94c22d2db197..6a62608ee3a9 100644
> > > --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> > > +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c
> > > @@ -291,10 +291,16 @@ int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb,
> > > dst = sg_next(dst);
> > > }
> > > } else {
> > > - ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr,
> > > - gem->dma_addr, gem->base.size);
> >
> > Did you compile the patch ? The rcdu variable is now unused. Apart from
> > that, it compiles fine and seems to operate as expected.
>
> I probably missed it in the logs. Thanks for catching it.
>
> > > - if (ret)
> > > + struct sg_table *ret_sgt;
> > > +
> > > + ret_sgt = drm_gem_dma_get_sg_table(gem);
> > > + if (IS_ERR(ret_sgt)) {
> > > + ret = PTR_ERR(ret_sgt);
> > > goto fail;
> > > + }
> > > +
> > > + memcpy(sgt, ret_sgt, sizeof(*sgt));
> > > + kfree(ret_sgt);
> >
> > It's a bit of a shame to kmalloc() a new sg_table and free it right
> > after :-/ Would it be that bad to switch to dma_get_sgtable_attrs()
> > here, and pass gem->dma_attrs to the function ?
>
> That's another option. I was trying to isolate the DMA API calls to
> just the GEM DMA helpers, but as you said, it's a bit wasteful.
I like the goal of avoiding direct DMA mapping API calls, but I'm
worried it will cause more harm than good in this case :-/
> I'll just switch to dma_get_sgtable_attrs() and squash the change into
> the other dma_*_attrs() conversion patch.
OK.
> > > }
> > >
> > > ret = vsp1_du_map_sg(vsp->vsp, sgt);
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag
2026-03-17 6:40 [PATCH v2 0/4] drm: Support DMA per allocation kernel mappings Chen-Yu Tsai
2026-03-17 6:40 ` [PATCH v2 1/4] drm/rcar-du: Use drm_gem_dma_get_sg_table() helper to get scatter gather table Chen-Yu Tsai
@ 2026-03-17 6:40 ` Chen-Yu Tsai
2026-03-17 8:12 ` Thomas Zimmermann
2026-03-17 6:40 ` [PATCH v2 3/4] drm/gem-dma: Use the dma_*_attr API variant Chen-Yu Tsai
2026-03-17 6:40 ` [PATCH v2 4/4] drm/gem-dma: Support DRM_MODE_DUMB_KERNEL_MAP flag Chen-Yu Tsai
3 siblings, 1 reply; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-17 6:40 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter
Cc: Rob Herring, Laurent Pinchart, dri-devel, linux-kernel,
linux-arm-kernel, asahi, Chen-Yu Tsai
From: Rob Herring <robh@kernel.org>
Introduce a new flag, DRM_MODE_DUMB_KERNEL_MAP, for struct
drm_mode_create_dumb. This flag is for internal kernel use to indicate
if dumb buffer allocation needs a kernel mapping. This is needed only for
CMA where creating a kernel mapping or not has to be decided at allocation
time because creating a mapping on demand (with vmap()) is not guaranteed
to work. Several drivers are using CMA, but not the CMA helpers because
they distinguish between kernel and userspace allocations to create a
kernel mapping or not.
Update the callers of drm_mode_dumb_create() to set
drm_mode_dumb_create.flags to appropriate defaults. Currently, flags can
be set to anything by userspace, but is unused within the kernel. Let's
force flags to zero (no kernel mapping) for userspace callers by default.
For in kernel clients, set DRM_MODE_DUMB_KERNEL_MAP by default. Drivers
can override this as needed.
Signed-off-by: Rob Herring <robh@kernel.org>
[wenst@chromium.org: Emit warning if args->flags is not zero]
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
Changes since v1:
- Emit warning if args->flags is not zero
---
drivers/gpu/drm/drm_client.c | 1 +
drivers/gpu/drm/drm_dumb_buffers.c | 4 ++++
include/uapi/drm/drm_mode.h | 2 ++
3 files changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 46c465bce98c..1a57e7eadc0f 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -404,6 +404,7 @@ drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 heig
dumb_args.width = width;
dumb_args.height = height;
dumb_args.bpp = drm_format_info_bpp(info, 0);
+ dumb_args.flags = DRM_MODE_DUMB_KERNEL_MAP;
ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
if (ret)
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c
index e2b62e5fb891..ccdcc401d4dc 100644
--- a/drivers/gpu/drm/drm_dumb_buffers.c
+++ b/drivers/gpu/drm/drm_dumb_buffers.c
@@ -233,6 +233,10 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
struct drm_mode_create_dumb *args = data;
int err;
+ if (args->flags)
+ drm_warn(dev, "drm_mode_create_dumb.flags is not zero.\n");
+ args->flags = 0;
+
err = drm_mode_create_dumb(dev, args, file_priv);
if (err) {
args->handle = 0;
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 3693d82b5279..7d5f50e4af70 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -1272,6 +1272,8 @@ struct drm_mode_create_dumb {
__u64 size;
};
+#define DRM_MODE_DUMB_KERNEL_MAP (1<<0) /* For internal kernel use */
+
/* set up for mmap of a dumb scanout buffer */
struct drm_mode_map_dumb {
/** Handle for the object being mapped. */
--
2.53.0.851.ga537e3e6e9-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag
2026-03-17 6:40 ` [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag Chen-Yu Tsai
@ 2026-03-17 8:12 ` Thomas Zimmermann
2026-03-17 10:58 ` Chen-Yu Tsai
0 siblings, 1 reply; 13+ messages in thread
From: Thomas Zimmermann @ 2026-03-17 8:12 UTC (permalink / raw)
To: Chen-Yu Tsai, Maarten Lankhorst, Maxime Ripard, David Airlie,
Simona Vetter
Cc: Rob Herring, Laurent Pinchart, dri-devel, linux-kernel,
linux-arm-kernel, asahi
Hi
Am 17.03.26 um 07:40 schrieb Chen-Yu Tsai:
> From: Rob Herring <robh@kernel.org>
>
> Introduce a new flag, DRM_MODE_DUMB_KERNEL_MAP, for struct
> drm_mode_create_dumb. This flag is for internal kernel use to indicate
> if dumb buffer allocation needs a kernel mapping. This is needed only for
> CMA where creating a kernel mapping or not has to be decided at allocation
> time because creating a mapping on demand (with vmap()) is not guaranteed
> to work. Several drivers are using CMA, but not the CMA helpers because
> they distinguish between kernel and userspace allocations to create a
> kernel mapping or not.
Any dumb allocation might require vmap. This is not limited to internal
buffers. Because if the dumb buffer is shared with another driver, that
driver might require the vmap for displaying the buffer content. There
are enough of such drivers.
>
> Update the callers of drm_mode_dumb_create() to set
> drm_mode_dumb_create.flags to appropriate defaults. Currently, flags can
> be set to anything by userspace, but is unused within the kernel. Let's
> force flags to zero (no kernel mapping) for userspace callers by default.
> For in kernel clients, set DRM_MODE_DUMB_KERNEL_MAP by default. Drivers
> can override this as needed.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
> [wenst@chromium.org: Emit warning if args->flags is not zero]
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
> Changes since v1:
> - Emit warning if args->flags is not zero
> ---
> drivers/gpu/drm/drm_client.c | 1 +
> drivers/gpu/drm/drm_dumb_buffers.c | 4 ++++
> include/uapi/drm/drm_mode.h | 2 ++
> 3 files changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
> index 46c465bce98c..1a57e7eadc0f 100644
> --- a/drivers/gpu/drm/drm_client.c
> +++ b/drivers/gpu/drm/drm_client.c
> @@ -404,6 +404,7 @@ drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 heig
> dumb_args.width = width;
> dumb_args.height = height;
> dumb_args.bpp = drm_format_info_bpp(info, 0);
> + dumb_args.flags = DRM_MODE_DUMB_KERNEL_MAP;
> ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
> if (ret)
> return ERR_PTR(ret);
> diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c
> index e2b62e5fb891..ccdcc401d4dc 100644
> --- a/drivers/gpu/drm/drm_dumb_buffers.c
> +++ b/drivers/gpu/drm/drm_dumb_buffers.c
> @@ -233,6 +233,10 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
> struct drm_mode_create_dumb *args = data;
> int err;
>
> + if (args->flags)
> + drm_warn(dev, "drm_mode_create_dumb.flags is not zero.\n");
At most use drm_warn_once() to not let this spam the kernel log.
> + args->flags = 0;
> +
> err = drm_mode_create_dumb(dev, args, file_priv);
> if (err) {
> args->handle = 0;
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 3693d82b5279..7d5f50e4af70 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -1272,6 +1272,8 @@ struct drm_mode_create_dumb {
> __u64 size;
> };
>
> +#define DRM_MODE_DUMB_KERNEL_MAP (1<<0) /* For internal kernel use */
> +
If this is an internal flag, it should not live in the UAPI header.
include/drm/drm_dumb_buffers.h would be a good place.
Best regards
Thomas
> /* set up for mmap of a dumb scanout buffer */
> struct drm_mode_map_dumb {
> /** Handle for the object being mapped. */
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag
2026-03-17 8:12 ` Thomas Zimmermann
@ 2026-03-17 10:58 ` Chen-Yu Tsai
2026-03-17 12:24 ` Thomas Zimmermann
0 siblings, 1 reply; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-17 10:58 UTC (permalink / raw)
To: Thomas Zimmermann
Cc: Chen-Yu Tsai, Maarten Lankhorst, Maxime Ripard, David Airlie,
Simona Vetter, Rob Herring, Laurent Pinchart, dri-devel,
linux-kernel, linux-arm-kernel, asahi
On Tue, Mar 17, 2026 at 4:12 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 17.03.26 um 07:40 schrieb Chen-Yu Tsai:
> > From: Rob Herring <robh@kernel.org>
> >
> > Introduce a new flag, DRM_MODE_DUMB_KERNEL_MAP, for struct
> > drm_mode_create_dumb. This flag is for internal kernel use to indicate
> > if dumb buffer allocation needs a kernel mapping. This is needed only for
> > CMA where creating a kernel mapping or not has to be decided at allocation
> > time because creating a mapping on demand (with vmap()) is not guaranteed
> > to work. Several drivers are using CMA, but not the CMA helpers because
> > they distinguish between kernel and userspace allocations to create a
> > kernel mapping or not.
>
> Any dumb allocation might require vmap. This is not limited to internal
> buffers. Because if the dumb buffer is shared with another driver, that
> driver might require the vmap for displaying the buffer content. There
> are enough of such drivers.
By sharing, do you mean exported via PRIME then imported by another device?
Or just passing around GEM objects within the kernel?
And could you provide an example?
> > Update the callers of drm_mode_dumb_create() to set
> > drm_mode_dumb_create.flags to appropriate defaults. Currently, flags can
> > be set to anything by userspace, but is unused within the kernel. Let's
> > force flags to zero (no kernel mapping) for userspace callers by default.
> > For in kernel clients, set DRM_MODE_DUMB_KERNEL_MAP by default. Drivers
> > can override this as needed.
> >
> > Signed-off-by: Rob Herring <robh@kernel.org>
> > [wenst@chromium.org: Emit warning if args->flags is not zero]
> > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> > ---
> > Changes since v1:
> > - Emit warning if args->flags is not zero
> > ---
> > drivers/gpu/drm/drm_client.c | 1 +
> > drivers/gpu/drm/drm_dumb_buffers.c | 4 ++++
> > include/uapi/drm/drm_mode.h | 2 ++
> > 3 files changed, 7 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
> > index 46c465bce98c..1a57e7eadc0f 100644
> > --- a/drivers/gpu/drm/drm_client.c
> > +++ b/drivers/gpu/drm/drm_client.c
> > @@ -404,6 +404,7 @@ drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 heig
> > dumb_args.width = width;
> > dumb_args.height = height;
> > dumb_args.bpp = drm_format_info_bpp(info, 0);
> > + dumb_args.flags = DRM_MODE_DUMB_KERNEL_MAP;
> > ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
> > if (ret)
> > return ERR_PTR(ret);
> > diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c
> > index e2b62e5fb891..ccdcc401d4dc 100644
> > --- a/drivers/gpu/drm/drm_dumb_buffers.c
> > +++ b/drivers/gpu/drm/drm_dumb_buffers.c
> > @@ -233,6 +233,10 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
> > struct drm_mode_create_dumb *args = data;
> > int err;
> >
> > + if (args->flags)
> > + drm_warn(dev, "drm_mode_create_dumb.flags is not zero.\n");
>
> At most use drm_warn_once() to not let this spam the kernel log.
Sure.
> > + args->flags = 0;
> > +
> > err = drm_mode_create_dumb(dev, args, file_priv);
> > if (err) {
> > args->handle = 0;
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 3693d82b5279..7d5f50e4af70 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -1272,6 +1272,8 @@ struct drm_mode_create_dumb {
> > __u64 size;
> > };
> >
> > +#define DRM_MODE_DUMB_KERNEL_MAP (1<<0) /* For internal kernel use */
> > +
>
> If this is an internal flag, it should not live in the UAPI header.
> include/drm/drm_dumb_buffers.h would be a good place.
Makes sense.
Thanks
ChenYu
> Best regards
> Thomas
>
> > /* set up for mmap of a dumb scanout buffer */
> > struct drm_mode_map_dumb {
> > /** Handle for the object being mapped. */
>
> --
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag
2026-03-17 10:58 ` Chen-Yu Tsai
@ 2026-03-17 12:24 ` Thomas Zimmermann
2026-03-18 4:57 ` Chen-Yu Tsai
0 siblings, 1 reply; 13+ messages in thread
From: Thomas Zimmermann @ 2026-03-17 12:24 UTC (permalink / raw)
To: wens
Cc: Chen-Yu Tsai, Maarten Lankhorst, Maxime Ripard, David Airlie,
Simona Vetter, Rob Herring, Laurent Pinchart, dri-devel,
linux-kernel, linux-arm-kernel, asahi
Hi
Am 17.03.26 um 11:58 schrieb Chen-Yu Tsai:
> On Tue, Mar 17, 2026 at 4:12 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> Hi
>>
>> Am 17.03.26 um 07:40 schrieb Chen-Yu Tsai:
>>> From: Rob Herring <robh@kernel.org>
>>>
>>> Introduce a new flag, DRM_MODE_DUMB_KERNEL_MAP, for struct
>>> drm_mode_create_dumb. This flag is for internal kernel use to indicate
>>> if dumb buffer allocation needs a kernel mapping. This is needed only for
>>> CMA where creating a kernel mapping or not has to be decided at allocation
>>> time because creating a mapping on demand (with vmap()) is not guaranteed
>>> to work. Several drivers are using CMA, but not the CMA helpers because
>>> they distinguish between kernel and userspace allocations to create a
>>> kernel mapping or not.
>> Any dumb allocation might require vmap. This is not limited to internal
>> buffers. Because if the dumb buffer is shared with another driver, that
>> driver might require the vmap for displaying the buffer content. There
>> are enough of such drivers.
> By sharing, do you mean exported via PRIME then imported by another device?
> Or just passing around GEM objects within the kernel?
I mean PRIME/dma-buf sharing.
>
> And could you provide an example?
Create a dumb GEM buffer on one of those CMA devices and mirror it to a
display or udl device. These devices have no means of scanning out the
provided buffer directly, so their drivers vmap the buffer and copy the
pixel data into their internal memory (via a peripheral bus). The vmap
call happens via the kernel's internal dma-buf interfaces. Hence any
driver needs support for vmap if it wants to support this use case.
Best regards
Thomas
>
>>> Update the callers of drm_mode_dumb_create() to set
>>> drm_mode_dumb_create.flags to appropriate defaults. Currently, flags can
>>> be set to anything by userspace, but is unused within the kernel. Let's
>>> force flags to zero (no kernel mapping) for userspace callers by default.
>>> For in kernel clients, set DRM_MODE_DUMB_KERNEL_MAP by default. Drivers
>>> can override this as needed.
>>>
>>> Signed-off-by: Rob Herring <robh@kernel.org>
>>> [wenst@chromium.org: Emit warning if args->flags is not zero]
>>> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
>>> ---
>>> Changes since v1:
>>> - Emit warning if args->flags is not zero
>>> ---
>>> drivers/gpu/drm/drm_client.c | 1 +
>>> drivers/gpu/drm/drm_dumb_buffers.c | 4 ++++
>>> include/uapi/drm/drm_mode.h | 2 ++
>>> 3 files changed, 7 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
>>> index 46c465bce98c..1a57e7eadc0f 100644
>>> --- a/drivers/gpu/drm/drm_client.c
>>> +++ b/drivers/gpu/drm/drm_client.c
>>> @@ -404,6 +404,7 @@ drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 heig
>>> dumb_args.width = width;
>>> dumb_args.height = height;
>>> dumb_args.bpp = drm_format_info_bpp(info, 0);
>>> + dumb_args.flags = DRM_MODE_DUMB_KERNEL_MAP;
>>> ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
>>> if (ret)
>>> return ERR_PTR(ret);
>>> diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c
>>> index e2b62e5fb891..ccdcc401d4dc 100644
>>> --- a/drivers/gpu/drm/drm_dumb_buffers.c
>>> +++ b/drivers/gpu/drm/drm_dumb_buffers.c
>>> @@ -233,6 +233,10 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev,
>>> struct drm_mode_create_dumb *args = data;
>>> int err;
>>>
>>> + if (args->flags)
>>> + drm_warn(dev, "drm_mode_create_dumb.flags is not zero.\n");
>> At most use drm_warn_once() to not let this spam the kernel log.
> Sure.
>
>>> + args->flags = 0;
>>> +
>>> err = drm_mode_create_dumb(dev, args, file_priv);
>>> if (err) {
>>> args->handle = 0;
>>> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
>>> index 3693d82b5279..7d5f50e4af70 100644
>>> --- a/include/uapi/drm/drm_mode.h
>>> +++ b/include/uapi/drm/drm_mode.h
>>> @@ -1272,6 +1272,8 @@ struct drm_mode_create_dumb {
>>> __u64 size;
>>> };
>>>
>>> +#define DRM_MODE_DUMB_KERNEL_MAP (1<<0) /* For internal kernel use */
>>> +
>> If this is an internal flag, it should not live in the UAPI header.
>> include/drm/drm_dumb_buffers.h would be a good place.
> Makes sense.
>
>
> Thanks
> ChenYu
>
>> Best regards
>> Thomas
>>
>>> /* set up for mmap of a dumb scanout buffer */
>>> struct drm_mode_map_dumb {
>>> /** Handle for the object being mapped. */
>> --
>> --
>> Thomas Zimmermann
>> Graphics Driver Developer
>> SUSE Software Solutions Germany GmbH
>> Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
>> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
>>
>>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag
2026-03-17 12:24 ` Thomas Zimmermann
@ 2026-03-18 4:57 ` Chen-Yu Tsai
2026-03-18 6:51 ` Chen-Yu Tsai
0 siblings, 1 reply; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-18 4:57 UTC (permalink / raw)
To: Thomas Zimmermann
Cc: wens, Maarten Lankhorst, Maxime Ripard, David Airlie,
Simona Vetter, Rob Herring, Laurent Pinchart, dri-devel,
linux-kernel, linux-arm-kernel, asahi, AngeloGioacchino Del Regno
On Tue, Mar 17, 2026 at 8:24 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 17.03.26 um 11:58 schrieb Chen-Yu Tsai:
> > On Tue, Mar 17, 2026 at 4:12 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >> Hi
> >>
> >> Am 17.03.26 um 07:40 schrieb Chen-Yu Tsai:
> >>> From: Rob Herring <robh@kernel.org>
> >>>
> >>> Introduce a new flag, DRM_MODE_DUMB_KERNEL_MAP, for struct
> >>> drm_mode_create_dumb. This flag is for internal kernel use to indicate
> >>> if dumb buffer allocation needs a kernel mapping. This is needed only for
> >>> CMA where creating a kernel mapping or not has to be decided at allocation
> >>> time because creating a mapping on demand (with vmap()) is not guaranteed
> >>> to work. Several drivers are using CMA, but not the CMA helpers because
> >>> they distinguish between kernel and userspace allocations to create a
> >>> kernel mapping or not.
> >> Any dumb allocation might require vmap. This is not limited to internal
> >> buffers. Because if the dumb buffer is shared with another driver, that
> >> driver might require the vmap for displaying the buffer content. There
> >> are enough of such drivers.
> > By sharing, do you mean exported via PRIME then imported by another device?
> > Or just passing around GEM objects within the kernel?
>
> I mean PRIME/dma-buf sharing.
>
> >
> > And could you provide an example?
>
> Create a dumb GEM buffer on one of those CMA devices and mirror it to a
> display or udl device. These devices have no means of scanning out the
> provided buffer directly, so their drivers vmap the buffer and copy the
> pixel data into their internal memory (via a peripheral bus). The vmap
> call happens via the kernel's internal dma-buf interfaces. Hence any
> driver needs support for vmap if it wants to support this use case.
I see.
In that case would it make sense to limit not setting this new flag to
drivers that already specify DMA_ATTR_NO_KERNEL_MAPPING? Or rather
inverting it so the default without the flag is to have the kernel
mapping. It would be opt-in rather than opt-out.
This includes just exynos, rockchip, and previously mediatek. Having
this would allow moving them closer to fully utilizing the GEM DMA
helpers without changing their existing behavior.
The flag was removed from the mediatek driver during a previous
refactoring to move it to the GEM DMA helpers, but I think it was
a limitation of the helpers, not an intended change. Angelo might
be able to provide some context around that.
Or maybe I just keep the dma_*_attr() conversion patch to satisfy
the needs of the aforementioned drivers? What do you think?
Thanks
ChenYu
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag
2026-03-18 4:57 ` Chen-Yu Tsai
@ 2026-03-18 6:51 ` Chen-Yu Tsai
0 siblings, 0 replies; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-18 6:51 UTC (permalink / raw)
To: Thomas Zimmermann
Cc: wens, Maarten Lankhorst, Maxime Ripard, David Airlie,
Simona Vetter, Rob Herring, Laurent Pinchart, dri-devel,
linux-kernel, linux-arm-kernel, asahi, AngeloGioacchino Del Regno
On Wed, Mar 18, 2026 at 12:57 PM Chen-Yu Tsai <wenst@chromium.org> wrote:
>
> On Tue, Mar 17, 2026 at 8:24 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >
> > Hi
> >
> > Am 17.03.26 um 11:58 schrieb Chen-Yu Tsai:
> > > On Tue, Mar 17, 2026 at 4:12 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
> > >> Hi
> > >>
> > >> Am 17.03.26 um 07:40 schrieb Chen-Yu Tsai:
> > >>> From: Rob Herring <robh@kernel.org>
> > >>>
> > >>> Introduce a new flag, DRM_MODE_DUMB_KERNEL_MAP, for struct
> > >>> drm_mode_create_dumb. This flag is for internal kernel use to indicate
> > >>> if dumb buffer allocation needs a kernel mapping. This is needed only for
> > >>> CMA where creating a kernel mapping or not has to be decided at allocation
> > >>> time because creating a mapping on demand (with vmap()) is not guaranteed
> > >>> to work. Several drivers are using CMA, but not the CMA helpers because
> > >>> they distinguish between kernel and userspace allocations to create a
> > >>> kernel mapping or not.
> > >> Any dumb allocation might require vmap. This is not limited to internal
> > >> buffers. Because if the dumb buffer is shared with another driver, that
> > >> driver might require the vmap for displaying the buffer content. There
> > >> are enough of such drivers.
> > > By sharing, do you mean exported via PRIME then imported by another device?
> > > Or just passing around GEM objects within the kernel?
> >
> > I mean PRIME/dma-buf sharing.
> >
> > >
> > > And could you provide an example?
> >
> > Create a dumb GEM buffer on one of those CMA devices and mirror it to a
> > display or udl device. These devices have no means of scanning out the
> > provided buffer directly, so their drivers vmap the buffer and copy the
> > pixel data into their internal memory (via a peripheral bus). The vmap
> > call happens via the kernel's internal dma-buf interfaces. Hence any
> > driver needs support for vmap if it wants to support this use case.
>
> I see.
>
> In that case would it make sense to limit not setting this new flag to
> drivers that already specify DMA_ATTR_NO_KERNEL_MAPPING? Or rather
> inverting it so the default without the flag is to have the kernel
> mapping. It would be opt-in rather than opt-out.
I guess this won't work since drm_client_buffer_create_dumb() calls
drm_mode_create_dumb(), and we need a way from the upper layer to
say we need the mapping.
> This includes just exynos, rockchip, and previously mediatek. Having
> this would allow moving them closer to fully utilizing the GEM DMA
> helpers without changing their existing behavior.
>
> The flag was removed from the mediatek driver during a previous
> refactoring to move it to the GEM DMA helpers, but I think it was
> a limitation of the helpers, not an intended change. Angelo might
> be able to provide some context around that.
>
> Or maybe I just keep the dma_*_attr() conversion patch to satisfy
> the needs of the aforementioned drivers? What do you think?
>
>
> Thanks
> ChenYu
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 3/4] drm/gem-dma: Use the dma_*_attr API variant
2026-03-17 6:40 [PATCH v2 0/4] drm: Support DMA per allocation kernel mappings Chen-Yu Tsai
2026-03-17 6:40 ` [PATCH v2 1/4] drm/rcar-du: Use drm_gem_dma_get_sg_table() helper to get scatter gather table Chen-Yu Tsai
2026-03-17 6:40 ` [PATCH v2 2/4] drm: Introduce DRM_MODE_DUMB_KERNEL_MAP flag Chen-Yu Tsai
@ 2026-03-17 6:40 ` Chen-Yu Tsai
2026-03-17 6:40 ` [PATCH v2 4/4] drm/gem-dma: Support DRM_MODE_DUMB_KERNEL_MAP flag Chen-Yu Tsai
3 siblings, 0 replies; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-17 6:40 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter
Cc: Rob Herring, Laurent Pinchart, dri-devel, linux-kernel,
linux-arm-kernel, asahi, Chen-Yu Tsai
From: Rob Herring <robh@kernel.org>
In preparation to allow DRM DMA users to adjust the DMA_ATTR_* flags,
convert the DMA helper code to use the dma_*_attr APIs instead of the
dma_*_wc variants.
Only the DMA_ATTR_WRITE_COMBINE and DMA_ATTR_NO_WARN attributes are set
in this commit, so there's no functional change.
Also change the dma_free_wc() call in vc4_bo_purge() in the vc4 driver
to use dma_free_attrs() to match. vc4_bo is a sub-class of
drm_gem_dma_object.
Sub-classes of |struct drm_gem_dma_object| can also set additional
DMA_ATTR_* flags if they choose so. For example a sub-class could
set DMA_ATTR_FORCE_CONTIGUOUS in certain cases.
Signed-off-by: Rob Herring <robh@kernel.org>
[wenst@chromium.org: Rebase onto renamed DMA helpers]
[wenst@chromium.org: Make vc4_bo_purge() use matching dma_free_attrs()]
[wenst@chromium.org: Expand commit message to mention that sub-classes
can set extra DMA_ATTR_* flags]
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
Changes since v1:
- Rebased onto renamed DMA helpers
- Made vc4_bo_purge() use matching dma_free_attrs()
- Expanded commit message to mention that sub-classes can set extra
DMA_ATTR_* flags
---
drivers/gpu/drm/drm_gem_dma_helper.c | 26 +++++++++++++++-----------
drivers/gpu/drm/vc4/vc4_bo.c | 2 +-
include/drm/drm_gem_dma_helper.h | 3 +++
3 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c
index 1c00a71ab3c9..9722c9fc86f3 100644
--- a/drivers/gpu/drm/drm_gem_dma_helper.c
+++ b/drivers/gpu/drm/drm_gem_dma_helper.c
@@ -108,6 +108,7 @@ __drm_gem_dma_create(struct drm_device *drm, size_t size, bool private)
goto error;
}
+ dma_obj->dma_attrs |= DMA_ATTR_NO_WARN | DMA_ATTR_WRITE_COMBINE;
return dma_obj;
error:
@@ -152,9 +153,10 @@ struct drm_gem_dma_object *drm_gem_dma_create(struct drm_device *drm,
DMA_TO_DEVICE,
GFP_KERNEL | __GFP_NOWARN);
} else {
- dma_obj->vaddr = dma_alloc_wc(drm_dev_dma_dev(drm), size,
- &dma_obj->dma_addr,
- GFP_KERNEL | __GFP_NOWARN);
+ dma_obj->vaddr = dma_alloc_attrs(drm_dev_dma_dev(drm), size,
+ &dma_obj->dma_addr,
+ GFP_KERNEL | __GFP_NOWARN,
+ dma_obj->dma_attrs);
}
if (!dma_obj->vaddr) {
drm_dbg(drm, "failed to allocate buffer with size %zu\n",
@@ -242,9 +244,9 @@ void drm_gem_dma_free(struct drm_gem_dma_object *dma_obj)
dma_obj->vaddr, dma_obj->dma_addr,
DMA_TO_DEVICE);
else
- dma_free_wc(drm_dev_dma_dev(gem_obj->dev),
- dma_obj->base.size, dma_obj->vaddr,
- dma_obj->dma_addr);
+ dma_free_attrs(drm_dev_dma_dev(gem_obj->dev),
+ dma_obj->base.size, dma_obj->vaddr,
+ dma_obj->dma_addr, dma_obj->dma_attrs);
}
drm_gem_object_release(gem_obj);
@@ -435,8 +437,9 @@ struct sg_table *drm_gem_dma_get_sg_table(struct drm_gem_dma_object *dma_obj)
if (!sgt)
return ERR_PTR(-ENOMEM);
- ret = dma_get_sgtable(drm_dev_dma_dev(obj->dev), sgt, dma_obj->vaddr,
- dma_obj->dma_addr, obj->size);
+ ret = dma_get_sgtable_attrs(drm_dev_dma_dev(obj->dev), sgt,
+ dma_obj->vaddr, dma_obj->dma_addr,
+ obj->size, dma_obj->dma_attrs);
if (ret < 0)
goto out;
@@ -546,9 +549,10 @@ int drm_gem_dma_mmap(struct drm_gem_dma_object *dma_obj, struct vm_area_struct *
vma, vma->vm_end - vma->vm_start,
virt_to_page(dma_obj->vaddr));
} else {
- ret = dma_mmap_wc(drm_dev_dma_dev(dma_obj->base.dev), vma,
- dma_obj->vaddr, dma_obj->dma_addr,
- vma->vm_end - vma->vm_start);
+ ret = dma_mmap_attrs(drm_dev_dma_dev(dma_obj->base.dev), vma,
+ dma_obj->vaddr, dma_obj->dma_addr,
+ vma->vm_end - vma->vm_start,
+ dma_obj->dma_attrs);
}
if (ret)
drm_gem_vm_close(vma);
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index f45ba47b4ba8..981593739a0f 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -304,7 +304,7 @@ static void vc4_bo_purge(struct drm_gem_object *obj)
drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
- dma_free_wc(dev->dev, obj->size, bo->base.vaddr, bo->base.dma_addr);
+ dma_free_attrs(dev->dev, obj->size, bo->base.vaddr, bo->base.dma_addr, bo->base.dma_attrs);
bo->base.vaddr = NULL;
bo->madv = __VC4_MADV_PURGED;
}
diff --git a/include/drm/drm_gem_dma_helper.h b/include/drm/drm_gem_dma_helper.h
index f2678e7ecb98..e815ff121e23 100644
--- a/include/drm/drm_gem_dma_helper.h
+++ b/include/drm/drm_gem_dma_helper.h
@@ -16,6 +16,8 @@ struct drm_mode_create_dumb;
* more than one entry but they are guaranteed to have contiguous
* DMA addresses.
* @vaddr: kernel virtual address of the backing memory
+ * @dma_attrs: DMA attributes used when allocating backing memory.
+ * Only applies to coherent memory.
* @map_noncoherent: if true, the GEM object is backed by non-coherent memory
*/
struct drm_gem_dma_object {
@@ -25,6 +27,7 @@ struct drm_gem_dma_object {
/* For objects with DMA memory allocated by GEM DMA */
void *vaddr;
+ unsigned long dma_attrs;
bool map_noncoherent;
};
--
2.53.0.851.ga537e3e6e9-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH v2 4/4] drm/gem-dma: Support DRM_MODE_DUMB_KERNEL_MAP flag
2026-03-17 6:40 [PATCH v2 0/4] drm: Support DMA per allocation kernel mappings Chen-Yu Tsai
` (2 preceding siblings ...)
2026-03-17 6:40 ` [PATCH v2 3/4] drm/gem-dma: Use the dma_*_attr API variant Chen-Yu Tsai
@ 2026-03-17 6:40 ` Chen-Yu Tsai
3 siblings, 0 replies; 13+ messages in thread
From: Chen-Yu Tsai @ 2026-03-17 6:40 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter
Cc: Rob Herring, Laurent Pinchart, dri-devel, linux-kernel,
linux-arm-kernel, asahi, Chen-Yu Tsai, Sasha Finkelstein,
Janne Grunau
From: Rob Herring <robh@kernel.org>
Add support in DMA helpers to handle callers specifying
DRM_MODE_DUMB_KERNEL_MAP flag. Existing behavior is maintained with this
change. drm_gem_dma_dumb_create() always creates a kernel mapping as
before. drm_gem_dma_dumb_create_internal() lets the caller set the flags
as desired.
Most drivers that use drm_gem_dma_dumb_create_internal() are already
using the internal client interface via drm_client_setup*() and
DRM_FBDEV_DMA_DRIVER_OPS, and do not have other direct kernel
accesses to the buffer memory internally. Therefore, there is no need
to add the DRM_MODE_DUMB_KERNEL_MAP flag for them.
The only outlier is the adp driver. The DRM_MODE_DUMB_KERNEL_MAP flag
is added to its dumb_create() function, adp_drm_gem_dumb_create().
Signed-off-by: Rob Herring <robh@kernel.org>
[wenst@chromium.org: Rebase onto renamed GEM DMA helpers]
[wenst@chromium.org: show "vaddr=(no mapping)" in drm_gem_dma_print_info()]
[wenst@chromium.org: Drop DRM_MODE_DUMB_KERNEL_MAP driver changes]
[wenst@chromium.org: Add DRM_MODE_DUMB_KERNEL_MAP to adp_drm_gem_dumb_create()]
[wenst@chromium.org: Add flags field to drm_gem_dma_create_with_handle()
kerneldoc]
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
Changes since v1:
- Rebased onto renamed GEM DMA helpers
- Added check in drm_fb_dma_get_scanout_buffer() and drm_gem_dma_vmap().
- Made drm_gem_dma_print_info() show "vaddr=(no mapping)" for objects
allocated without kernel mapping
- Dropped existing DRM_MODE_DUMB_KERNEL_MAP flag addition in various
drivers
- Added DRM_MODE_DUMB_KERNEL_MAP flag to adp_drm_gem_dumb_create()
- Added flags field kerneldoc for drm_gem_dma_create_with_handle()
Cc: Sasha Finkelstein <fnkl.kernel@gmail.com>
Cc: Janne Grunau <j@jannau.net>
Cc: asahi@lists.linux.dev
---
drivers/gpu/drm/adp/adp_drv.c | 1 +
drivers/gpu/drm/drm_fb_dma_helper.c | 4 ++
drivers/gpu/drm/drm_gem_dma_helper.c | 67 +++++++++++++++++-----------
3 files changed, 47 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/adp/adp_drv.c b/drivers/gpu/drm/adp/adp_drv.c
index 4554cf75565e..c549b44b3814 100644
--- a/drivers/gpu/drm/adp/adp_drv.c
+++ b/drivers/gpu/drm/adp/adp_drv.c
@@ -95,6 +95,7 @@ static int adp_drm_gem_dumb_create(struct drm_file *file_priv,
{
args->height = ALIGN(args->height, 64);
args->size = args->pitch * args->height;
+ args->flags = DRM_MODE_DUMB_KERNEL_MAP;
return drm_gem_dma_dumb_create_internal(file_priv, drm, args);
}
diff --git a/drivers/gpu/drm/drm_fb_dma_helper.c b/drivers/gpu/drm/drm_fb_dma_helper.c
index fd71969d2fb1..12a44accc48c 100644
--- a/drivers/gpu/drm/drm_fb_dma_helper.c
+++ b/drivers/gpu/drm/drm_fb_dma_helper.c
@@ -187,6 +187,10 @@ int drm_fb_dma_get_scanout_buffer(struct drm_plane *plane,
if (!dma_obj->vaddr)
return -ENODEV;
+ /* Buffer was allocated with NO_KERNEL_MAPPING */
+ if (dma_obj->dma_attrs & DMA_ATTR_NO_KERNEL_MAPPING)
+ return -ENODEV;
+
iosys_map_set_vaddr(&sb->map[0], dma_obj->vaddr);
sb->format = fb->format;
sb->height = fb->height;
diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c
index 9722c9fc86f3..281fb563f061 100644
--- a/drivers/gpu/drm/drm_gem_dma_helper.c
+++ b/drivers/gpu/drm/drm_gem_dma_helper.c
@@ -116,26 +116,8 @@ __drm_gem_dma_create(struct drm_device *drm, size_t size, bool private)
return ERR_PTR(ret);
}
-/**
- * drm_gem_dma_create - allocate an object with the given size
- * @drm: DRM device
- * @size: size of the object to allocate
- *
- * This function creates a DMA GEM object and allocates memory as backing store.
- * The allocated memory will occupy a contiguous chunk of bus address space.
- *
- * For devices that are directly connected to the memory bus then the allocated
- * memory will be physically contiguous. For devices that access through an
- * IOMMU, then the allocated memory is not expected to be physically contiguous
- * because having contiguous IOVAs is sufficient to meet a devices DMA
- * requirements.
- *
- * Returns:
- * A struct drm_gem_dma_object * on success or an ERR_PTR()-encoded negative
- * error code on failure.
- */
-struct drm_gem_dma_object *drm_gem_dma_create(struct drm_device *drm,
- size_t size)
+static struct drm_gem_dma_object *
+drm_gem_dma_create_flags(struct drm_device *drm, size_t size, u32 flags)
{
struct drm_gem_dma_object *dma_obj;
int ret;
@@ -146,6 +128,9 @@ struct drm_gem_dma_object *drm_gem_dma_create(struct drm_device *drm,
if (IS_ERR(dma_obj))
return dma_obj;
+ if (!(flags & DRM_MODE_DUMB_KERNEL_MAP))
+ dma_obj->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
+
if (dma_obj->map_noncoherent) {
dma_obj->vaddr = dma_alloc_noncoherent(drm_dev_dma_dev(drm),
size,
@@ -171,6 +156,30 @@ struct drm_gem_dma_object *drm_gem_dma_create(struct drm_device *drm,
drm_gem_object_put(&dma_obj->base);
return ERR_PTR(ret);
}
+
+/**
+ * drm_gem_dma_create - allocate an object with the given size
+ * @drm: DRM device
+ * @size: size of the object to allocate
+ *
+ * This function creates a DMA GEM object and allocates memory as backing store.
+ * The allocated memory will occupy a contiguous chunk of bus address space.
+ *
+ * For devices that are directly connected to the memory bus then the allocated
+ * memory will be physically contiguous. For devices that access through an
+ * IOMMU, then the allocated memory is not expected to be physically contiguous
+ * because having contiguous IOVAs is sufficient to meet a devices DMA
+ * requirements.
+ *
+ * Returns:
+ * A struct drm_gem_dma_object * on success or an ERR_PTR()-encoded negative
+ * error code on failure.
+ */
+struct drm_gem_dma_object *drm_gem_dma_create(struct drm_device *drm,
+ size_t size)
+{
+ return drm_gem_dma_create_flags(drm, size, DRM_MODE_DUMB_KERNEL_MAP);
+}
EXPORT_SYMBOL_GPL(drm_gem_dma_create);
/**
@@ -179,6 +188,7 @@ EXPORT_SYMBOL_GPL(drm_gem_dma_create);
* @file_priv: DRM file-private structure to register the handle for
* @drm: DRM device
* @size: size of the object to allocate
+ * @flags: DRM_MODE_DUMB_* flags if any
* @handle: return location for the GEM handle
*
* This function creates a DMA GEM object, allocating a chunk of memory as
@@ -194,14 +204,14 @@ EXPORT_SYMBOL_GPL(drm_gem_dma_create);
*/
static struct drm_gem_dma_object *
drm_gem_dma_create_with_handle(struct drm_file *file_priv,
- struct drm_device *drm, size_t size,
+ struct drm_device *drm, size_t size, u32 flags,
uint32_t *handle)
{
struct drm_gem_dma_object *dma_obj;
struct drm_gem_object *gem_obj;
int ret;
- dma_obj = drm_gem_dma_create(drm, size);
+ dma_obj = drm_gem_dma_create_flags(drm, size, DRM_MODE_DUMB_KERNEL_MAP);
if (IS_ERR(dma_obj))
return dma_obj;
@@ -283,7 +293,7 @@ int drm_gem_dma_dumb_create_internal(struct drm_file *file_priv,
args->size = args->pitch * args->height;
dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args->size,
- &args->handle);
+ args->flags, &args->handle);
return PTR_ERR_OR_ZERO(dma_obj);
}
EXPORT_SYMBOL_GPL(drm_gem_dma_dumb_create_internal);
@@ -313,12 +323,13 @@ int drm_gem_dma_dumb_create(struct drm_file *file_priv,
struct drm_gem_dma_object *dma_obj;
int ret;
+ args->flags = DRM_MODE_DUMB_KERNEL_MAP;
ret = drm_mode_size_dumb(drm, args, 0, 0);
if (ret)
return ret;
dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args->size,
- &args->handle);
+ args->flags, &args->handle);
return PTR_ERR_OR_ZERO(dma_obj);
}
EXPORT_SYMBOL_GPL(drm_gem_dma_dumb_create);
@@ -412,7 +423,10 @@ void drm_gem_dma_print_info(const struct drm_gem_dma_object *dma_obj,
struct drm_printer *p, unsigned int indent)
{
drm_printf_indent(p, indent, "dma_addr=%pad\n", &dma_obj->dma_addr);
- drm_printf_indent(p, indent, "vaddr=%p\n", dma_obj->vaddr);
+ if (dma_obj->dma_attrs & DMA_ATTR_NO_KERNEL_MAPPING)
+ drm_printf_indent(p, indent, "vaddr=(no mapping)\n");
+ else
+ drm_printf_indent(p, indent, "vaddr=%p\n", dma_obj->vaddr);
}
EXPORT_SYMBOL(drm_gem_dma_print_info);
@@ -511,6 +525,9 @@ EXPORT_SYMBOL_GPL(drm_gem_dma_prime_import_sg_table);
int drm_gem_dma_vmap(struct drm_gem_dma_object *dma_obj,
struct iosys_map *map)
{
+ if (dma_obj->dma_attrs & DMA_ATTR_NO_KERNEL_MAPPING)
+ return -ENOMEM;
+
iosys_map_set_vaddr(map, dma_obj->vaddr);
return 0;
--
2.53.0.851.ga537e3e6e9-goog
^ permalink raw reply related [flat|nested] 13+ messages in thread