* [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
@ 2025-05-22 7:07 oushixiong1025
2025-05-22 7:07 ` [PATCH v5 RESEND 2/3] drm/ast: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT oushixiong1025
` (3 more replies)
0 siblings, 4 replies; 22+ messages in thread
From: oushixiong1025 @ 2025-05-22 7:07 UTC (permalink / raw)
To: Christian König
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sean Paul, Jocelyn Falempe, dri-devel,
linux-kernel, Shixiong Ou
From: Shixiong Ou <oushixiong@kylinos.cn>
[WHY]
1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
sg_table import.
They only need dma_buf_vmap() to access the shared buffer's
kernel virtual address.
2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
restricts the maximum DMA streaming mapping memory, resulting in
errors like:
ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
[HOW]
Provide a gem_prime_import implementation without sg_table mapping
to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
require sg_table can adopt this.
Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
---
v1->v2:
Patch rebase.
v2->v3:
Rename the import callback function.
Remove drm_gem_shmem_prime_export() and separate some codes
to drm_gem_prime_import_self().
v3->v4:
Separate the test from the policy.
Rename the macro.
v4->v5:
Rename some functions.
drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
include/drm/drm_gem_shmem_helper.h | 15 +++++++
include/drm/drm_prime.h | 3 ++
4 files changed, 102 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index aa43265f4f4f..126aa79042ad 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
}
EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
+/**
+ * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
+ * @dev: Device to import into
+ * @dma_buf: dma-buf object to import
+ *
+ * Drivers that use the shmem helpers but also wants to import dmabuf without
+ * mapping its sg_table can use this as their &drm_driver.gem_prime_import
+ * implementation.
+ */
+struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
+ struct dma_buf *dma_buf)
+{
+ struct dma_buf_attachment *attach;
+ struct drm_gem_shmem_object *shmem;
+ struct drm_gem_object *obj;
+ size_t size;
+ int ret;
+
+ if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
+ /*
+ * Importing dmabuf exported from our own gem increases
+ * refcount on gem itself instead of f_count of dmabuf.
+ */
+ obj = dma_buf->priv;
+ drm_gem_object_get(obj);
+ return obj;
+ }
+
+ attach = dma_buf_attach(dma_buf, dev->dev);
+ if (IS_ERR(attach))
+ return ERR_CAST(attach);
+
+ get_dma_buf(dma_buf);
+
+ size = PAGE_ALIGN(attach->dmabuf->size);
+
+ shmem = __drm_gem_shmem_create(dev, size, true, NULL);
+ if (IS_ERR(shmem)) {
+ ret = PTR_ERR(shmem);
+ goto fail_detach;
+ }
+
+ drm_dbg_prime(dev, "size = %zu\n", size);
+
+ shmem->base.import_attach = attach;
+ shmem->base.resv = dma_buf->resv;
+
+ return &shmem->base;
+
+fail_detach:
+ dma_buf_detach(dma_buf, attach);
+ dma_buf_put(dma_buf);
+
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
+
MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
MODULE_IMPORT_NS("DMA_BUF");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index d828502268b8..b825b71038d6 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
}
EXPORT_SYMBOL(drm_gem_prime_export);
+
+/**
+ * drm_gem_is_prime_exported_dma_buf -
+ * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
+ * @dev: drm_device to check against
+ * @dma_buf: dma-buf object to import
+ *
+ * Return: true if the DMA-BUF was exported from a GEM object belonging
+ * to @dev, false otherwise.
+ */
+
+bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
+ struct dma_buf *dma_buf)
+{
+ struct drm_gem_object *obj = dma_buf->priv;
+
+ return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
+}
+EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
+
/**
* drm_gem_prime_import_dev - core implementation of the import callback
* @dev: drm_device to import into
@@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
struct drm_gem_object *obj;
int ret;
- if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
+ if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
+ /*
+ * Importing dmabuf exported from our own gem increases
+ * refcount on gem itself instead of f_count of dmabuf.
+ */
obj = dma_buf->priv;
- if (obj->dev == dev) {
- /*
- * Importing dmabuf exported from our own gem increases
- * refcount on gem itself instead of f_count of dmabuf.
- */
- drm_gem_object_get(obj);
- return obj;
- }
+ drm_gem_object_get(obj);
+ return obj;
}
if (!dev->driver->gem_prime_import_sg_table)
diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
index b4f993da3cae..35f7466dca84 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
struct sg_table *sgt);
int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
+struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
+ struct dma_buf *buf);
/**
* DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
@@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
.gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
.dumb_create = drm_gem_shmem_dumb_create
+/**
+ * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
+ * without mapping sg_table on
+ * imported buffer.
+ *
+ * This macro provides a shortcut for setting the shmem GEM operations in
+ * the &drm_driver structure for drivers that do not require a sg_table on
+ * imported buffers.
+ */
+#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
+ .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
+ .dumb_create = drm_gem_shmem_dumb_create
+
#endif /* __DRM_GEM_SHMEM_HELPER_H__ */
diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
index fa085c44d4ca..f50f862f0d8b 100644
--- a/include/drm/drm_prime.h
+++ b/include/drm/drm_prime.h
@@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
/* helper functions for importing */
+bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
+ struct dma_buf *dma_buf);
+
struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
struct dma_buf *dma_buf,
struct device *attach_dev);
--
2.17.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v5 RESEND 2/3] drm/ast: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT
2025-05-22 7:07 [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table oushixiong1025
@ 2025-05-22 7:07 ` oushixiong1025
2025-05-26 13:56 ` Thomas Zimmermann
2025-05-22 7:07 ` [PATCH v5 RESEND 3/3] drm/udl: " oushixiong1025
` (2 subsequent siblings)
3 siblings, 1 reply; 22+ messages in thread
From: oushixiong1025 @ 2025-05-22 7:07 UTC (permalink / raw)
To: Christian König
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sean Paul, Jocelyn Falempe, dri-devel,
linux-kernel, Shixiong Ou
From: Shixiong Ou <oushixiong@kylinos.cn>
Import dmabuf without mapping its sg_table to avoid issues likes:
ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
---
drivers/gpu/drm/ast/ast_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 6fbf62a99c48..054acda41909 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -64,7 +64,7 @@ static const struct drm_driver ast_driver = {
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
- DRM_GEM_SHMEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT,
DRM_FBDEV_SHMEM_DRIVER_OPS,
};
--
2.17.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v5 RESEND 3/3] drm/udl: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT
2025-05-22 7:07 [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table oushixiong1025
2025-05-22 7:07 ` [PATCH v5 RESEND 2/3] drm/ast: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT oushixiong1025
@ 2025-05-22 7:07 ` oushixiong1025
2025-05-26 13:57 ` Thomas Zimmermann
2025-05-26 15:00 ` [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table Thomas Zimmermann
2025-07-11 14:16 ` Thomas Zimmermann
3 siblings, 1 reply; 22+ messages in thread
From: oushixiong1025 @ 2025-05-22 7:07 UTC (permalink / raw)
To: Christian König
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sean Paul, Jocelyn Falempe, dri-devel,
linux-kernel, Shixiong Ou
From: Shixiong Ou <oushixiong@kylinos.cn>
Import dmabuf without mapping its sg_table to avoid issues likes:
udl 2-1.4:1.0: swiotlb buffer is full (sz: 2097152 bytes), total 65536 (slots), used 1 (slots)
Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
---
drivers/gpu/drm/udl/udl_drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index 1922988625eb..ce5ae7cacb90 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -57,7 +57,7 @@ static const struct drm_driver driver = {
/* GEM hooks */
.fops = &udl_driver_fops,
- DRM_GEM_SHMEM_DRIVER_OPS,
+ DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT,
DRM_FBDEV_SHMEM_DRIVER_OPS,
.name = DRIVER_NAME,
--
2.17.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 2/3] drm/ast: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT
2025-05-22 7:07 ` [PATCH v5 RESEND 2/3] drm/ast: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT oushixiong1025
@ 2025-05-26 13:56 ` Thomas Zimmermann
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Zimmermann @ 2025-05-26 13:56 UTC (permalink / raw)
To: oushixiong1025, Christian König
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
> From: Shixiong Ou <oushixiong@kylinos.cn>
>
> Import dmabuf without mapping its sg_table to avoid issues likes:
> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>
> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/ast/ast_drv.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
> index 6fbf62a99c48..054acda41909 100644
> --- a/drivers/gpu/drm/ast/ast_drv.c
> +++ b/drivers/gpu/drm/ast/ast_drv.c
> @@ -64,7 +64,7 @@ static const struct drm_driver ast_driver = {
> .minor = DRIVER_MINOR,
> .patchlevel = DRIVER_PATCHLEVEL,
>
> - DRM_GEM_SHMEM_DRIVER_OPS,
> + DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT,
> DRM_FBDEV_SHMEM_DRIVER_OPS,
> };
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 3/3] drm/udl: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT
2025-05-22 7:07 ` [PATCH v5 RESEND 3/3] drm/udl: " oushixiong1025
@ 2025-05-26 13:57 ` Thomas Zimmermann
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Zimmermann @ 2025-05-26 13:57 UTC (permalink / raw)
To: oushixiong1025, Christian König
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
> From: Shixiong Ou <oushixiong@kylinos.cn>
>
> Import dmabuf without mapping its sg_table to avoid issues likes:
> udl 2-1.4:1.0: swiotlb buffer is full (sz: 2097152 bytes), total 65536 (slots), used 1 (slots)
>
> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/udl/udl_drv.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
> index 1922988625eb..ce5ae7cacb90 100644
> --- a/drivers/gpu/drm/udl/udl_drv.c
> +++ b/drivers/gpu/drm/udl/udl_drv.c
> @@ -57,7 +57,7 @@ static const struct drm_driver driver = {
>
> /* GEM hooks */
> .fops = &udl_driver_fops,
> - DRM_GEM_SHMEM_DRIVER_OPS,
> + DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT,
> DRM_FBDEV_SHMEM_DRIVER_OPS,
>
> .name = DRIVER_NAME,
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-05-22 7:07 [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table oushixiong1025
2025-05-22 7:07 ` [PATCH v5 RESEND 2/3] drm/ast: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT oushixiong1025
2025-05-22 7:07 ` [PATCH v5 RESEND 3/3] drm/udl: " oushixiong1025
@ 2025-05-26 15:00 ` Thomas Zimmermann
2025-06-03 7:49 ` Thomas Zimmermann
2025-07-11 14:16 ` Thomas Zimmermann
3 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-05-26 15:00 UTC (permalink / raw)
To: oushixiong1025, Christian König
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi
Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
> From: Shixiong Ou <oushixiong@kylinos.cn>
>
> [WHY]
> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
> sg_table import.
> They only need dma_buf_vmap() to access the shared buffer's
> kernel virtual address.
>
> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
> restricts the maximum DMA streaming mapping memory, resulting in
> errors like:
>
> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>
> [HOW]
> Provide a gem_prime_import implementation without sg_table mapping
> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
> require sg_table can adopt this.
>
> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Looks good to me, but Christian might want to take a look as well.
Thanks for addressing the issue.
Best regards
Thomas
> ---
> v1->v2:
> Patch rebase.
> v2->v3:
> Rename the import callback function.
> Remove drm_gem_shmem_prime_export() and separate some codes
> to drm_gem_prime_import_self().
> v3->v4:
> Separate the test from the policy.
> Rename the macro.
> v4->v5:
> Rename some functions.
>
> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
> include/drm/drm_gem_shmem_helper.h | 15 +++++++
> include/drm/drm_prime.h | 3 ++
> 4 files changed, 102 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index aa43265f4f4f..126aa79042ad 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
> }
> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>
> +/**
> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
> + * @dev: Device to import into
> + * @dma_buf: dma-buf object to import
> + *
> + * Drivers that use the shmem helpers but also wants to import dmabuf without
> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
> + * implementation.
> + */
> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
> + struct dma_buf *dma_buf)
> +{
> + struct dma_buf_attachment *attach;
> + struct drm_gem_shmem_object *shmem;
> + struct drm_gem_object *obj;
> + size_t size;
> + int ret;
> +
> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
> + /*
> + * Importing dmabuf exported from our own gem increases
> + * refcount on gem itself instead of f_count of dmabuf.
> + */
> + obj = dma_buf->priv;
> + drm_gem_object_get(obj);
> + return obj;
> + }
> +
> + attach = dma_buf_attach(dma_buf, dev->dev);
> + if (IS_ERR(attach))
> + return ERR_CAST(attach);
> +
> + get_dma_buf(dma_buf);
> +
> + size = PAGE_ALIGN(attach->dmabuf->size);
> +
> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
> + if (IS_ERR(shmem)) {
> + ret = PTR_ERR(shmem);
> + goto fail_detach;
> + }
> +
> + drm_dbg_prime(dev, "size = %zu\n", size);
> +
> + shmem->base.import_attach = attach;
> + shmem->base.resv = dma_buf->resv;
> +
> + return &shmem->base;
> +
> +fail_detach:
> + dma_buf_detach(dma_buf, attach);
> + dma_buf_put(dma_buf);
> +
> + return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
> +
> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
> MODULE_IMPORT_NS("DMA_BUF");
> MODULE_LICENSE("GPL v2");
> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> index d828502268b8..b825b71038d6 100644
> --- a/drivers/gpu/drm/drm_prime.c
> +++ b/drivers/gpu/drm/drm_prime.c
> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
> }
> EXPORT_SYMBOL(drm_gem_prime_export);
>
> +
> +/**
> + * drm_gem_is_prime_exported_dma_buf -
> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
> + * @dev: drm_device to check against
> + * @dma_buf: dma-buf object to import
> + *
> + * Return: true if the DMA-BUF was exported from a GEM object belonging
> + * to @dev, false otherwise.
> + */
> +
> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
> + struct dma_buf *dma_buf)
> +{
> + struct drm_gem_object *obj = dma_buf->priv;
> +
> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
> +}
> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
> +
> /**
> * drm_gem_prime_import_dev - core implementation of the import callback
> * @dev: drm_device to import into
> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
> struct drm_gem_object *obj;
> int ret;
>
> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
> + /*
> + * Importing dmabuf exported from our own gem increases
> + * refcount on gem itself instead of f_count of dmabuf.
> + */
> obj = dma_buf->priv;
> - if (obj->dev == dev) {
> - /*
> - * Importing dmabuf exported from our own gem increases
> - * refcount on gem itself instead of f_count of dmabuf.
> - */
> - drm_gem_object_get(obj);
> - return obj;
> - }
> + drm_gem_object_get(obj);
> + return obj;
> }
>
> if (!dev->driver->gem_prime_import_sg_table)
> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
> index b4f993da3cae..35f7466dca84 100644
> --- a/include/drm/drm_gem_shmem_helper.h
> +++ b/include/drm/drm_gem_shmem_helper.h
> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
> struct sg_table *sgt);
> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
> struct drm_mode_create_dumb *args);
> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
> + struct dma_buf *buf);
>
> /**
> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
> .dumb_create = drm_gem_shmem_dumb_create
>
> +/**
> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
> + * without mapping sg_table on
> + * imported buffer.
> + *
> + * This macro provides a shortcut for setting the shmem GEM operations in
> + * the &drm_driver structure for drivers that do not require a sg_table on
> + * imported buffers.
> + */
> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
> + .dumb_create = drm_gem_shmem_dumb_create
> +
> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
> index fa085c44d4ca..f50f862f0d8b 100644
> --- a/include/drm/drm_prime.h
> +++ b/include/drm/drm_prime.h
> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>
> /* helper functions for importing */
> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
> + struct dma_buf *dma_buf);
> +
> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
> struct dma_buf *dma_buf,
> struct device *attach_dev);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-05-26 15:00 ` [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table Thomas Zimmermann
@ 2025-06-03 7:49 ` Thomas Zimmermann
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Zimmermann @ 2025-06-03 7:49 UTC (permalink / raw)
To: oushixiong1025, Christian König
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi
Am 26.05.25 um 17:00 schrieb Thomas Zimmermann:
> Hi
>
> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>
>> [WHY]
>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>> sg_table import.
>> They only need dma_buf_vmap() to access the shared buffer's
>> kernel virtual address.
>>
>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>> restricts the maximum DMA streaming mapping memory, resulting in
>> errors like:
>>
>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes),
>> total 32768 (slots), used 0 (slots)
>>
>> [HOW]
>> Provide a gem_prime_import implementation without sg_table mapping
>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>> require sg_table can adopt this.
>>
>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>
> Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
>
> Looks good to me, but Christian might want to take a look as well.
> Thanks for addressing the issue.
Christian told me that he's fine with the changes. I've merged the
series into drm-misc-next. Thanks a lot for fixing the issue.
Best regards
Thomas
>
> Best regards
> Thomas
>
>> ---
>> v1->v2:
>> Patch rebase.
>> v2->v3:
>> Rename the import callback function.
>> Remove drm_gem_shmem_prime_export() and separate some codes
>> to drm_gem_prime_import_self().
>> v3->v4:
>> Separate the test from the policy.
>> Rename the macro.
>> v4->v5:
>> Rename some functions.
>>
>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>> include/drm/drm_prime.h | 3 ++
>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c
>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> index aa43265f4f4f..126aa79042ad 100644
>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct
>> drm_device *dev,
>> }
>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>> +/**
>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping
>> its sg_table
>> + * @dev: Device to import into
>> + * @dma_buf: dma-buf object to import
>> + *
>> + * Drivers that use the shmem helpers but also wants to import
>> dmabuf without
>> + * mapping its sg_table can use this as their
>> &drm_driver.gem_prime_import
>> + * implementation.
>> + */
>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>> drm_device *dev,
>> + struct dma_buf *dma_buf)
>> +{
>> + struct dma_buf_attachment *attach;
>> + struct drm_gem_shmem_object *shmem;
>> + struct drm_gem_object *obj;
>> + size_t size;
>> + int ret;
>> +
>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>> + /*
>> + * Importing dmabuf exported from our own gem increases
>> + * refcount on gem itself instead of f_count of dmabuf.
>> + */
>> + obj = dma_buf->priv;
>> + drm_gem_object_get(obj);
>> + return obj;
>> + }
>> +
>> + attach = dma_buf_attach(dma_buf, dev->dev);
>> + if (IS_ERR(attach))
>> + return ERR_CAST(attach);
>> +
>> + get_dma_buf(dma_buf);
>> +
>> + size = PAGE_ALIGN(attach->dmabuf->size);
>> +
>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>> + if (IS_ERR(shmem)) {
>> + ret = PTR_ERR(shmem);
>> + goto fail_detach;
>> + }
>> +
>> + drm_dbg_prime(dev, "size = %zu\n", size);
>> +
>> + shmem->base.import_attach = attach;
>> + shmem->base.resv = dma_buf->resv;
>> +
>> + return &shmem->base;
>> +
>> +fail_detach:
>> + dma_buf_detach(dma_buf, attach);
>> + dma_buf_put(dma_buf);
>> +
>> + return ERR_PTR(ret);
>> +}
>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>> +
>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>> MODULE_IMPORT_NS("DMA_BUF");
>> MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>> index d828502268b8..b825b71038d6 100644
>> --- a/drivers/gpu/drm/drm_prime.c
>> +++ b/drivers/gpu/drm/drm_prime.c
>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct
>> drm_gem_object *obj,
>> }
>> EXPORT_SYMBOL(drm_gem_prime_export);
>> +
>> +/**
>> + * drm_gem_is_prime_exported_dma_buf -
>> + * checks if the DMA-BUF was exported from a GEM object belonging to
>> @dev.
>> + * @dev: drm_device to check against
>> + * @dma_buf: dma-buf object to import
>> + *
>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>> + * to @dev, false otherwise.
>> + */
>> +
>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>> + struct dma_buf *dma_buf)
>> +{
>> + struct drm_gem_object *obj = dma_buf->priv;
>> +
>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev
>> == dev);
>> +}
>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>> +
>> /**
>> * drm_gem_prime_import_dev - core implementation of the import
>> callback
>> * @dev: drm_device to import into
>> @@ -933,16 +953,14 @@ struct drm_gem_object
>> *drm_gem_prime_import_dev(struct drm_device *dev,
>> struct drm_gem_object *obj;
>> int ret;
>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>> + /*
>> + * Importing dmabuf exported from our own gem increases
>> + * refcount on gem itself instead of f_count of dmabuf.
>> + */
>> obj = dma_buf->priv;
>> - if (obj->dev == dev) {
>> - /*
>> - * Importing dmabuf exported from our own gem increases
>> - * refcount on gem itself instead of f_count of dmabuf.
>> - */
>> - drm_gem_object_get(obj);
>> - return obj;
>> - }
>> + drm_gem_object_get(obj);
>> + return obj;
>> }
>> if (!dev->driver->gem_prime_import_sg_table)
>> diff --git a/include/drm/drm_gem_shmem_helper.h
>> b/include/drm/drm_gem_shmem_helper.h
>> index b4f993da3cae..35f7466dca84 100644
>> --- a/include/drm/drm_gem_shmem_helper.h
>> +++ b/include/drm/drm_gem_shmem_helper.h
>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct
>> drm_device *dev,
>> struct sg_table *sgt);
>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct
>> drm_device *dev,
>> struct drm_mode_create_dumb *args);
>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>> drm_device *dev,
>> + struct dma_buf *buf);
>> /**
>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file
>> *file, struct drm_device *dev,
>> .gem_prime_import_sg_table =
>> drm_gem_shmem_prime_import_sg_table, \
>> .dumb_create = drm_gem_shmem_dumb_create
>> +/**
>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>> + * without mapping sg_table on
>> + * imported buffer.
>> + *
>> + * This macro provides a shortcut for setting the shmem GEM
>> operations in
>> + * the &drm_driver structure for drivers that do not require a
>> sg_table on
>> + * imported buffers.
>> + */
>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>> + .dumb_create = drm_gem_shmem_dumb_create
>> +
>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>> index fa085c44d4ca..f50f862f0d8b 100644
>> --- a/include/drm/drm_prime.h
>> +++ b/include/drm/drm_prime.h
>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct
>> drm_gem_object *obj,
>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>> /* helper functions for importing */
>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>> + struct dma_buf *dma_buf);
>> +
>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device
>> *dev,
>> struct dma_buf *dma_buf,
>> struct device *attach_dev);
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-05-22 7:07 [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table oushixiong1025
` (2 preceding siblings ...)
2025-05-26 15:00 ` [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table Thomas Zimmermann
@ 2025-07-11 14:16 ` Thomas Zimmermann
[not found] ` <7d974eaa-d8a4-4430-a999-7b06c4e17a81@163.com>
3 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-07-11 14:16 UTC (permalink / raw)
To: oushixiong1025, Christian König
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi
this patch regresses buffer sharing between udl and amdgpu. The latter
uses TTM. When udl imports a dma_buf from amdgpu, vmap returns a kernel
address, but pagefaults on the buffer cannot be handled. A full error
message is attached. It fails right at [1], where udl read the first
pixel from the buffer. That pixel address is the vmap'ed buffer.
[1]
https://elixir.bootlin.com/linux/v6.15.5/source/drivers/gpu/drm/udl/udl_transfer.c#L109
Buffer sharing works with SHMEM-based drivers, which have their buffers
in system memory though. I assume that amdgpu's buffer is located in I/O
memory or scanout.
Best regards
Thomas
[ 168.785445] BUG: unable to handle page fault for address:
ffffc9012b800000
[ 168.792311] #PF: supervisor read access in kernel mode
[ 168.797452] #PF: error_code(0x0000) - not-present page
[ 168.802586] PGD 100000067 P4D 100000067 PUD 0
[ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
[ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted:
G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
[ 168.823537] Tainted: [E]=UNSIGNED_MODULE
[ 168.827458] Hardware name: System manufacturer System Product
Name/Z170-A, BIOS 3802 03/15/2018
[ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
[ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83
f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00
00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
c1
[ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
[ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
0000000000000002
[ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
0000000000000100
[ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
ffff8881082e0000
[ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12:
ffff88811c7e76f8
[ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
0000000000000000
[ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000)
knlGS:0000000000000000
[ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
00000000003706f0
[ 168.922170] Call Trace:
[ 168.924616] <TASK>
[ 168.926714] ? validate_chain+0x24e/0x5e0
[ 168.930718] ? __lock_acquire+0x568/0xae0
[ 168.934725] udl_render_hline+0x165/0x33b [udl]
[ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
[ 168.944297] ? local_clock_noinstr+0xb/0x100
[ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
[ 168.953162] ? mark_held_locks+0x40/0x70
[ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
[ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
[ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10
[udl]
[ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
[ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
[ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
[ 169.002943] commit_tail+0x204/0x330
[ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
[ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
[ 169.016413] drm_atomic_commit+0x1e1/0x290
[ 169.020500] ? prepare_signaling+0x355/0xda0
[ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
[ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
[ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
[ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
[ 169.043466] ? find_held_lock+0x2b/0x80
[ 169.047295] ? __lock_acquire+0x568/0xae0
[ 169.051293] ? mark_usage+0x65/0x180
[ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
[ 169.059823] ? do_raw_spin_unlock+0x55/0x230
[ 169.064081] ? drm_is_current_master+0x26/0x30
[ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
[ 169.073465] drm_ioctl_kernel+0x141/0x2b0
[ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
[ 169.081987] ? lock_release.part.0+0x47/0x90
[ 169.086249] drm_ioctl+0x481/0xb50
[ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
[ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
[ 169.098525] ? find_held_lock+0x2b/0x80
[ 169.102356] ? lock_release.part.0+0x47/0x90
[ 169.106621] ? __fget_files+0x1aa/0x2f0
[ 169.110450] ? __fget_files+0x1b4/0x2f0
[ 169.114281] __x64_sys_ioctl+0x135/0x1c0
[ 169.118201] do_syscall_64+0x68/0x2a0
[ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 169.126892] RIP: 0033:0x7f469391a53f
[ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10
00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f
05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
00
[ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX:
0000000000000010
[ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX:
00007f469391a53f
[ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI:
0000000000000010
[ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09:
00007f465c044cf0
[ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12:
00000000c03864bc
[ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15:
00007f45d402b110
[ 169.192525] </TASK>
[ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E)
snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E)
binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
_cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E)
iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E)
x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E)
e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E)
snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E)
xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E)
soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E)
ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E)
drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
[ 169.194874] gpu_sched(E) drm_suballoc_helper(E)
ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E)
aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E)
drm_display_helper(E) cec(E) w
mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E)
efivarfs(E) dmi_sysfs(E)
[ 169.311501] CR2: ffffc9012b800000
[ 169.314835] ---[ end trace 0000000000000000 ]---
[ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
[ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83
f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00
00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
c1
[ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
[ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
0000000000000002
[ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
0000000000000100
[ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
ffff8881082e0000
[ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12:
ffff88811c7e76f8
[ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
0000000000000000
[ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000)
knlGS:0000000000000000
[ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
00000000003706f0
[ 169.521180] note: KMS thread[2380] exited with irqs disabled
[ 175.343111]
==================================================================
[ 175.350342] BUG: KASAN: slab-use-after-free in
mutex_can_spin_on_owner+0x1a6/0x1c0
[ 175.357886] Read of size 4 at addr ffff8881172daff4 by task
kworker/5:0/49
[ 175.364738]
[ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G
D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
[ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
[ 175.366242] Hardware name: System manufacturer System Product
Name/Z170-A, BIOS 3802 03/15/2018
[ 175.366244] Workqueue: events output_poll_execute
[ 175.366249] Call Trace:
[ 175.366251] <TASK>
[ 175.366254] dump_stack_lvl+0x68/0x90
[ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
[ 175.366261] print_address_description.constprop.0+0x88/0x380
[ 175.366266] ? lock_acquire+0xf2/0x140
[ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
[ 175.366272] print_report+0xf8/0x1e2
[ 175.366275] ? __virt_addr_valid+0x22e/0x500
[ 175.366279] ? kasan_addr_to_slab+0x9/0x90
[ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
[ 175.366284] kasan_report+0xd8/0x190
[ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
[ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
[ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
[ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
[ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
[ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
[ 175.366311] ? modeset_lock+0x3c6/0x640
[ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
[ 175.366320] ? rcu_is_watching+0x11/0xb0
[ 175.366323] ? timerqueue_add+0x154/0x3c0
[ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
[ 175.366331] ? rcu_is_watching+0x11/0xb0
[ 175.366334] ? lock_acquired+0xb6/0xf0
[ 175.366337] ? rcu_is_watching+0x11/0xb0
[ 175.366340] ? rcu_is_watching+0x11/0xb0
[ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
[ 175.366345] ? lock_acquire+0xf2/0x140
[ 175.366349] ? ww_mutex_lock+0x27/0x150
[ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
[ 175.366355] ww_mutex_lock+0x27/0x150
[ 175.366358] modeset_lock+0x3c6/0x640
[ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
[ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
[ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
[ 175.366381] output_poll_execute+0x29b/0x760
[ 175.366387] ? trace_hardirqs_on+0x14/0x150
[ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
[ 175.366396] process_one_work+0x7b5/0x1390
[ 175.366404] ? __pfx_process_one_work+0x10/0x10
[ 175.366409] ? assign_work+0x156/0x390
[ 175.366413] worker_thread+0x58d/0xf60
[ 175.366420] ? __pfx_worker_thread+0x10/0x10
[ 175.366422] kthread+0x370/0x720
[ 175.366425] ? __pfx_kthread+0x10/0x10
[ 175.366428] ? local_clock_noinstr+0x56/0x100
[ 175.366431] ? local_clock+0x11/0x30
[ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
[ 175.366437] ? rcu_is_watching+0x11/0xb0
[ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
[ 175.366442] ? __pfx_kthread+0x10/0x10
[ 175.366445] ret_from_fork+0x1f4/0x2f0
[ 175.366448] ? __pfx_kthread+0x10/0x10
[ 175.366450] ret_from_fork_asm+0x1a/0x30
[ 175.366459] </TASK>
[ 175.366460]
[ 175.632772] Allocated by task 2342:
[ 175.636282] kasan_save_stack+0x1c/0x40
[ 175.640137] kasan_save_track+0x10/0x30
[ 175.643992] __kasan_slab_alloc+0x5f/0x70
[ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
[ 175.653097] dup_task_struct+0x32/0x730
[ 175.656952] copy_process+0x2d8/0x5380
[ 175.660720] kernel_clone+0x9f/0x5e0
[ 175.664318] __do_sys_clone3+0x135/0x180
[ 175.668258] do_syscall_64+0x68/0x2a0
[ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 175.677014]
[ 175.678520] Freed by task 0:
[ 175.681418] kasan_save_stack+0x1c/0x40
[ 175.685273] kasan_save_track+0x10/0x30
[ 175.689130] kasan_save_free_info+0x37/0x70
[ 175.693333] __kasan_slab_free+0x33/0x40
[ 175.697278] kmem_cache_free+0x10b/0x4d0
[ 175.701221] delayed_put_task_struct+0x15e/0x1e0
[ 175.705858] rcu_do_batch+0x2e3/0xb30
[ 175.709542] rcu_core+0x51d/0xb60
[ 175.712873] handle_softirqs+0x1a2/0x6b0
[ 175.716817] __irq_exit_rcu+0xf7/0x160
[ 175.720585] irq_exit_rcu+0xa/0x30
[ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
[ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
[ 175.733980]
[ 175.735486] Last potentially related work creation:
[ 175.740385] kasan_save_stack+0x1c/0x40
[ 175.744243] kasan_record_aux_stack+0x88/0xa0
[ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
[ 175.753693] __schedule+0x887/0x1d00
[ 175.757287] schedule+0xd0/0x260
[ 175.760533] smpboot_thread_fn+0x583/0x7a0
[ 175.764650] kthread+0x370/0x720
[ 175.767896] ret_from_fork+0x1f4/0x2f0
[ 175.771665] ret_from_fork_asm+0x1a/0x30
[ 175.775608]
[ 175.777113] Second to last potentially related work creation:
[ 175.782886] kasan_save_stack+0x1c/0x40
[ 175.786739] kasan_record_aux_stack+0x88/0xa0
[ 175.791118] task_work_add+0x1b1/0x270
[ 175.794886] sched_tick+0x226/0x6f0
[ 175.798394] update_process_times+0xe9/0x1f0
[ 175.802685] tick_nohz_handler+0x1a6/0x4b0
[ 175.806801] __hrtimer_run_queues+0x161/0x960
[ 175.811181] hrtimer_interrupt+0x33e/0x880
[ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
[ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
[ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
[ 175.830343]
[ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
[ 175.831849] which belongs to the cache task_struct of size 11968
[ 175.844582] The buggy address is located 52 bytes inside of
[ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
[ 175.856969]
[ 175.858474] The buggy address belongs to the physical page:
[ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000
index:0x0 pfn:0x1172d8
[ 175.872104] head: order:3 mapcount:0 entire_mapcount:0
nr_pages_mapped:0 pincount:0
[ 175.879788] memcg:ffff88811068a301
[ 175.883209] anon flags:
0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
[ 175.890547] page_type: f5(slab)
[ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000
0000000000000001
[ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000
ffff88811068a301
[ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000
0000000000000001
[ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000
ffff88811068a301
[ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff
00000000ffffffff
[ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff
0000000000000008
[ 175.940685] page dumped because: kasan: bad access detected
[ 175.946283]
[ 175.947787] Memory state around the buggy address:
[ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc
fc fc fc
[ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc
[ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb
fb fb fb
[ 175.974353] ^
[ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb
[ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb
[ 175.995755]
==================================================================
Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
> From: Shixiong Ou <oushixiong@kylinos.cn>
>
> [WHY]
> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
> sg_table import.
> They only need dma_buf_vmap() to access the shared buffer's
> kernel virtual address.
>
> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
> restricts the maximum DMA streaming mapping memory, resulting in
> errors like:
>
> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>
> [HOW]
> Provide a gem_prime_import implementation without sg_table mapping
> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
> require sg_table can adopt this.
>
> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
> ---
> v1->v2:
> Patch rebase.
> v2->v3:
> Rename the import callback function.
> Remove drm_gem_shmem_prime_export() and separate some codes
> to drm_gem_prime_import_self().
> v3->v4:
> Separate the test from the policy.
> Rename the macro.
> v4->v5:
> Rename some functions.
>
> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
> include/drm/drm_gem_shmem_helper.h | 15 +++++++
> include/drm/drm_prime.h | 3 ++
> 4 files changed, 102 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index aa43265f4f4f..126aa79042ad 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
> }
> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>
> +/**
> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
> + * @dev: Device to import into
> + * @dma_buf: dma-buf object to import
> + *
> + * Drivers that use the shmem helpers but also wants to import dmabuf without
> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
> + * implementation.
> + */
> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
> + struct dma_buf *dma_buf)
> +{
> + struct dma_buf_attachment *attach;
> + struct drm_gem_shmem_object *shmem;
> + struct drm_gem_object *obj;
> + size_t size;
> + int ret;
> +
> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
> + /*
> + * Importing dmabuf exported from our own gem increases
> + * refcount on gem itself instead of f_count of dmabuf.
> + */
> + obj = dma_buf->priv;
> + drm_gem_object_get(obj);
> + return obj;
> + }
> +
> + attach = dma_buf_attach(dma_buf, dev->dev);
> + if (IS_ERR(attach))
> + return ERR_CAST(attach);
> +
> + get_dma_buf(dma_buf);
> +
> + size = PAGE_ALIGN(attach->dmabuf->size);
> +
> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
> + if (IS_ERR(shmem)) {
> + ret = PTR_ERR(shmem);
> + goto fail_detach;
> + }
> +
> + drm_dbg_prime(dev, "size = %zu\n", size);
> +
> + shmem->base.import_attach = attach;
> + shmem->base.resv = dma_buf->resv;
> +
> + return &shmem->base;
> +
> +fail_detach:
> + dma_buf_detach(dma_buf, attach);
> + dma_buf_put(dma_buf);
> +
> + return ERR_PTR(ret);
> +}
> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
> +
> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
> MODULE_IMPORT_NS("DMA_BUF");
> MODULE_LICENSE("GPL v2");
> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> index d828502268b8..b825b71038d6 100644
> --- a/drivers/gpu/drm/drm_prime.c
> +++ b/drivers/gpu/drm/drm_prime.c
> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
> }
> EXPORT_SYMBOL(drm_gem_prime_export);
>
> +
> +/**
> + * drm_gem_is_prime_exported_dma_buf -
> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
> + * @dev: drm_device to check against
> + * @dma_buf: dma-buf object to import
> + *
> + * Return: true if the DMA-BUF was exported from a GEM object belonging
> + * to @dev, false otherwise.
> + */
> +
> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
> + struct dma_buf *dma_buf)
> +{
> + struct drm_gem_object *obj = dma_buf->priv;
> +
> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
> +}
> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
> +
> /**
> * drm_gem_prime_import_dev - core implementation of the import callback
> * @dev: drm_device to import into
> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
> struct drm_gem_object *obj;
> int ret;
>
> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
> + /*
> + * Importing dmabuf exported from our own gem increases
> + * refcount on gem itself instead of f_count of dmabuf.
> + */
> obj = dma_buf->priv;
> - if (obj->dev == dev) {
> - /*
> - * Importing dmabuf exported from our own gem increases
> - * refcount on gem itself instead of f_count of dmabuf.
> - */
> - drm_gem_object_get(obj);
> - return obj;
> - }
> + drm_gem_object_get(obj);
> + return obj;
> }
>
> if (!dev->driver->gem_prime_import_sg_table)
> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
> index b4f993da3cae..35f7466dca84 100644
> --- a/include/drm/drm_gem_shmem_helper.h
> +++ b/include/drm/drm_gem_shmem_helper.h
> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
> struct sg_table *sgt);
> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
> struct drm_mode_create_dumb *args);
> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
> + struct dma_buf *buf);
>
> /**
> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
> .dumb_create = drm_gem_shmem_dumb_create
>
> +/**
> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
> + * without mapping sg_table on
> + * imported buffer.
> + *
> + * This macro provides a shortcut for setting the shmem GEM operations in
> + * the &drm_driver structure for drivers that do not require a sg_table on
> + * imported buffers.
> + */
> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
> + .dumb_create = drm_gem_shmem_dumb_create
> +
> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
> index fa085c44d4ca..f50f862f0d8b 100644
> --- a/include/drm/drm_prime.h
> +++ b/include/drm/drm_prime.h
> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>
> /* helper functions for importing */
> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
> + struct dma_buf *dma_buf);
> +
> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
> struct dma_buf *dma_buf,
> struct device *attach_dev);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
[not found] ` <7d974eaa-d8a4-4430-a999-7b06c4e17a81@163.com>
@ 2025-07-14 10:47 ` Thomas Zimmermann
2025-08-13 9:25 ` Thomas Zimmermann
1 sibling, 0 replies; 22+ messages in thread
From: Thomas Zimmermann @ 2025-07-14 10:47 UTC (permalink / raw)
To: Shixiong Ou, Christian König
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou,
Alexander Deucher, amd-gfx@lists.freedesktop.org
(cc:ing more AMD devs)
Hi
Am 14.07.25 um 12:16 schrieb Shixiong Ou:
>
>
> 在 2025/7/11 22:16, Thomas Zimmermann 写道:
>> Hi
>>
>> this patch regresses buffer sharing between udl and amdgpu. The
>> latter uses TTM. When udl imports a dma_buf from amdgpu, vmap returns
>> a kernel address, but pagefaults on the buffer cannot be handled. A
>> full error message is attached. It fails right at [1], where udl read
>> the first pixel from the buffer. That pixel address is the vmap'ed
>> buffer.
>>
>> [1]
>> https://elixir.bootlin.com/linux/v6.15.5/source/drivers/gpu/drm/udl/udl_transfer.c#L109
>>
>> Buffer sharing works with SHMEM-based drivers, which have their
>> buffers in system memory though. I assume that amdgpu's buffer is
>> located in I/O memory or scanout.
>>
>> Best regards
>> Thomas
>>
>
> Hi,
> I haven't been able to reproduce this issue yet.
> Did the driver not pin the buffer into GTT?
>
Could be. The setup is fairly simple. There's a discrete AMD GPU used
for booting up. Login happens via gdm. I attach the USB device before
logging into the test system. Gnome sets up the system such that udl
imports the buffer from amdgpu. The error happens on the first display
update. The vmap itself works; it's just that there's no memory behind
the buffer.
Amdgpu uses ttm_bo_vmap(), [1] which doesn't do any pinning. The pinning
appears to be happening in amd_display_crtc_page_flip_target(), [2]
which might be too late.
[1]
https://elixir.bootlin.com/linux/v6.16-rc5/source/drivers/gpu/drm/ttm/ttm_bo_util.c#L470
[2]
https://elixir.bootlin.com/linux/v6.16-rc5/source/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c#L238
Best regards
Thomas
>
> Best regards,
> Shixiong
>
>
>>
>> [ 168.785445] BUG: unable to handle page fault for address:
>> ffffc9012b800000
>> [ 168.792311] #PF: supervisor read access in kernel mode
>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted:
>> G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>> [ 168.827458] Hardware name: System manufacturer System Product
>> Name/Z170-A, BIOS 3802 03/15/2018
>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd
>> 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82
>> 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1
>> e8 08
>> c1
>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
>> 0000000000000002
>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
>> 0000000000000100
>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
>> ffff8881082e0000
>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12:
>> ffff88811c7e76f8
>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
>> 0000000000000000
>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000)
>> knlGS:0000000000000000
>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
>> 00000000003706f0
>> [ 168.922170] Call Trace:
>> [ 168.924616] <TASK>
>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>> [ 168.953162] ? mark_held_locks+0x40/0x70
>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>> [ 168.969145] ?
>> __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>> [ 168.980357] ?
>> drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>> [ 169.002943] commit_tail+0x204/0x330
>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.043466] ? find_held_lock+0x2b/0x80
>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>> [ 169.051293] ? mark_usage+0x65/0x180
>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>> [ 169.086249] drm_ioctl+0x481/0xb50
>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>> [ 169.098525] ? find_held_lock+0x2b/0x80
>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>> [ 169.118201] do_syscall_64+0x68/0x2a0
>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>> [ 169.126892] RIP: 0033:0x7f469391a53f
>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24
>> 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00
>> 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25
>> 28 00
>> 00
>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX:
>> 0000000000000010
>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX:
>> 00007f469391a53f
>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI:
>> 0000000000000010
>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09:
>> 00007f465c044cf0
>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12:
>> 00000000c03864bc
>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15:
>> 00007f45d402b110
>> [ 169.192525] </TASK>
>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E)
>> snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E)
>> iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E)
>> eeepc_wmi(E) nls
>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E)
>> iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E)
>> sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E)
>> snd_hda_scodec_component(
>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E)
>> fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E)
>> i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E)
>> intel_wmi_thunder
>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E)
>> xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E)
>> soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E)
>> nvme_fabrics(
>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E)
>> ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E)
>> drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E)
>> ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E)
>> aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E)
>> drm_display_helper(E) cec(E) w
>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E)
>> i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>> [ 169.311501] CR2: ffffc9012b800000
>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd
>> 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82
>> 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1
>> e8 08
>> c1
>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
>> 0000000000000002
>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
>> 0000000000000100
>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
>> ffff8881082e0000
>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12:
>> ffff88811c7e76f8
>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
>> 0000000000000000
>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000)
>> knlGS:0000000000000000
>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
>> 00000000003706f0
>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>> [ 175.343111]
>> ==================================================================
>> [ 175.350342] BUG: KASAN: slab-use-after-free in
>> mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task
>> kworker/5:0/49
>> [ 175.364738]
>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted:
>> G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>> [ 175.366242] Hardware name: System manufacturer System Product
>> Name/Z170-A, BIOS 3802 03/15/2018
>> [ 175.366244] Workqueue: events output_poll_execute
>> [ 175.366249] Call Trace:
>> [ 175.366251] <TASK>
>> [ 175.366254] dump_stack_lvl+0x68/0x90
>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>> [ 175.366266] ? lock_acquire+0xf2/0x140
>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366272] print_report+0xf8/0x1e2
>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366284] kasan_report+0xd8/0x190
>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>> [ 175.366345] ? lock_acquire+0xf2/0x140
>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>> [ 175.366355] ww_mutex_lock+0x27/0x150
>> [ 175.366358] modeset_lock+0x3c6/0x640
>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>> [ 175.366381] output_poll_execute+0x29b/0x760
>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>> [ 175.366396] process_one_work+0x7b5/0x1390
>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>> [ 175.366409] ? assign_work+0x156/0x390
>> [ 175.366413] worker_thread+0x58d/0xf60
>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>> [ 175.366422] kthread+0x370/0x720
>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>> [ 175.366431] ? local_clock+0x11/0x30
>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>> [ 175.366459] </TASK>
>> [ 175.366460]
>> [ 175.632772] Allocated by task 2342:
>> [ 175.636282] kasan_save_stack+0x1c/0x40
>> [ 175.640137] kasan_save_track+0x10/0x30
>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>> [ 175.653097] dup_task_struct+0x32/0x730
>> [ 175.656952] copy_process+0x2d8/0x5380
>> [ 175.660720] kernel_clone+0x9f/0x5e0
>> [ 175.664318] __do_sys_clone3+0x135/0x180
>> [ 175.668258] do_syscall_64+0x68/0x2a0
>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>> [ 175.677014]
>> [ 175.678520] Freed by task 0:
>> [ 175.681418] kasan_save_stack+0x1c/0x40
>> [ 175.685273] kasan_save_track+0x10/0x30
>> [ 175.689130] kasan_save_free_info+0x37/0x70
>> [ 175.693333] __kasan_slab_free+0x33/0x40
>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>> [ 175.709542] rcu_core+0x51d/0xb60
>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>> [ 175.720585] irq_exit_rcu+0xa/0x30
>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>> [ 175.733980]
>> [ 175.735486] Last potentially related work creation:
>> [ 175.740385] kasan_save_stack+0x1c/0x40
>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>> [ 175.753693] __schedule+0x887/0x1d00
>> [ 175.757287] schedule+0xd0/0x260
>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>> [ 175.764650] kthread+0x370/0x720
>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>> [ 175.775608]
>> [ 175.777113] Second to last potentially related work creation:
>> [ 175.782886] kasan_save_stack+0x1c/0x40
>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>> [ 175.791118] task_work_add+0x1b1/0x270
>> [ 175.794886] sched_tick+0x226/0x6f0
>> [ 175.798394] update_process_times+0xe9/0x1f0
>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>> [ 175.830343]
>> [ 175.831849] The buggy address belongs to the object at
>> ffff8881172dafc0
>> [ 175.831849] which belongs to the cache task_struct of size 11968
>> [ 175.844582] The buggy address is located 52 bytes inside of
>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0,
>> ffff8881172dde80)
>> [ 175.856969]
>> [ 175.858474] The buggy address belongs to the physical page:
>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000
>> index:0x0 pfn:0x1172d8
>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0
>> nr_pages_mapped:0 pincount:0
>> [ 175.879788] memcg:ffff88811068a301
>> [ 175.883209] anon flags:
>> 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>> [ 175.890547] page_type: f5(slab)
>> [ 175.893706] raw: 002ffff800000040 ffff888100930500
>> 0000000000000000 0000000000000001
>> [ 175.901479] raw: 0000000000000000 0000000000020002
>> 00000000f5000000 ffff88811068a301
>> [ 175.909249] head: 002ffff800000040 ffff888100930500
>> 0000000000000000 0000000000000001
>> [ 175.917109] head: 0000000000000000 0000000000020002
>> 00000000f5000000 ffff88811068a301
>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601
>> 00000000ffffffff 00000000ffffffff
>> [ 175.932827] head: ffffffffffffffff 0000000000000000
>> 00000000ffffffff 0000000000000008
>> [ 175.940685] page dumped because: kasan: bad access detected
>> [ 175.946283]
>> [ 175.947787] Memory state around the buggy address:
>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc
>> fc fc fc fc
>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc
>> fc fc fc fc
>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb
>> fb fb fb fb
>> [ 175.974353] ^
>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb
>> fb fb fb fb
>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb
>> fb fb fb fb
>> [ 175.995755]
>> ==================================================================
>>
>>
>>
>>
>>
>>
>>
>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>
>>> [WHY]
>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>> sg_table import.
>>> They only need dma_buf_vmap() to access the shared buffer's
>>> kernel virtual address.
>>>
>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>> restricts the maximum DMA streaming mapping memory, resulting in
>>> errors like:
>>>
>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes),
>>> total 32768 (slots), used 0 (slots)
>>>
>>> [HOW]
>>> Provide a gem_prime_import implementation without sg_table mapping
>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>> require sg_table can adopt this.
>>>
>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>> ---
>>> v1->v2:
>>> Patch rebase.
>>> v2->v3:
>>> Rename the import callback function.
>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>> to drm_gem_prime_import_self().
>>> v3->v4:
>>> Separate the test from the policy.
>>> Rename the macro.
>>> v4->v5:
>>> Rename some functions.
>>>
>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57
>>> ++++++++++++++++++++++++++
>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>> include/drm/drm_prime.h | 3 ++
>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> index aa43265f4f4f..126aa79042ad 100644
>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct
>>> drm_device *dev,
>>> }
>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>> +/**
>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without
>>> mapping its sg_table
>>> + * @dev: Device to import into
>>> + * @dma_buf: dma-buf object to import
>>> + *
>>> + * Drivers that use the shmem helpers but also wants to import
>>> dmabuf without
>>> + * mapping its sg_table can use this as their
>>> &drm_driver.gem_prime_import
>>> + * implementation.
>>> + */
>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>>> drm_device *dev,
>>> + struct dma_buf *dma_buf)
>>> +{
>>> + struct dma_buf_attachment *attach;
>>> + struct drm_gem_shmem_object *shmem;
>>> + struct drm_gem_object *obj;
>>> + size_t size;
>>> + int ret;
>>> +
>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>> + /*
>>> + * Importing dmabuf exported from our own gem increases
>>> + * refcount on gem itself instead of f_count of dmabuf.
>>> + */
>>> + obj = dma_buf->priv;
>>> + drm_gem_object_get(obj);
>>> + return obj;
>>> + }
>>> +
>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>> + if (IS_ERR(attach))
>>> + return ERR_CAST(attach);
>>> +
>>> + get_dma_buf(dma_buf);
>>> +
>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>> +
>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>> + if (IS_ERR(shmem)) {
>>> + ret = PTR_ERR(shmem);
>>> + goto fail_detach;
>>> + }
>>> +
>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>> +
>>> + shmem->base.import_attach = attach;
>>> + shmem->base.resv = dma_buf->resv;
>>> +
>>> + return &shmem->base;
>>> +
>>> +fail_detach:
>>> + dma_buf_detach(dma_buf, attach);
>>> + dma_buf_put(dma_buf);
>>> +
>>> + return ERR_PTR(ret);
>>> +}
>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>> +
>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>> MODULE_IMPORT_NS("DMA_BUF");
>>> MODULE_LICENSE("GPL v2");
>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>> index d828502268b8..b825b71038d6 100644
>>> --- a/drivers/gpu/drm/drm_prime.c
>>> +++ b/drivers/gpu/drm/drm_prime.c
>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct
>>> drm_gem_object *obj,
>>> }
>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>> +
>>> +/**
>>> + * drm_gem_is_prime_exported_dma_buf -
>>> + * checks if the DMA-BUF was exported from a GEM object belonging
>>> to @dev.
>>> + * @dev: drm_device to check against
>>> + * @dma_buf: dma-buf object to import
>>> + *
>>> + * Return: true if the DMA-BUF was exported from a GEM object
>>> belonging
>>> + * to @dev, false otherwise.
>>> + */
>>> +
>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>> + struct dma_buf *dma_buf)
>>> +{
>>> + struct drm_gem_object *obj = dma_buf->priv;
>>> +
>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev
>>> == dev);
>>> +}
>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>> +
>>> /**
>>> * drm_gem_prime_import_dev - core implementation of the import
>>> callback
>>> * @dev: drm_device to import into
>>> @@ -933,16 +953,14 @@ struct drm_gem_object
>>> *drm_gem_prime_import_dev(struct drm_device *dev,
>>> struct drm_gem_object *obj;
>>> int ret;
>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>> + /*
>>> + * Importing dmabuf exported from our own gem increases
>>> + * refcount on gem itself instead of f_count of dmabuf.
>>> + */
>>> obj = dma_buf->priv;
>>> - if (obj->dev == dev) {
>>> - /*
>>> - * Importing dmabuf exported from our own gem increases
>>> - * refcount on gem itself instead of f_count of dmabuf.
>>> - */
>>> - drm_gem_object_get(obj);
>>> - return obj;
>>> - }
>>> + drm_gem_object_get(obj);
>>> + return obj;
>>> }
>>> if (!dev->driver->gem_prime_import_sg_table)
>>> diff --git a/include/drm/drm_gem_shmem_helper.h
>>> b/include/drm/drm_gem_shmem_helper.h
>>> index b4f993da3cae..35f7466dca84 100644
>>> --- a/include/drm/drm_gem_shmem_helper.h
>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct
>>> drm_device *dev,
>>> struct sg_table *sgt);
>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct
>>> drm_device *dev,
>>> struct drm_mode_create_dumb *args);
>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>>> drm_device *dev,
>>> + struct dma_buf *buf);
>>> /**
>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file
>>> *file, struct drm_device *dev,
>>> .gem_prime_import_sg_table =
>>> drm_gem_shmem_prime_import_sg_table, \
>>> .dumb_create = drm_gem_shmem_dumb_create
>>> +/**
>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>> + * without mapping sg_table on
>>> + * imported buffer.
>>> + *
>>> + * This macro provides a shortcut for setting the shmem GEM
>>> operations in
>>> + * the &drm_driver structure for drivers that do not require a
>>> sg_table on
>>> + * imported buffers.
>>> + */
>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>> + .dumb_create = drm_gem_shmem_dumb_create
>>> +
>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>> index fa085c44d4ca..f50f862f0d8b 100644
>>> --- a/include/drm/drm_prime.h
>>> +++ b/include/drm/drm_prime.h
>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct
>>> drm_gem_object *obj,
>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>> /* helper functions for importing */
>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>> + struct dma_buf *dma_buf);
>>> +
>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device
>>> *dev,
>>> struct dma_buf *dma_buf,
>>> struct device *attach_dev);
>>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
[not found] ` <7d974eaa-d8a4-4430-a999-7b06c4e17a81@163.com>
2025-07-14 10:47 ` Thomas Zimmermann
@ 2025-08-13 9:25 ` Thomas Zimmermann
2025-08-13 11:18 ` Christian König
1 sibling, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-13 9:25 UTC (permalink / raw)
To: Shixiong Ou, Christian König
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi
Am 14.07.25 um 12:16 schrieb Shixiong Ou:
>
>
> 在 2025/7/11 22:16, Thomas Zimmermann 写道:
>> Hi
>>
>> this patch regresses buffer sharing between udl and amdgpu. The
>> latter uses TTM. When udl imports a dma_buf from amdgpu, vmap returns
>> a kernel address, but pagefaults on the buffer cannot be handled. A
>> full error message is attached. It fails right at [1], where udl read
>> the first pixel from the buffer. That pixel address is the vmap'ed
>> buffer.
>>
>> [1]
>> https://elixir.bootlin.com/linux/v6.15.5/source/drivers/gpu/drm/udl/udl_transfer.c#L109
>>
>> Buffer sharing works with SHMEM-based drivers, which have their
>> buffers in system memory though. I assume that amdgpu's buffer is
>> located in I/O memory or scanout.
>>
>> Best regards
>> Thomas
>>
>
> Hi,
> I haven't been able to reproduce this issue yet.
> Did the driver not pin the buffer into GTT?
>
Any updates here? If we cannot fix the problem, we have to revert the
sg_table change.
Best regards
Thomas
>
> Best regards,
> Shixiong
>
>
>>
>> [ 168.785445] BUG: unable to handle page fault for address:
>> ffffc9012b800000
>> [ 168.792311] #PF: supervisor read access in kernel mode
>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted:
>> G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>> [ 168.827458] Hardware name: System manufacturer System Product
>> Name/Z170-A, BIOS 3802 03/15/2018
>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd
>> 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82
>> 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1
>> e8 08
>> c1
>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
>> 0000000000000002
>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
>> 0000000000000100
>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
>> ffff8881082e0000
>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12:
>> ffff88811c7e76f8
>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
>> 0000000000000000
>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000)
>> knlGS:0000000000000000
>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
>> 00000000003706f0
>> [ 168.922170] Call Trace:
>> [ 168.924616] <TASK>
>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>> [ 168.953162] ? mark_held_locks+0x40/0x70
>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>> [ 168.969145] ?
>> __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>> [ 168.980357] ?
>> drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>> [ 169.002943] commit_tail+0x204/0x330
>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.043466] ? find_held_lock+0x2b/0x80
>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>> [ 169.051293] ? mark_usage+0x65/0x180
>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>> [ 169.086249] drm_ioctl+0x481/0xb50
>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>> [ 169.098525] ? find_held_lock+0x2b/0x80
>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>> [ 169.118201] do_syscall_64+0x68/0x2a0
>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>> [ 169.126892] RIP: 0033:0x7f469391a53f
>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24
>> 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00
>> 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25
>> 28 00
>> 00
>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX:
>> 0000000000000010
>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX:
>> 00007f469391a53f
>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI:
>> 0000000000000010
>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09:
>> 00007f465c044cf0
>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12:
>> 00000000c03864bc
>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15:
>> 00007f45d402b110
>> [ 169.192525] </TASK>
>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E)
>> snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E)
>> iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E)
>> eeepc_wmi(E) nls
>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E)
>> iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E)
>> sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E)
>> snd_hda_scodec_component(
>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E)
>> fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E)
>> i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E)
>> intel_wmi_thunder
>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E)
>> xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E)
>> soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E)
>> nvme_fabrics(
>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E)
>> ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E)
>> drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E)
>> ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E)
>> aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E)
>> drm_display_helper(E) cec(E) w
>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E)
>> i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>> [ 169.311501] CR2: ffffc9012b800000
>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd
>> 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82
>> 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1
>> e8 08
>> c1
>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
>> 0000000000000002
>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
>> 0000000000000100
>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
>> ffff8881082e0000
>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12:
>> ffff88811c7e76f8
>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
>> 0000000000000000
>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000)
>> knlGS:0000000000000000
>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
>> 00000000003706f0
>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>> [ 175.343111]
>> ==================================================================
>> [ 175.350342] BUG: KASAN: slab-use-after-free in
>> mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task
>> kworker/5:0/49
>> [ 175.364738]
>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted:
>> G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>> [ 175.366242] Hardware name: System manufacturer System Product
>> Name/Z170-A, BIOS 3802 03/15/2018
>> [ 175.366244] Workqueue: events output_poll_execute
>> [ 175.366249] Call Trace:
>> [ 175.366251] <TASK>
>> [ 175.366254] dump_stack_lvl+0x68/0x90
>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>> [ 175.366266] ? lock_acquire+0xf2/0x140
>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366272] print_report+0xf8/0x1e2
>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366284] kasan_report+0xd8/0x190
>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>> [ 175.366345] ? lock_acquire+0xf2/0x140
>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>> [ 175.366355] ww_mutex_lock+0x27/0x150
>> [ 175.366358] modeset_lock+0x3c6/0x640
>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>> [ 175.366381] output_poll_execute+0x29b/0x760
>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>> [ 175.366396] process_one_work+0x7b5/0x1390
>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>> [ 175.366409] ? assign_work+0x156/0x390
>> [ 175.366413] worker_thread+0x58d/0xf60
>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>> [ 175.366422] kthread+0x370/0x720
>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>> [ 175.366431] ? local_clock+0x11/0x30
>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>> [ 175.366459] </TASK>
>> [ 175.366460]
>> [ 175.632772] Allocated by task 2342:
>> [ 175.636282] kasan_save_stack+0x1c/0x40
>> [ 175.640137] kasan_save_track+0x10/0x30
>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>> [ 175.653097] dup_task_struct+0x32/0x730
>> [ 175.656952] copy_process+0x2d8/0x5380
>> [ 175.660720] kernel_clone+0x9f/0x5e0
>> [ 175.664318] __do_sys_clone3+0x135/0x180
>> [ 175.668258] do_syscall_64+0x68/0x2a0
>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>> [ 175.677014]
>> [ 175.678520] Freed by task 0:
>> [ 175.681418] kasan_save_stack+0x1c/0x40
>> [ 175.685273] kasan_save_track+0x10/0x30
>> [ 175.689130] kasan_save_free_info+0x37/0x70
>> [ 175.693333] __kasan_slab_free+0x33/0x40
>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>> [ 175.709542] rcu_core+0x51d/0xb60
>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>> [ 175.720585] irq_exit_rcu+0xa/0x30
>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>> [ 175.733980]
>> [ 175.735486] Last potentially related work creation:
>> [ 175.740385] kasan_save_stack+0x1c/0x40
>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>> [ 175.753693] __schedule+0x887/0x1d00
>> [ 175.757287] schedule+0xd0/0x260
>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>> [ 175.764650] kthread+0x370/0x720
>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>> [ 175.775608]
>> [ 175.777113] Second to last potentially related work creation:
>> [ 175.782886] kasan_save_stack+0x1c/0x40
>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>> [ 175.791118] task_work_add+0x1b1/0x270
>> [ 175.794886] sched_tick+0x226/0x6f0
>> [ 175.798394] update_process_times+0xe9/0x1f0
>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>> [ 175.830343]
>> [ 175.831849] The buggy address belongs to the object at
>> ffff8881172dafc0
>> [ 175.831849] which belongs to the cache task_struct of size 11968
>> [ 175.844582] The buggy address is located 52 bytes inside of
>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0,
>> ffff8881172dde80)
>> [ 175.856969]
>> [ 175.858474] The buggy address belongs to the physical page:
>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000
>> index:0x0 pfn:0x1172d8
>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0
>> nr_pages_mapped:0 pincount:0
>> [ 175.879788] memcg:ffff88811068a301
>> [ 175.883209] anon flags:
>> 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>> [ 175.890547] page_type: f5(slab)
>> [ 175.893706] raw: 002ffff800000040 ffff888100930500
>> 0000000000000000 0000000000000001
>> [ 175.901479] raw: 0000000000000000 0000000000020002
>> 00000000f5000000 ffff88811068a301
>> [ 175.909249] head: 002ffff800000040 ffff888100930500
>> 0000000000000000 0000000000000001
>> [ 175.917109] head: 0000000000000000 0000000000020002
>> 00000000f5000000 ffff88811068a301
>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601
>> 00000000ffffffff 00000000ffffffff
>> [ 175.932827] head: ffffffffffffffff 0000000000000000
>> 00000000ffffffff 0000000000000008
>> [ 175.940685] page dumped because: kasan: bad access detected
>> [ 175.946283]
>> [ 175.947787] Memory state around the buggy address:
>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc
>> fc fc fc fc
>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc
>> fc fc fc fc
>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb
>> fb fb fb fb
>> [ 175.974353] ^
>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb
>> fb fb fb fb
>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb
>> fb fb fb fb
>> [ 175.995755]
>> ==================================================================
>>
>>
>>
>>
>>
>>
>>
>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>
>>> [WHY]
>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>> sg_table import.
>>> They only need dma_buf_vmap() to access the shared buffer's
>>> kernel virtual address.
>>>
>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>> restricts the maximum DMA streaming mapping memory, resulting in
>>> errors like:
>>>
>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes),
>>> total 32768 (slots), used 0 (slots)
>>>
>>> [HOW]
>>> Provide a gem_prime_import implementation without sg_table mapping
>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>> require sg_table can adopt this.
>>>
>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>> ---
>>> v1->v2:
>>> Patch rebase.
>>> v2->v3:
>>> Rename the import callback function.
>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>> to drm_gem_prime_import_self().
>>> v3->v4:
>>> Separate the test from the policy.
>>> Rename the macro.
>>> v4->v5:
>>> Rename some functions.
>>>
>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57
>>> ++++++++++++++++++++++++++
>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>> include/drm/drm_prime.h | 3 ++
>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> index aa43265f4f4f..126aa79042ad 100644
>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct
>>> drm_device *dev,
>>> }
>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>> +/**
>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without
>>> mapping its sg_table
>>> + * @dev: Device to import into
>>> + * @dma_buf: dma-buf object to import
>>> + *
>>> + * Drivers that use the shmem helpers but also wants to import
>>> dmabuf without
>>> + * mapping its sg_table can use this as their
>>> &drm_driver.gem_prime_import
>>> + * implementation.
>>> + */
>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>>> drm_device *dev,
>>> + struct dma_buf *dma_buf)
>>> +{
>>> + struct dma_buf_attachment *attach;
>>> + struct drm_gem_shmem_object *shmem;
>>> + struct drm_gem_object *obj;
>>> + size_t size;
>>> + int ret;
>>> +
>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>> + /*
>>> + * Importing dmabuf exported from our own gem increases
>>> + * refcount on gem itself instead of f_count of dmabuf.
>>> + */
>>> + obj = dma_buf->priv;
>>> + drm_gem_object_get(obj);
>>> + return obj;
>>> + }
>>> +
>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>> + if (IS_ERR(attach))
>>> + return ERR_CAST(attach);
>>> +
>>> + get_dma_buf(dma_buf);
>>> +
>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>> +
>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>> + if (IS_ERR(shmem)) {
>>> + ret = PTR_ERR(shmem);
>>> + goto fail_detach;
>>> + }
>>> +
>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>> +
>>> + shmem->base.import_attach = attach;
>>> + shmem->base.resv = dma_buf->resv;
>>> +
>>> + return &shmem->base;
>>> +
>>> +fail_detach:
>>> + dma_buf_detach(dma_buf, attach);
>>> + dma_buf_put(dma_buf);
>>> +
>>> + return ERR_PTR(ret);
>>> +}
>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>> +
>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>> MODULE_IMPORT_NS("DMA_BUF");
>>> MODULE_LICENSE("GPL v2");
>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>> index d828502268b8..b825b71038d6 100644
>>> --- a/drivers/gpu/drm/drm_prime.c
>>> +++ b/drivers/gpu/drm/drm_prime.c
>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct
>>> drm_gem_object *obj,
>>> }
>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>> +
>>> +/**
>>> + * drm_gem_is_prime_exported_dma_buf -
>>> + * checks if the DMA-BUF was exported from a GEM object belonging
>>> to @dev.
>>> + * @dev: drm_device to check against
>>> + * @dma_buf: dma-buf object to import
>>> + *
>>> + * Return: true if the DMA-BUF was exported from a GEM object
>>> belonging
>>> + * to @dev, false otherwise.
>>> + */
>>> +
>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>> + struct dma_buf *dma_buf)
>>> +{
>>> + struct drm_gem_object *obj = dma_buf->priv;
>>> +
>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev
>>> == dev);
>>> +}
>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>> +
>>> /**
>>> * drm_gem_prime_import_dev - core implementation of the import
>>> callback
>>> * @dev: drm_device to import into
>>> @@ -933,16 +953,14 @@ struct drm_gem_object
>>> *drm_gem_prime_import_dev(struct drm_device *dev,
>>> struct drm_gem_object *obj;
>>> int ret;
>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>> + /*
>>> + * Importing dmabuf exported from our own gem increases
>>> + * refcount on gem itself instead of f_count of dmabuf.
>>> + */
>>> obj = dma_buf->priv;
>>> - if (obj->dev == dev) {
>>> - /*
>>> - * Importing dmabuf exported from our own gem increases
>>> - * refcount on gem itself instead of f_count of dmabuf.
>>> - */
>>> - drm_gem_object_get(obj);
>>> - return obj;
>>> - }
>>> + drm_gem_object_get(obj);
>>> + return obj;
>>> }
>>> if (!dev->driver->gem_prime_import_sg_table)
>>> diff --git a/include/drm/drm_gem_shmem_helper.h
>>> b/include/drm/drm_gem_shmem_helper.h
>>> index b4f993da3cae..35f7466dca84 100644
>>> --- a/include/drm/drm_gem_shmem_helper.h
>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct
>>> drm_device *dev,
>>> struct sg_table *sgt);
>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct
>>> drm_device *dev,
>>> struct drm_mode_create_dumb *args);
>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>>> drm_device *dev,
>>> + struct dma_buf *buf);
>>> /**
>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file
>>> *file, struct drm_device *dev,
>>> .gem_prime_import_sg_table =
>>> drm_gem_shmem_prime_import_sg_table, \
>>> .dumb_create = drm_gem_shmem_dumb_create
>>> +/**
>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>> + * without mapping sg_table on
>>> + * imported buffer.
>>> + *
>>> + * This macro provides a shortcut for setting the shmem GEM
>>> operations in
>>> + * the &drm_driver structure for drivers that do not require a
>>> sg_table on
>>> + * imported buffers.
>>> + */
>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>> + .dumb_create = drm_gem_shmem_dumb_create
>>> +
>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>> index fa085c44d4ca..f50f862f0d8b 100644
>>> --- a/include/drm/drm_prime.h
>>> +++ b/include/drm/drm_prime.h
>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct
>>> drm_gem_object *obj,
>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>> /* helper functions for importing */
>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>> + struct dma_buf *dma_buf);
>>> +
>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device
>>> *dev,
>>> struct dma_buf *dma_buf,
>>> struct device *attach_dev);
>>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-13 9:25 ` Thomas Zimmermann
@ 2025-08-13 11:18 ` Christian König
2025-08-13 12:08 ` Thomas Zimmermann
0 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2025-08-13 11:18 UTC (permalink / raw)
To: Thomas Zimmermann, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
On 13.08.25 11:25, Thomas Zimmermann wrote:
> Hi
>
> Am 14.07.25 um 12:16 schrieb Shixiong Ou:
>>
>>
>> 在 2025/7/11 22:16, Thomas Zimmermann 写道:
>>> Hi
>>>
>>> this patch regresses buffer sharing between udl and amdgpu. The latter uses TTM. When udl imports a dma_buf from amdgpu, vmap returns a kernel address, but pagefaults on the buffer cannot be handled. A full error message is attached. It fails right at [1], where udl read the first pixel from the buffer. That pixel address is the vmap'ed buffer.
>>>
>>> [1] https://elixir.bootlin.com/linux/v6.15.5/source/drivers/gpu/drm/udl/udl_transfer.c#L109
>>>
>>> Buffer sharing works with SHMEM-based drivers, which have their buffers in system memory though. I assume that amdgpu's buffer is located in I/O memory or scanout.
>>>
>>> Best regards
>>> Thomas
>>>
>>
>> Hi,
>> I haven't been able to reproduce this issue yet.
>> Did the driver not pin the buffer into GTT?
>>
>
> Any updates here? If we cannot fix the problem, we have to revert the sg_table change.
Of hand that looks like a bug or rather missing implementation in udl to me which is just uncovered by this change.
See the comment in udl_handle_damage:
void *vaddr = map->vaddr; /* TODO: Use mapping abstraction properly */
Here udl just silently assumes that it got a vaddr, but that isn't necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can return an io addr as well.
Regards,
Christian.
>
> Best regards
> Thomas
>
>>
>> Best regards,
>> Shixiong
>>
>>
>>>
>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>> c1
>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>> [ 168.922170] Call Trace:
>>> [ 168.924616] <TASK>
>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>> [ 169.002943] commit_tail+0x204/0x330
>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>> [ 169.051293] ? mark_usage+0x65/0x180
>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>> 00
>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>> [ 169.192525] </TASK>
>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>> [ 169.311501] CR2: ffffc9012b800000
>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>> c1
>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>> [ 175.343111] ==================================================================
>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>> [ 175.364738]
>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>> [ 175.366244] Workqueue: events output_poll_execute
>>> [ 175.366249] Call Trace:
>>> [ 175.366251] <TASK>
>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>> [ 175.366272] print_report+0xf8/0x1e2
>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>> [ 175.366284] kasan_report+0xd8/0x190
>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>> [ 175.366409] ? assign_work+0x156/0x390
>>> [ 175.366413] worker_thread+0x58d/0xf60
>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>> [ 175.366422] kthread+0x370/0x720
>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>> [ 175.366431] ? local_clock+0x11/0x30
>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>> [ 175.366459] </TASK>
>>> [ 175.366460]
>>> [ 175.632772] Allocated by task 2342:
>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>> [ 175.640137] kasan_save_track+0x10/0x30
>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>> [ 175.653097] dup_task_struct+0x32/0x730
>>> [ 175.656952] copy_process+0x2d8/0x5380
>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>> [ 175.677014]
>>> [ 175.678520] Freed by task 0:
>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>> [ 175.685273] kasan_save_track+0x10/0x30
>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>> [ 175.709542] rcu_core+0x51d/0xb60
>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>> [ 175.733980]
>>> [ 175.735486] Last potentially related work creation:
>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>> [ 175.753693] __schedule+0x887/0x1d00
>>> [ 175.757287] schedule+0xd0/0x260
>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>> [ 175.764650] kthread+0x370/0x720
>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>> [ 175.775608]
>>> [ 175.777113] Second to last potentially related work creation:
>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>> [ 175.791118] task_work_add+0x1b1/0x270
>>> [ 175.794886] sched_tick+0x226/0x6f0
>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>> [ 175.830343]
>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>> [ 175.856969]
>>> [ 175.858474] The buggy address belongs to the physical page:
>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>> [ 175.879788] memcg:ffff88811068a301
>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>> [ 175.890547] page_type: f5(slab)
>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>> [ 175.940685] page dumped because: kasan: bad access detected
>>> [ 175.946283]
>>> [ 175.947787] Memory state around the buggy address:
>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>> [ 175.974353] ^
>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>> [ 175.995755] ==================================================================
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>
>>>> [WHY]
>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>> sg_table import.
>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>> kernel virtual address.
>>>>
>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>> errors like:
>>>>
>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>
>>>> [HOW]
>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>> require sg_table can adopt this.
>>>>
>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>> ---
>>>> v1->v2:
>>>> Patch rebase.
>>>> v2->v3:
>>>> Rename the import callback function.
>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>> to drm_gem_prime_import_self().
>>>> v3->v4:
>>>> Separate the test from the policy.
>>>> Rename the macro.
>>>> v4->v5:
>>>> Rename some functions.
>>>>
>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>> include/drm/drm_prime.h | 3 ++
>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>> index aa43265f4f4f..126aa79042ad 100644
>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>> }
>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>> +/**
>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>> + * @dev: Device to import into
>>>> + * @dma_buf: dma-buf object to import
>>>> + *
>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>> + * implementation.
>>>> + */
>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>> + struct dma_buf *dma_buf)
>>>> +{
>>>> + struct dma_buf_attachment *attach;
>>>> + struct drm_gem_shmem_object *shmem;
>>>> + struct drm_gem_object *obj;
>>>> + size_t size;
>>>> + int ret;
>>>> +
>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>> + /*
>>>> + * Importing dmabuf exported from our own gem increases
>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>> + */
>>>> + obj = dma_buf->priv;
>>>> + drm_gem_object_get(obj);
>>>> + return obj;
>>>> + }
>>>> +
>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>> + if (IS_ERR(attach))
>>>> + return ERR_CAST(attach);
>>>> +
>>>> + get_dma_buf(dma_buf);
>>>> +
>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>> +
>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>> + if (IS_ERR(shmem)) {
>>>> + ret = PTR_ERR(shmem);
>>>> + goto fail_detach;
>>>> + }
>>>> +
>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>> +
>>>> + shmem->base.import_attach = attach;
>>>> + shmem->base.resv = dma_buf->resv;
>>>> +
>>>> + return &shmem->base;
>>>> +
>>>> +fail_detach:
>>>> + dma_buf_detach(dma_buf, attach);
>>>> + dma_buf_put(dma_buf);
>>>> +
>>>> + return ERR_PTR(ret);
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>> +
>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>> MODULE_LICENSE("GPL v2");
>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>> index d828502268b8..b825b71038d6 100644
>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>> }
>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>> +
>>>> +/**
>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>> + * @dev: drm_device to check against
>>>> + * @dma_buf: dma-buf object to import
>>>> + *
>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>> + * to @dev, false otherwise.
>>>> + */
>>>> +
>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>> + struct dma_buf *dma_buf)
>>>> +{
>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>> +
>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>> +}
>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>> +
>>>> /**
>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>> * @dev: drm_device to import into
>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>> struct drm_gem_object *obj;
>>>> int ret;
>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>> + /*
>>>> + * Importing dmabuf exported from our own gem increases
>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>> + */
>>>> obj = dma_buf->priv;
>>>> - if (obj->dev == dev) {
>>>> - /*
>>>> - * Importing dmabuf exported from our own gem increases
>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>> - */
>>>> - drm_gem_object_get(obj);
>>>> - return obj;
>>>> - }
>>>> + drm_gem_object_get(obj);
>>>> + return obj;
>>>> }
>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>> index b4f993da3cae..35f7466dca84 100644
>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>> struct sg_table *sgt);
>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>> struct drm_mode_create_dumb *args);
>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>> + struct dma_buf *buf);
>>>> /**
>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>> +/**
>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>> + * without mapping sg_table on
>>>> + * imported buffer.
>>>> + *
>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>> + * imported buffers.
>>>> + */
>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>> +
>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>> --- a/include/drm/drm_prime.h
>>>> +++ b/include/drm/drm_prime.h
>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>> /* helper functions for importing */
>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>> + struct dma_buf *dma_buf);
>>>> +
>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>> struct dma_buf *dma_buf,
>>>> struct device *attach_dev);
>>>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-13 11:18 ` Christian König
@ 2025-08-13 12:08 ` Thomas Zimmermann
2025-08-13 12:16 ` Thomas Zimmermann
0 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-13 12:08 UTC (permalink / raw)
To: Christian König, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi
Am 13.08.25 um 13:18 schrieb Christian König:
> On 13.08.25 11:25, Thomas Zimmermann wrote:
>> Hi
>>
>> Am 14.07.25 um 12:16 schrieb Shixiong Ou:
>>>
>>> 在 2025/7/11 22:16, Thomas Zimmermann 写道:
>>>> Hi
>>>>
>>>> this patch regresses buffer sharing between udl and amdgpu. The latter uses TTM. When udl imports a dma_buf from amdgpu, vmap returns a kernel address, but pagefaults on the buffer cannot be handled. A full error message is attached. It fails right at [1], where udl read the first pixel from the buffer. That pixel address is the vmap'ed buffer.
>>>>
>>>> [1] https://elixir.bootlin.com/linux/v6.15.5/source/drivers/gpu/drm/udl/udl_transfer.c#L109
>>>>
>>>> Buffer sharing works with SHMEM-based drivers, which have their buffers in system memory though. I assume that amdgpu's buffer is located in I/O memory or scanout.
>>>>
>>>> Best regards
>>>> Thomas
>>>>
>>> Hi,
>>> I haven't been able to reproduce this issue yet.
>>> Did the driver not pin the buffer into GTT?
>>>
>> Any updates here? If we cannot fix the problem, we have to revert the sg_table change.
> Of hand that looks like a bug or rather missing implementation in udl to me which is just uncovered by this change.
>
> See the comment in udl_handle_damage:
>
> void *vaddr = map->vaddr; /* TODO: Use mapping abstraction properly */
>
> Here udl just silently assumes that it got a vaddr, but that isn't necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can return an io addr as well.
That's a union of the two pointer types. [1] Using them interchangeably
has worked so far (*) and should work here as well. As I said in the
other mail, ttm_bo_vmap() never bothers to pin the pages in place and
amdgpu might relocated them shortly after.
[1]
https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
Best regards
Thomas
(*) White lie: we had problems on exotic architectures, such as sparc,
but never on x86.
>
> Regards,
> Christian.
>
>> Best regards
>> Thomas
>>
>>> Best regards,
>>> Shixiong
>>>
>>>
>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>> c1
>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>> [ 168.922170] Call Trace:
>>>> [ 168.924616] <TASK>
>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>> [ 169.002943] commit_tail+0x204/0x330
>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>> 00
>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>> [ 169.192525] </TASK>
>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>> [ 169.311501] CR2: ffffc9012b800000
>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>> c1
>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>> [ 175.343111] ==================================================================
>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>> [ 175.364738]
>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>> [ 175.366249] Call Trace:
>>>> [ 175.366251] <TASK>
>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>> [ 175.366422] kthread+0x370/0x720
>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>> [ 175.366459] </TASK>
>>>> [ 175.366460]
>>>> [ 175.632772] Allocated by task 2342:
>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>> [ 175.677014]
>>>> [ 175.678520] Freed by task 0:
>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>> [ 175.733980]
>>>> [ 175.735486] Last potentially related work creation:
>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>> [ 175.757287] schedule+0xd0/0x260
>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>> [ 175.764650] kthread+0x370/0x720
>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>> [ 175.775608]
>>>> [ 175.777113] Second to last potentially related work creation:
>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>> [ 175.830343]
>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>> [ 175.856969]
>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>> [ 175.879788] memcg:ffff88811068a301
>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>> [ 175.890547] page_type: f5(slab)
>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>> [ 175.946283]
>>>> [ 175.947787] Memory state around the buggy address:
>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>> [ 175.974353] ^
>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>> [ 175.995755] ==================================================================
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>
>>>>> [WHY]
>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>> sg_table import.
>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>> kernel virtual address.
>>>>>
>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>> errors like:
>>>>>
>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>
>>>>> [HOW]
>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>> require sg_table can adopt this.
>>>>>
>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>> ---
>>>>> v1->v2:
>>>>> Patch rebase.
>>>>> v2->v3:
>>>>> Rename the import callback function.
>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>> to drm_gem_prime_import_self().
>>>>> v3->v4:
>>>>> Separate the test from the policy.
>>>>> Rename the macro.
>>>>> v4->v5:
>>>>> Rename some functions.
>>>>>
>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>> include/drm/drm_prime.h | 3 ++
>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>> }
>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>> +/**
>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>> + * @dev: Device to import into
>>>>> + * @dma_buf: dma-buf object to import
>>>>> + *
>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>> + * implementation.
>>>>> + */
>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>> + struct dma_buf *dma_buf)
>>>>> +{
>>>>> + struct dma_buf_attachment *attach;
>>>>> + struct drm_gem_shmem_object *shmem;
>>>>> + struct drm_gem_object *obj;
>>>>> + size_t size;
>>>>> + int ret;
>>>>> +
>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>> + /*
>>>>> + * Importing dmabuf exported from our own gem increases
>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>> + */
>>>>> + obj = dma_buf->priv;
>>>>> + drm_gem_object_get(obj);
>>>>> + return obj;
>>>>> + }
>>>>> +
>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>> + if (IS_ERR(attach))
>>>>> + return ERR_CAST(attach);
>>>>> +
>>>>> + get_dma_buf(dma_buf);
>>>>> +
>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>> +
>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>> + if (IS_ERR(shmem)) {
>>>>> + ret = PTR_ERR(shmem);
>>>>> + goto fail_detach;
>>>>> + }
>>>>> +
>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>> +
>>>>> + shmem->base.import_attach = attach;
>>>>> + shmem->base.resv = dma_buf->resv;
>>>>> +
>>>>> + return &shmem->base;
>>>>> +
>>>>> +fail_detach:
>>>>> + dma_buf_detach(dma_buf, attach);
>>>>> + dma_buf_put(dma_buf);
>>>>> +
>>>>> + return ERR_PTR(ret);
>>>>> +}
>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>> +
>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>> MODULE_LICENSE("GPL v2");
>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>> index d828502268b8..b825b71038d6 100644
>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>> }
>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>> +
>>>>> +/**
>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>> + * @dev: drm_device to check against
>>>>> + * @dma_buf: dma-buf object to import
>>>>> + *
>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>> + * to @dev, false otherwise.
>>>>> + */
>>>>> +
>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>> + struct dma_buf *dma_buf)
>>>>> +{
>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>> +
>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>> +}
>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>> +
>>>>> /**
>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>> * @dev: drm_device to import into
>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>> struct drm_gem_object *obj;
>>>>> int ret;
>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>> + /*
>>>>> + * Importing dmabuf exported from our own gem increases
>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>> + */
>>>>> obj = dma_buf->priv;
>>>>> - if (obj->dev == dev) {
>>>>> - /*
>>>>> - * Importing dmabuf exported from our own gem increases
>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>> - */
>>>>> - drm_gem_object_get(obj);
>>>>> - return obj;
>>>>> - }
>>>>> + drm_gem_object_get(obj);
>>>>> + return obj;
>>>>> }
>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>> struct sg_table *sgt);
>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>> struct drm_mode_create_dumb *args);
>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>> + struct dma_buf *buf);
>>>>> /**
>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>> +/**
>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>> + * without mapping sg_table on
>>>>> + * imported buffer.
>>>>> + *
>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>> + * imported buffers.
>>>>> + */
>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>> +
>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>> --- a/include/drm/drm_prime.h
>>>>> +++ b/include/drm/drm_prime.h
>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>> /* helper functions for importing */
>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>> + struct dma_buf *dma_buf);
>>>>> +
>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>> struct dma_buf *dma_buf,
>>>>> struct device *attach_dev);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-13 12:08 ` Thomas Zimmermann
@ 2025-08-13 12:16 ` Thomas Zimmermann
2025-08-13 13:35 ` Christian König
0 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-13 12:16 UTC (permalink / raw)
To: Christian König, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
In addition:
>> Here udl just silently assumes that it got a vaddr, but that isn't
>> necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can
>> return an io addr as well.
>
> That's a union of the two pointer types. [1] Using them
> interchangeably has worked so far (*) and should work here as well. As
> I said in the other mail, ttm_bo_vmap() never bothers to pin the pages
> in place and amdgpu might relocated them shortly after.
AFAICT with the old code we ran dma_buf_pin_on_map() at some point.
Could we do this in the new version as well?
[1]
https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
Best regards
Thomas
>
> [1]
> https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>
> Best regards
> Thomas
>
> (*) White lie: we had problems on exotic architectures, such as sparc,
> but never on x86.
>
>
>>
>> Regards,
>> Christian.
>>
>>> Best regards
>>> Thomas
>>>
>>>> Best regards,
>>>> Shixiong
>>>>
>>>>
>>>>> [ 168.785445] BUG: unable to handle page fault for address:
>>>>> ffffc9012b800000
>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread
>>>>> Tainted: G E 6.16.0-rc5-1-default+ #4080
>>>>> PREEMPT(voluntary)
>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>> [ 168.827458] Hardware name: System manufacturer System Product
>>>>> Name/Z170-A, BIOS 3802 03/15/2018
>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01
>>>>> dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f
>>>>> 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41
>>>>> 89 c4 c1 e8 08
>>>>> c1
>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
>>>>> 0000000000000002
>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
>>>>> 0000000000000100
>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
>>>>> ffff8881082e0000
>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12:
>>>>> ffff88811c7e76f8
>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
>>>>> 0000000000000000
>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000)
>>>>> GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
>>>>> 00000000003706f0
>>>>> [ 168.922170] Call Trace:
>>>>> [ 168.924616] <TASK>
>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670
>>>>> [udl]
>>>>> [ 168.969145] ?
>>>>> __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>> [ 168.980357] ?
>>>>> drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04
>>>>> 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10
>>>>> 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48
>>>>> 2b 04 25 28 00
>>>>> 00
>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246
>>>>> ORIG_RAX: 0000000000000010
>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX:
>>>>> 00007f469391a53f
>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI:
>>>>> 0000000000000010
>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09:
>>>>> 00007f465c044cf0
>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12:
>>>>> 00000000c03864bc
>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15:
>>>>> 00007f45d402b110
>>>>> [ 169.192525] </TASK>
>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E)
>>>>> snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E)
>>>>> nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E)
>>>>> nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E)
>>>>> asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E)
>>>>> sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E)
>>>>> snd_hda_scodec_component(
>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E)
>>>>> fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E)
>>>>> i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E)
>>>>> intel_wmi_thunder
>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E)
>>>>> snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E)
>>>>> snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E)
>>>>> mei(E) joydev(E) nvme_fabrics(
>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E)
>>>>> nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E)
>>>>> i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E)
>>>>> ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E)
>>>>> aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E)
>>>>> drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E)
>>>>> i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01
>>>>> dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f
>>>>> 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41
>>>>> 89 c4 c1 e8 08
>>>>> c1
>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX:
>>>>> 0000000000000002
>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
>>>>> 0000000000000100
>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09:
>>>>> ffff8881082e0000
>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12:
>>>>> ffff88811c7e76f8
>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15:
>>>>> 0000000000000000
>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000)
>>>>> GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4:
>>>>> 00000000003706f0
>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>> [ 175.343111]
>>>>> ==================================================================
>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in
>>>>> mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task
>>>>> kworker/5:0/49
>>>>> [ 175.364738]
>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted:
>>>>> G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>> [ 175.366242] Hardware name: System manufacturer System Product
>>>>> Name/Z170-A, BIOS 3802 03/15/2018
>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>> [ 175.366249] Call Trace:
>>>>> [ 175.366251] <TASK>
>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>> [ 175.366422] kthread+0x370/0x720
>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>> [ 175.366459] </TASK>
>>>>> [ 175.366460]
>>>>> [ 175.632772] Allocated by task 2342:
>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>> [ 175.677014]
>>>>> [ 175.678520] Freed by task 0:
>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>> [ 175.733980]
>>>>> [ 175.735486] Last potentially related work creation:
>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>> [ 175.764650] kthread+0x370/0x720
>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>> [ 175.775608]
>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>> [ 175.830343]
>>>>> [ 175.831849] The buggy address belongs to the object at
>>>>> ffff8881172dafc0
>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0,
>>>>> ffff8881172dde80)
>>>>> [ 175.856969]
>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>> [ 175.864070] page: refcount:0 mapcount:0
>>>>> mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0
>>>>> nr_pages_mapped:0 pincount:0
>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>> [ 175.883209] anon flags:
>>>>> 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>> [ 175.890547] page_type: f5(slab)
>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500
>>>>> 0000000000000000 0000000000000001
>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002
>>>>> 00000000f5000000 ffff88811068a301
>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500
>>>>> 0000000000000000 0000000000000001
>>>>> [ 175.917109] head: 0000000000000000 0000000000020002
>>>>> 00000000f5000000 ffff88811068a301
>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601
>>>>> 00000000ffffffff 00000000ffffffff
>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000
>>>>> 00000000ffffffff 0000000000000008
>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>> [ 175.946283]
>>>>> [ 175.947787] Memory state around the buggy address:
>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc
>>>>> fc fc fc fc fc
>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc
>>>>> fc fc fc fc fc
>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb
>>>>> fb fb fb fb fb
>>>>> [ 175.974353] ^
>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb
>>>>> fb fb fb fb fb
>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb
>>>>> fb fb fb fb fb
>>>>> [ 175.995755]
>>>>> ==================================================================
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>
>>>>>> [WHY]
>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>> sg_table import.
>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>> kernel virtual address.
>>>>>>
>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>> restricts the maximum DMA streaming mapping memory,
>>>>>> resulting in
>>>>>> errors like:
>>>>>>
>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728
>>>>>> bytes), total 32768 (slots), used 0 (slots)
>>>>>>
>>>>>> [HOW]
>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do
>>>>>> not
>>>>>> require sg_table can adopt this.
>>>>>>
>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>> ---
>>>>>> v1->v2:
>>>>>> Patch rebase.
>>>>>> v2->v3:
>>>>>> Rename the import callback function.
>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>> to drm_gem_prime_import_self().
>>>>>> v3->v4:
>>>>>> Separate the test from the policy.
>>>>>> Rename the macro.
>>>>>> v4->v5:
>>>>>> Rename some functions.
>>>>>>
>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57
>>>>>> ++++++++++++++++++++++++++
>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct
>>>>>> drm_device *dev,
>>>>>> }
>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>> +/**
>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without
>>>>>> mapping its sg_table
>>>>>> + * @dev: Device to import into
>>>>>> + * @dma_buf: dma-buf object to import
>>>>>> + *
>>>>>> + * Drivers that use the shmem helpers but also wants to import
>>>>>> dmabuf without
>>>>>> + * mapping its sg_table can use this as their
>>>>>> &drm_driver.gem_prime_import
>>>>>> + * implementation.
>>>>>> + */
>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>>>>>> drm_device *dev,
>>>>>> + struct dma_buf *dma_buf)
>>>>>> +{
>>>>>> + struct dma_buf_attachment *attach;
>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>> + struct drm_gem_object *obj;
>>>>>> + size_t size;
>>>>>> + int ret;
>>>>>> +
>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>> + /*
>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>> + */
>>>>>> + obj = dma_buf->priv;
>>>>>> + drm_gem_object_get(obj);
>>>>>> + return obj;
>>>>>> + }
>>>>>> +
>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>> + if (IS_ERR(attach))
>>>>>> + return ERR_CAST(attach);
>>>>>> +
>>>>>> + get_dma_buf(dma_buf);
>>>>>> +
>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>> +
>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>> + if (IS_ERR(shmem)) {
>>>>>> + ret = PTR_ERR(shmem);
>>>>>> + goto fail_detach;
>>>>>> + }
>>>>>> +
>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>> +
>>>>>> + shmem->base.import_attach = attach;
>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>> +
>>>>>> + return &shmem->base;
>>>>>> +
>>>>>> +fail_detach:
>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>> + dma_buf_put(dma_buf);
>>>>>> +
>>>>>> + return ERR_PTR(ret);
>>>>>> +}
>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>> +
>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>> MODULE_LICENSE("GPL v2");
>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c
>>>>>> b/drivers/gpu/drm/drm_prime.c
>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct
>>>>>> drm_gem_object *obj,
>>>>>> }
>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>> +
>>>>>> +/**
>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>> + * checks if the DMA-BUF was exported from a GEM object
>>>>>> belonging to @dev.
>>>>>> + * @dev: drm_device to check against
>>>>>> + * @dma_buf: dma-buf object to import
>>>>>> + *
>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object
>>>>>> belonging
>>>>>> + * to @dev, false otherwise.
>>>>>> + */
>>>>>> +
>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>> + struct dma_buf *dma_buf)
>>>>>> +{
>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>> +
>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) &&
>>>>>> (obj->dev == dev);
>>>>>> +}
>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>> +
>>>>>> /**
>>>>>> * drm_gem_prime_import_dev - core implementation of the
>>>>>> import callback
>>>>>> * @dev: drm_device to import into
>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object
>>>>>> *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>> struct drm_gem_object *obj;
>>>>>> int ret;
>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>> + /*
>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>> + */
>>>>>> obj = dma_buf->priv;
>>>>>> - if (obj->dev == dev) {
>>>>>> - /*
>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>> - */
>>>>>> - drm_gem_object_get(obj);
>>>>>> - return obj;
>>>>>> - }
>>>>>> + drm_gem_object_get(obj);
>>>>>> + return obj;
>>>>>> }
>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h
>>>>>> b/include/drm/drm_gem_shmem_helper.h
>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct
>>>>>> drm_device *dev,
>>>>>> struct sg_table *sgt);
>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct
>>>>>> drm_device *dev,
>>>>>> struct drm_mode_create_dumb *args);
>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct
>>>>>> drm_device *dev,
>>>>>> + struct dma_buf *buf);
>>>>>> /**
>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct
>>>>>> drm_file *file, struct drm_device *dev,
>>>>>> .gem_prime_import_sg_table =
>>>>>> drm_gem_shmem_prime_import_sg_table, \
>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>> +/**
>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>> + * without mapping
>>>>>> sg_table on
>>>>>> + * imported buffer.
>>>>>> + *
>>>>>> + * This macro provides a shortcut for setting the shmem GEM
>>>>>> operations in
>>>>>> + * the &drm_driver structure for drivers that do not require a
>>>>>> sg_table on
>>>>>> + * imported buffers.
>>>>>> + */
>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>> +
>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>> --- a/include/drm/drm_prime.h
>>>>>> +++ b/include/drm/drm_prime.h
>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct
>>>>>> drm_gem_object *obj,
>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table
>>>>>> *sgt);
>>>>>> /* helper functions for importing */
>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>> + struct dma_buf *dma_buf);
>>>>>> +
>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct
>>>>>> drm_device *dev,
>>>>>> struct dma_buf *dma_buf,
>>>>>> struct device *attach_dev);
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-13 12:16 ` Thomas Zimmermann
@ 2025-08-13 13:35 ` Christian König
2025-08-13 14:06 ` Thomas Zimmermann
0 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2025-08-13 13:35 UTC (permalink / raw)
To: Thomas Zimmermann, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
On 13.08.25 14:16, Thomas Zimmermann wrote:
> In addition:
>
>>> Here udl just silently assumes that it got a vaddr, but that isn't necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can return an io addr as well.
>>
>> That's a union of the two pointer types. [1] Using them interchangeably has worked so far (*) and should work here as well. As I said in the other mail, ttm_bo_vmap() never bothers to pin the pages in place and amdgpu might relocated them shortly after.
>
> AFAICT with the old code we ran dma_buf_pin_on_map() at some point. Could we do this in the new version as well?
Ah, yes that could be it. So basically the buffer moves and because of that the vmap is unmapped.
It would probably be a good idea to call dma_buf_pin() from drm_gem_dmabuf_vmap() before calling drm_gem_vmap_locked().
Should be trivial since we already have the dma_buf object and the necessary lock is held as well.
Regards,
Christian.
>
> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>
> Best regards
> Thomas
>
>>
>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>
>> Best regards
>> Thomas
>>
>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>
>>
>>>
>>> Regards,
>>> Christian.
>>>
>>>> Best regards
>>>> Thomas
>>>>
>>>>> Best regards,
>>>>> Shixiong
>>>>>
>>>>>
>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>> c1
>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>> [ 168.922170] Call Trace:
>>>>>> [ 168.924616] <TASK>
>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>> 00
>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>> [ 169.192525] </TASK>
>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>> c1
>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>> [ 175.343111] ==================================================================
>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>> [ 175.364738]
>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>> [ 175.366249] Call Trace:
>>>>>> [ 175.366251] <TASK>
>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>> [ 175.366459] </TASK>
>>>>>> [ 175.366460]
>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>> [ 175.677014]
>>>>>> [ 175.678520] Freed by task 0:
>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>> [ 175.733980]
>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>> [ 175.775608]
>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>> [ 175.830343]
>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>> [ 175.856969]
>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>> [ 175.946283]
>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>> [ 175.974353] ^
>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>> [ 175.995755] ==================================================================
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>
>>>>>>> [WHY]
>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>> sg_table import.
>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>> kernel virtual address.
>>>>>>>
>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>> errors like:
>>>>>>>
>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>
>>>>>>> [HOW]
>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>> require sg_table can adopt this.
>>>>>>>
>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>> ---
>>>>>>> v1->v2:
>>>>>>> Patch rebase.
>>>>>>> v2->v3:
>>>>>>> Rename the import callback function.
>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>> to drm_gem_prime_import_self().
>>>>>>> v3->v4:
>>>>>>> Separate the test from the policy.
>>>>>>> Rename the macro.
>>>>>>> v4->v5:
>>>>>>> Rename some functions.
>>>>>>>
>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>> }
>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>> +/**
>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>> + * @dev: Device to import into
>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>> + *
>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>> + * implementation.
>>>>>>> + */
>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>> + struct dma_buf *dma_buf)
>>>>>>> +{
>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>> + struct drm_gem_object *obj;
>>>>>>> + size_t size;
>>>>>>> + int ret;
>>>>>>> +
>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>> + /*
>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>> + */
>>>>>>> + obj = dma_buf->priv;
>>>>>>> + drm_gem_object_get(obj);
>>>>>>> + return obj;
>>>>>>> + }
>>>>>>> +
>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>> + if (IS_ERR(attach))
>>>>>>> + return ERR_CAST(attach);
>>>>>>> +
>>>>>>> + get_dma_buf(dma_buf);
>>>>>>> +
>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>> +
>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>> + goto fail_detach;
>>>>>>> + }
>>>>>>> +
>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>> +
>>>>>>> + shmem->base.import_attach = attach;
>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>> +
>>>>>>> + return &shmem->base;
>>>>>>> +
>>>>>>> +fail_detach:
>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>> + dma_buf_put(dma_buf);
>>>>>>> +
>>>>>>> + return ERR_PTR(ret);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>> +
>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>> }
>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>> +
>>>>>>> +/**
>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>> + * @dev: drm_device to check against
>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>> + *
>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>> + * to @dev, false otherwise.
>>>>>>> + */
>>>>>>> +
>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>> + struct dma_buf *dma_buf)
>>>>>>> +{
>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>> +
>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>> +
>>>>>>> /**
>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>> * @dev: drm_device to import into
>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>> struct drm_gem_object *obj;
>>>>>>> int ret;
>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>> + /*
>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>> + */
>>>>>>> obj = dma_buf->priv;
>>>>>>> - if (obj->dev == dev) {
>>>>>>> - /*
>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>> - */
>>>>>>> - drm_gem_object_get(obj);
>>>>>>> - return obj;
>>>>>>> - }
>>>>>>> + drm_gem_object_get(obj);
>>>>>>> + return obj;
>>>>>>> }
>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>> struct sg_table *sgt);
>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>> + struct dma_buf *buf);
>>>>>>> /**
>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>> +/**
>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>> + * without mapping sg_table on
>>>>>>> + * imported buffer.
>>>>>>> + *
>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>> + * imported buffers.
>>>>>>> + */
>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>> +
>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>> /* helper functions for importing */
>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>> + struct dma_buf *dma_buf);
>>>>>>> +
>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>> struct dma_buf *dma_buf,
>>>>>>> struct device *attach_dev);
>>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-13 13:35 ` Christian König
@ 2025-08-13 14:06 ` Thomas Zimmermann
2025-08-14 10:22 ` Christian König
0 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-13 14:06 UTC (permalink / raw)
To: Christian König, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
[-- Attachment #1: Type: text/plain, Size: 29018 bytes --]
Hi
Am 13.08.25 um 15:35 schrieb Christian König:
> On 13.08.25 14:16, Thomas Zimmermann wrote:
>> In addition:
>>
>>>> Here udl just silently assumes that it got a vaddr, but that isn't necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can return an io addr as well.
>>> That's a union of the two pointer types. [1] Using them interchangeably has worked so far (*) and should work here as well. As I said in the other mail, ttm_bo_vmap() never bothers to pin the pages in place and amdgpu might relocated them shortly after.
>> AFAICT with the old code we ran dma_buf_pin_on_map() at some point. Could we do this in the new version as well?
> Ah, yes that could be it. So basically the buffer moves and because of that the vmap is unmapped.
>
> It would probably be a good idea to call dma_buf_pin() from drm_gem_dmabuf_vmap() before calling drm_gem_vmap_locked().
>
> Should be trivial since we already have the dma_buf object and the necessary lock is held as well.
The attached patch fixes the problem on my test system. It further
integrates well with the existing logic, so changes are minimal. Any
comments before I send it out for review?
Best regards
Thomas
>
> Regards,
> Christian.
>
>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>
>> Best regards
>> Thomas
>>
>>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>
>>> Best regards
>>> Thomas
>>>
>>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>>
>>>
>>>> Regards,
>>>> Christian.
>>>>
>>>>> Best regards
>>>>> Thomas
>>>>>
>>>>>> Best regards,
>>>>>> Shixiong
>>>>>>
>>>>>>
>>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>> c1
>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>> [ 168.922170] Call Trace:
>>>>>>> [ 168.924616] <TASK>
>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>> 00
>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>> [ 169.192525] </TASK>
>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>> c1
>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>>> [ 175.343111] ==================================================================
>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>>> [ 175.364738]
>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>> [ 175.366249] Call Trace:
>>>>>>> [ 175.366251] <TASK>
>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>> [ 175.366459] </TASK>
>>>>>>> [ 175.366460]
>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>> [ 175.677014]
>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>> [ 175.733980]
>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>> [ 175.775608]
>>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>> [ 175.830343]
>>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>>> [ 175.856969]
>>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>>> [ 175.946283]
>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>>> [ 175.974353] ^
>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>> [ 175.995755] ==================================================================
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>
>>>>>>>> [WHY]
>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>>> sg_table import.
>>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>>> kernel virtual address.
>>>>>>>>
>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>>> errors like:
>>>>>>>>
>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>
>>>>>>>> [HOW]
>>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>>> require sg_table can adopt this.
>>>>>>>>
>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>> ---
>>>>>>>> v1->v2:
>>>>>>>> Patch rebase.
>>>>>>>> v2->v3:
>>>>>>>> Rename the import callback function.
>>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>> v3->v4:
>>>>>>>> Separate the test from the policy.
>>>>>>>> Rename the macro.
>>>>>>>> v4->v5:
>>>>>>>> Rename some functions.
>>>>>>>>
>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>> }
>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>> +/**
>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>>> + * @dev: Device to import into
>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>> + *
>>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>>> + * implementation.
>>>>>>>> + */
>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>> +{
>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>> + size_t size;
>>>>>>>> + int ret;
>>>>>>>> +
>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>> + /*
>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>> + */
>>>>>>>> + obj = dma_buf->priv;
>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>> + return obj;
>>>>>>>> + }
>>>>>>>> +
>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>> + if (IS_ERR(attach))
>>>>>>>> + return ERR_CAST(attach);
>>>>>>>> +
>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>> +
>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>> +
>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>> + goto fail_detach;
>>>>>>>> + }
>>>>>>>> +
>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>> +
>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>> +
>>>>>>>> + return &shmem->base;
>>>>>>>> +
>>>>>>>> +fail_detach:
>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>> +
>>>>>>>> + return ERR_PTR(ret);
>>>>>>>> +}
>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>> +
>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>> }
>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>> +
>>>>>>>> +/**
>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>>> + * @dev: drm_device to check against
>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>> + *
>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>>> + * to @dev, false otherwise.
>>>>>>>> + */
>>>>>>>> +
>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>> +{
>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>> +
>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>>> +}
>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>> +
>>>>>>>> /**
>>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>>> * @dev: drm_device to import into
>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>> struct drm_gem_object *obj;
>>>>>>>> int ret;
>>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>> + /*
>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>> + */
>>>>>>>> obj = dma_buf->priv;
>>>>>>>> - if (obj->dev == dev) {
>>>>>>>> - /*
>>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>> - */
>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>> - return obj;
>>>>>>>> - }
>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>> + return obj;
>>>>>>>> }
>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>> struct sg_table *sgt);
>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>> + struct dma_buf *buf);
>>>>>>>> /**
>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>> +/**
>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>>> + * without mapping sg_table on
>>>>>>>> + * imported buffer.
>>>>>>>> + *
>>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>>> + * imported buffers.
>>>>>>>> + */
>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>> +
>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>> /* helper functions for importing */
>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>> +
>>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>> struct device *attach_dev);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
[-- Attachment #2: 0001-drm-gem-shmem-Pin-and-unpin-buffers-when-importing-w.patch --]
[-- Type: text/x-patch, Size: 6666 bytes --]
From ed057acf38cfb8fafe1d68e5d7965c414e8a9a60 Mon Sep 17 00:00:00 2001
From: Thomas Zimmermann <tzimmermann@suse.de>
Date: Wed, 13 Aug 2025 14:40:43 +0200
Subject: [PATCH] drm/gem-shmem: Pin and unpin buffers when importing w/o S/G
table
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Imported dma-buf objects need to be pinned while being vmap'ed into
kernel address space. This used to be done before while creating an
S/G table.
GEM-SHMEN can import dma-buf objects without creating the S/G table,
but the pin/unpin is now missing. Leads to page-mapping errors such
as the one shown below.
[ 102.101726] BUG: unable to handle page fault for address: ffffc90127000000
[...]
[ 102.157102] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
[...]
[ 102.243250] Call Trace:
[ 102.245695] <TASK>
[ 102.2477V95] ? validate_chain+0x24e/0x5e0
[ 102.251805] ? __lock_acquire+0x568/0xae0
[ 102.255807] udl_render_hline+0x165/0x341 [udl]
[ 102.260338] ? __pfx_udl_render_hline+0x10/0x10 [udl]
[ 102.265379] ? local_clock_noinstr+0xb/0x100
[ 102.269642] ? __lock_release.isra.0+0x16c/0x2e0
[ 102.274246] ? mark_held_locks+0x40/0x70
[ 102.278177] udl_primary_plane_helper_atomic_update+0x43e/0x680 [udl]
[ 102.284606] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
[ 102.291551] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
[ 102.297208] ? lockdep_hardirqs_on+0x88/0x130
[ 102.301554] ? _raw_spin_unlock_irq+0x24/0x50
[ 102.305901] ? wait_for_completion_timeout+0x2bb/0x3a0
[ 102.311028] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
[ 102.317714] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 102.323279] drm_atomic_helper_commit_planes+0x3b6/0x1030
[ 102.328664] drm_atomic_helper_commit_tail+0x41/0xb0
[ 102.333622] commit_tail+0x204/0x330
[...]
[ 102.529946] ---[ end trace 0000000000000000 ]---
[ 102.651980] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
Support pin/unpin in drm_buf_map_attachment() without creating S/G
table. Passing DMA_NONE for the DMA direction will only pin. Do the
inverse for unmap_attachment(). Modify GEM-SHMEM accordingly, so that
it pins the imported dma-buf.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 660cd44659a0 ("drm/shmem-helper: Import dmabuf without mapping its sg_table")
Cc: Shixiong Ou <oushixiong@kylinos.cn>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: David Airlie <airlied@gmail.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: "Christian König" <christian.koenig@amd.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-media@vger.kernel.org
Cc: linaro-mm-sig@lists.linaro.org
---
drivers/dma-buf/dma-buf.c | 16 +++++++++++++---
drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++++++-
drivers/gpu/drm/drm_prime.c | 2 ++
3 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 2bcf9ceca997..f1e1385ce630 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1086,7 +1086,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, "DMA_BUF");
* @direction: [in] direction of DMA transfer
*
* Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
- * on error. May return -EINTR if it is interrupted by a signal.
+ * on error. May return -EINTR if it is interrupted by a signal. Returns NULL
+ * on success iff direction is DMA_NONE.
*
* On success, the DMA addresses and lengths in the returned scatterlist are
* PAGE_SIZE aligned.
@@ -1122,6 +1123,8 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
if (ret)
return ERR_PTR(ret);
}
+ if (!valid_dma_direction(direction))
+ return NULL; /* only pin; don't map */
sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
if (!sg_table)
@@ -1216,14 +1219,21 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
{
might_sleep();
- if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
+ if (WARN_ON(!attach || !attach->dmabuf))
return;
dma_resv_assert_held(attach->dmabuf->resv);
+ if (!valid_dma_direction(direction))
+ goto unpin;
+
+ if (WARN_ON(!sg_table))
+ return;
+
mangle_sg_table(sg_table);
attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
+unpin:
if (dma_buf_pin_on_map(attach))
attach->dmabuf->ops->unpin(attach);
}
@@ -1245,7 +1255,7 @@ void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
{
might_sleep();
- if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
+ if (WARN_ON(!attach || !attach->dmabuf))
return;
dma_resv_lock(attach->dmabuf->resv, NULL);
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 5d1349c34afd..1b66501420d3 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -817,6 +817,7 @@ struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
struct dma_buf *dma_buf)
{
struct dma_buf_attachment *attach;
+ struct sg_table *sgt;
struct drm_gem_shmem_object *shmem;
struct drm_gem_object *obj;
size_t size;
@@ -838,12 +839,18 @@ struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
get_dma_buf(dma_buf);
+ sgt = dma_buf_map_attachment_unlocked(attach, DMA_NONE);
+ if (IS_ERR(sgt)) {
+ ret = PTR_ERR(sgt);
+ goto fail_detach;
+ }
+
size = PAGE_ALIGN(attach->dmabuf->size);
shmem = __drm_gem_shmem_create(dev, size, true, NULL);
if (IS_ERR(shmem)) {
ret = PTR_ERR(shmem);
- goto fail_detach;
+ goto fail_unmap;
}
drm_dbg_prime(dev, "size = %zu\n", size);
@@ -853,6 +860,8 @@ struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
return &shmem->base;
+fail_unmap:
+ dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_NONE);
fail_detach:
dma_buf_detach(dma_buf, attach);
dma_buf_put(dma_buf);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 43a10b4af43a..b3b070868e3b 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -1109,6 +1109,8 @@ void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
attach = obj->import_attach;
if (sg)
dma_buf_unmap_attachment_unlocked(attach, sg, DMA_BIDIRECTIONAL);
+ else
+ dma_buf_unmap_attachment_unlocked(attach, NULL, DMA_NONE);
dma_buf = attach->dmabuf;
dma_buf_detach(attach->dmabuf, attach);
/* remove the reference */
--
2.50.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-13 14:06 ` Thomas Zimmermann
@ 2025-08-14 10:22 ` Christian König
2025-08-14 12:51 ` Thomas Zimmermann
0 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2025-08-14 10:22 UTC (permalink / raw)
To: Thomas Zimmermann, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
On 13.08.25 16:06, Thomas Zimmermann wrote:
> Hi
>
> Am 13.08.25 um 15:35 schrieb Christian König:
>> On 13.08.25 14:16, Thomas Zimmermann wrote:
>>> In addition:
>>>
>>>>> Here udl just silently assumes that it got a vaddr, but that isn't necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can return an io addr as well.
>>>> That's a union of the two pointer types. [1] Using them interchangeably has worked so far (*) and should work here as well. As I said in the other mail, ttm_bo_vmap() never bothers to pin the pages in place and amdgpu might relocated them shortly after.
>>> AFAICT with the old code we ran dma_buf_pin_on_map() at some point. Could we do this in the new version as well?
>> Ah, yes that could be it. So basically the buffer moves and because of that the vmap is unmapped.
>>
>> It would probably be a good idea to call dma_buf_pin() from drm_gem_dmabuf_vmap() before calling drm_gem_vmap_locked().
>>
>> Should be trivial since we already have the dma_buf object and the necessary lock is held as well.
>
> The attached patch fixes the problem on my test system. It further integrates well with the existing logic, so changes are minimal. Any comments before I send it out for review?
Mhm that looks more or less like what I had in mind initially as well, but I was convinced that this is probably not the best idea.
We have exposed the dma_buf_pin()/dma_buf_unpin() functions for exactly that use case. So we should probably make use of that.
Either by pinning in the exporter, e.g. drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() or even lower level (amdgpu/ttm) or in the importer.
Not doing it in TTM was intentional since we have use cases where kmap/vmap is only temporary valid until you drop the dma_resv lock again.
Doing it in the importer would be the cleanest approach, but that means changing the semantics of the DMA-buf API including audition all imports using dma_buf_vmap()... so a lot of work.
So that leaves either drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() or amdgpu. I think drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() is the cleanest and schould have no impact on other drivers.
Regards,
Christian.
>
> Best regards
> Thomas
>
>>
>> Regards,
>> Christian.
>>
>>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>>
>>> Best regards
>>> Thomas
>>>
>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>>
>>>> Best regards
>>>> Thomas
>>>>
>>>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>>>
>>>>
>>>>> Regards,
>>>>> Christian.
>>>>>
>>>>>> Best regards
>>>>>> Thomas
>>>>>>
>>>>>>> Best regards,
>>>>>>> Shixiong
>>>>>>>
>>>>>>>
>>>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>> c1
>>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>> [ 168.922170] Call Trace:
>>>>>>>> [ 168.924616] <TASK>
>>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>>> 00
>>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>>> [ 169.192525] </TASK>
>>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>> c1
>>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>>>> [ 175.343111] ==================================================================
>>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>>>> [ 175.364738]
>>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>>> [ 175.366249] Call Trace:
>>>>>>>> [ 175.366251] <TASK>
>>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>>> [ 175.366459] </TASK>
>>>>>>>> [ 175.366460]
>>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>> [ 175.677014]
>>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>> [ 175.733980]
>>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>>> [ 175.775608]
>>>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>> [ 175.830343]
>>>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>>>> [ 175.856969]
>>>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>>>> [ 175.946283]
>>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>>>> [ 175.974353] ^
>>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>> [ 175.995755] ==================================================================
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>
>>>>>>>>> [WHY]
>>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>>>> sg_table import.
>>>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>>>> kernel virtual address.
>>>>>>>>>
>>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>>>> errors like:
>>>>>>>>>
>>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>>
>>>>>>>>> [HOW]
>>>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>>>> require sg_table can adopt this.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>> ---
>>>>>>>>> v1->v2:
>>>>>>>>> Patch rebase.
>>>>>>>>> v2->v3:
>>>>>>>>> Rename the import callback function.
>>>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>>> v3->v4:
>>>>>>>>> Separate the test from the policy.
>>>>>>>>> Rename the macro.
>>>>>>>>> v4->v5:
>>>>>>>>> Rename some functions.
>>>>>>>>>
>>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>> }
>>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>>> +/**
>>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>>>> + * @dev: Device to import into
>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>> + *
>>>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>>>> + * implementation.
>>>>>>>>> + */
>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>> +{
>>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>>> + size_t size;
>>>>>>>>> + int ret;
>>>>>>>>> +
>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>> + /*
>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>> + */
>>>>>>>>> + obj = dma_buf->priv;
>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>> + return obj;
>>>>>>>>> + }
>>>>>>>>> +
>>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>>> + if (IS_ERR(attach))
>>>>>>>>> + return ERR_CAST(attach);
>>>>>>>>> +
>>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>>> +
>>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>>> +
>>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>>> + goto fail_detach;
>>>>>>>>> + }
>>>>>>>>> +
>>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>>> +
>>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>>> +
>>>>>>>>> + return &shmem->base;
>>>>>>>>> +
>>>>>>>>> +fail_detach:
>>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>>> +
>>>>>>>>> + return ERR_PTR(ret);
>>>>>>>>> +}
>>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>>> +
>>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>> }
>>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>>> +
>>>>>>>>> +/**
>>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>>>> + * @dev: drm_device to check against
>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>> + *
>>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>>>> + * to @dev, false otherwise.
>>>>>>>>> + */
>>>>>>>>> +
>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>> +{
>>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>>> +
>>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>>>> +}
>>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>>> +
>>>>>>>>> /**
>>>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>>>> * @dev: drm_device to import into
>>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>> struct drm_gem_object *obj;
>>>>>>>>> int ret;
>>>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>> + /*
>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>> + */
>>>>>>>>> obj = dma_buf->priv;
>>>>>>>>> - if (obj->dev == dev) {
>>>>>>>>> - /*
>>>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>> - */
>>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>>> - return obj;
>>>>>>>>> - }
>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>> + return obj;
>>>>>>>>> }
>>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>> struct sg_table *sgt);
>>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>> + struct dma_buf *buf);
>>>>>>>>> /**
>>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>> +/**
>>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>>>> + * without mapping sg_table on
>>>>>>>>> + * imported buffer.
>>>>>>>>> + *
>>>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>>>> + * imported buffers.
>>>>>>>>> + */
>>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>> +
>>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>>> /* helper functions for importing */
>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>>> +
>>>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>>> struct device *attach_dev);
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-14 10:22 ` Christian König
@ 2025-08-14 12:51 ` Thomas Zimmermann
2025-08-14 13:16 ` Christian König
0 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-14 12:51 UTC (permalink / raw)
To: Christian König, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi Christian
Am 14.08.25 um 12:22 schrieb Christian König:
> On 13.08.25 16:06, Thomas Zimmermann wrote:
>> Hi
>>
>> Am 13.08.25 um 15:35 schrieb Christian König:
>>> On 13.08.25 14:16, Thomas Zimmermann wrote:
>>>> In addition:
>>>>
>>>>>> Here udl just silently assumes that it got a vaddr, but that isn't necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can return an io addr as well.
>>>>> That's a union of the two pointer types. [1] Using them interchangeably has worked so far (*) and should work here as well. As I said in the other mail, ttm_bo_vmap() never bothers to pin the pages in place and amdgpu might relocated them shortly after.
>>>> AFAICT with the old code we ran dma_buf_pin_on_map() at some point. Could we do this in the new version as well?
>>> Ah, yes that could be it. So basically the buffer moves and because of that the vmap is unmapped.
>>>
>>> It would probably be a good idea to call dma_buf_pin() from drm_gem_dmabuf_vmap() before calling drm_gem_vmap_locked().
>>>
>>> Should be trivial since we already have the dma_buf object and the necessary lock is held as well.
>> The attached patch fixes the problem on my test system. It further integrates well with the existing logic, so changes are minimal. Any comments before I send it out for review?
> Mhm that looks more or less like what I had in mind initially as well, but I was convinced that this is probably not the best idea.
What do you mean by 'convinced'? Was there a review of a previous patch?
>
> We have exposed the dma_buf_pin()/dma_buf_unpin() functions for exactly that use case. So we should probably make use of that.
>
> Either by pinning in the exporter, e.g. drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() or even lower level (amdgpu/ttm) or in the importer.
>
> Not doing it in TTM was intentional since we have use cases where kmap/vmap is only temporary valid until you drop the dma_resv lock again.
>
> Doing it in the importer would be the cleanest approach, but that means changing the semantics of the DMA-buf API including audition all imports using dma_buf_vmap()... so a lot of work.
I don't fully understand your comment. We used to pin these buffer
before. The proposed change is just an extension to the existing
semantics of dma_buf_map_attachment(). Admittedly, I did not check the
full kernel codebase if DMA_NONE is a valid input for any implementation
of map_dma_buf. Would that be valid semantics?
>
> So that leaves either drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() or amdgpu. I think drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() is the cleanest and schould have no impact on other drivers.
If we pull the pin/unpin into gem-shmem helpers, what about that test
with dma_buf_pin_on_map()? Do we need that in gem-shmem as well? [1]
[1]
https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
BTW, I always thought that the dma-buf vmap implementation guarantees
that the buffer won't move. If so, that would imply that
drm_gem_dmabuf_vmap() would be the right place.
Another point to keep in mind is that other drivers besides amdgpu might
also be affected. Most drivers appear to be using
drm_gem_prime_export(), which ends up with drm_gem_dmabuf_vmap(). So a
fix there would benefit them.
Best regards
Thomas
>
> Regards,
> Christian.
>
>> Best regards
>> Thomas
>>
>>> Regards,
>>> Christian.
>>>
>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>>>
>>>> Best regards
>>>> Thomas
>>>>
>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>>>
>>>>> Best regards
>>>>> Thomas
>>>>>
>>>>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>>>>
>>>>>
>>>>>> Regards,
>>>>>> Christian.
>>>>>>
>>>>>>> Best regards
>>>>>>> Thomas
>>>>>>>
>>>>>>>> Best regards,
>>>>>>>> Shixiong
>>>>>>>>
>>>>>>>>
>>>>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>> c1
>>>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>> [ 168.922170] Call Trace:
>>>>>>>>> [ 168.924616] <TASK>
>>>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>>>> 00
>>>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>>>> [ 169.192525] </TASK>
>>>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>> c1
>>>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>>>>> [ 175.343111] ==================================================================
>>>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>>>>> [ 175.364738]
>>>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>>>> [ 175.366249] Call Trace:
>>>>>>>>> [ 175.366251] <TASK>
>>>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>>>> [ 175.366459] </TASK>
>>>>>>>>> [ 175.366460]
>>>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>> [ 175.677014]
>>>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>> [ 175.733980]
>>>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>>>> [ 175.775608]
>>>>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>> [ 175.830343]
>>>>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>>>>> [ 175.856969]
>>>>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>>>>> [ 175.946283]
>>>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>>>>> [ 175.974353] ^
>>>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>> [ 175.995755] ==================================================================
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>
>>>>>>>>>> [WHY]
>>>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>>>>> sg_table import.
>>>>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>>>>> kernel virtual address.
>>>>>>>>>>
>>>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>>>>> errors like:
>>>>>>>>>>
>>>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>>>
>>>>>>>>>> [HOW]
>>>>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>>>>> require sg_table can adopt this.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>> ---
>>>>>>>>>> v1->v2:
>>>>>>>>>> Patch rebase.
>>>>>>>>>> v2->v3:
>>>>>>>>>> Rename the import callback function.
>>>>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>>>> v3->v4:
>>>>>>>>>> Separate the test from the policy.
>>>>>>>>>> Rename the macro.
>>>>>>>>>> v4->v5:
>>>>>>>>>> Rename some functions.
>>>>>>>>>>
>>>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>> }
>>>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>>>> +/**
>>>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>>>>> + * @dev: Device to import into
>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>> + *
>>>>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>>>>> + * implementation.
>>>>>>>>>> + */
>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>> +{
>>>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>>>> + size_t size;
>>>>>>>>>> + int ret;
>>>>>>>>>> +
>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>> + /*
>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>> + */
>>>>>>>>>> + obj = dma_buf->priv;
>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>> + return obj;
>>>>>>>>>> + }
>>>>>>>>>> +
>>>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>>>> + if (IS_ERR(attach))
>>>>>>>>>> + return ERR_CAST(attach);
>>>>>>>>>> +
>>>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>>>> +
>>>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>>>> +
>>>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>>>> + goto fail_detach;
>>>>>>>>>> + }
>>>>>>>>>> +
>>>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>>>> +
>>>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>>>> +
>>>>>>>>>> + return &shmem->base;
>>>>>>>>>> +
>>>>>>>>>> +fail_detach:
>>>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>>>> +
>>>>>>>>>> + return ERR_PTR(ret);
>>>>>>>>>> +}
>>>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>>>> +
>>>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>> }
>>>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>>>> +
>>>>>>>>>> +/**
>>>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>>>>> + * @dev: drm_device to check against
>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>> + *
>>>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>>>>> + * to @dev, false otherwise.
>>>>>>>>>> + */
>>>>>>>>>> +
>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>> +{
>>>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>>>> +
>>>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>>>>> +}
>>>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>>>> +
>>>>>>>>>> /**
>>>>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>>>>> * @dev: drm_device to import into
>>>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>> struct drm_gem_object *obj;
>>>>>>>>>> int ret;
>>>>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>> + /*
>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>> + */
>>>>>>>>>> obj = dma_buf->priv;
>>>>>>>>>> - if (obj->dev == dev) {
>>>>>>>>>> - /*
>>>>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>> - */
>>>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>>>> - return obj;
>>>>>>>>>> - }
>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>> + return obj;
>>>>>>>>>> }
>>>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>> struct sg_table *sgt);
>>>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>> + struct dma_buf *buf);
>>>>>>>>>> /**
>>>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>> +/**
>>>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>>>>> + * without mapping sg_table on
>>>>>>>>>> + * imported buffer.
>>>>>>>>>> + *
>>>>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>>>>> + * imported buffers.
>>>>>>>>>> + */
>>>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>> +
>>>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>>>> /* helper functions for importing */
>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>>>> +
>>>>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>>>> struct device *attach_dev);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-14 12:51 ` Thomas Zimmermann
@ 2025-08-14 13:16 ` Christian König
2025-08-15 12:46 ` Thomas Zimmermann
0 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2025-08-14 13:16 UTC (permalink / raw)
To: Thomas Zimmermann, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
On 14.08.25 14:51, Thomas Zimmermann wrote:
> Hi Christian
>
> Am 14.08.25 um 12:22 schrieb Christian König:
>> On 13.08.25 16:06, Thomas Zimmermann wrote:
>>> Hi
>>>
>>> Am 13.08.25 um 15:35 schrieb Christian König:
>>>> On 13.08.25 14:16, Thomas Zimmermann wrote:
>>>>> In addition:
>>>>>
>>>>>>> Here udl just silently assumes that it got a vaddr, but that isn't necessarily the case. Drivers amdgpu (or radeon, nouveau etc...) can return an io addr as well.
>>>>>> That's a union of the two pointer types. [1] Using them interchangeably has worked so far (*) and should work here as well. As I said in the other mail, ttm_bo_vmap() never bothers to pin the pages in place and amdgpu might relocated them shortly after.
>>>>> AFAICT with the old code we ran dma_buf_pin_on_map() at some point. Could we do this in the new version as well?
>>>> Ah, yes that could be it. So basically the buffer moves and because of that the vmap is unmapped.
>>>>
>>>> It would probably be a good idea to call dma_buf_pin() from drm_gem_dmabuf_vmap() before calling drm_gem_vmap_locked().
>>>>
>>>> Should be trivial since we already have the dma_buf object and the necessary lock is held as well.
>>> The attached patch fixes the problem on my test system. It further integrates well with the existing logic, so changes are minimal. Any comments before I send it out for review?
>> Mhm that looks more or less like what I had in mind initially as well, but I was convinced that this is probably not the best idea.
>
> What do you mean by 'convinced'? Was there a review of a previous patch?
No code, just some chatting with Sima and others about how to handle that.
>>
>> We have exposed the dma_buf_pin()/dma_buf_unpin() functions for exactly that use case. So we should probably make use of that.
>>
>> Either by pinning in the exporter, e.g. drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() or even lower level (amdgpu/ttm) or in the importer.
>>
>> Not doing it in TTM was intentional since we have use cases where kmap/vmap is only temporary valid until you drop the dma_resv lock again.
>>
>> Doing it in the importer would be the cleanest approach, but that means changing the semantics of the DMA-buf API including audition all imports using dma_buf_vmap()... so a lot of work.
>
> I don't fully understand your comment. We used to pin these buffer before. The proposed change is just an extension to the existing semantics of dma_buf_map_attachment(). Admittedly, I did not check the full kernel codebase if DMA_NONE is a valid input for any implementation of map_dma_buf. Would that be valid semantics?
Yeah, exactly that's the point. As far as I know DMA_NONE is only used for debugging. So creating an attachment with DMA_NONE to pin the buffer is just a hack.
>>
>> So that leaves either drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() or amdgpu. I think drm_gem_dmabuf_vmap()/drm_gem_dmabuf_vunmap() is the cleanest and schould have no impact on other drivers.
>
> If we pull the pin/unpin into gem-shmem helpers, what about that test with dma_buf_pin_on_map()? Do we need that in gem-shmem as well? [1]
No, this is basically checking if we can skip the pin for the mapping.
But for vmap we can't skip the pinning when the CPU mapping should last longer than holding the lock (which is the case for DMA-buf, but not the case for TTM).
>
> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>
> BTW, I always thought that the dma-buf vmap implementation guarantees that the buffer won't move. If so, that would imply that drm_gem_dmabuf_vmap() would be the right place.
Good point. This basically means that we should put the pinning into dma_buf_vmap() since it is general DMA-buf semantic that buffers need to be pinned to be vmapped.
> Another point to keep in mind is that other drivers besides amdgpu might also be affected. Most drivers appear to be using drm_gem_prime_export(), which ends up with drm_gem_dmabuf_vmap(). So a fix there would benefit them.
Yeah, good point as well. I quickly checked and Xe and virtgpu seem to have the same problem.
So we indeed need to put it somewhere into common code.
Regards,
Christian.
>
> Best regards
> Thomas
>
>>
>> Regards,
>> Christian.
>>
>>> Best regards
>>> Thomas
>>>
>>>> Regards,
>>>> Christian.
>>>>
>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>>>>
>>>>> Best regards
>>>>> Thomas
>>>>>
>>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>>>>
>>>>>> Best regards
>>>>>> Thomas
>>>>>>
>>>>>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>>>>>
>>>>>>
>>>>>>> Regards,
>>>>>>> Christian.
>>>>>>>
>>>>>>>> Best regards
>>>>>>>> Thomas
>>>>>>>>
>>>>>>>>> Best regards,
>>>>>>>>> Shixiong
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>> c1
>>>>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>> [ 168.922170] Call Trace:
>>>>>>>>>> [ 168.924616] <TASK>
>>>>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>>>>> 00
>>>>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>>>>> [ 169.192525] </TASK>
>>>>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>> c1
>>>>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>>>>>> [ 175.343111] ==================================================================
>>>>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>>>>>> [ 175.364738]
>>>>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>>>>> [ 175.366249] Call Trace:
>>>>>>>>>> [ 175.366251] <TASK>
>>>>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>> [ 175.366459] </TASK>
>>>>>>>>>> [ 175.366460]
>>>>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>> [ 175.677014]
>>>>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>> [ 175.733980]
>>>>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>> [ 175.775608]
>>>>>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>> [ 175.830343]
>>>>>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>>>>>> [ 175.856969]
>>>>>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>>>>>> [ 175.946283]
>>>>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>>>>>> [ 175.974353] ^
>>>>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>> [ 175.995755] ==================================================================
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>
>>>>>>>>>>> [WHY]
>>>>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>>>>>> sg_table import.
>>>>>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>>>>>> kernel virtual address.
>>>>>>>>>>>
>>>>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>>>>>> errors like:
>>>>>>>>>>>
>>>>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>>>>
>>>>>>>>>>> [HOW]
>>>>>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>>>>>> require sg_table can adopt this.
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>> ---
>>>>>>>>>>> v1->v2:
>>>>>>>>>>> Patch rebase.
>>>>>>>>>>> v2->v3:
>>>>>>>>>>> Rename the import callback function.
>>>>>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>>>>> v3->v4:
>>>>>>>>>>> Separate the test from the policy.
>>>>>>>>>>> Rename the macro.
>>>>>>>>>>> v4->v5:
>>>>>>>>>>> Rename some functions.
>>>>>>>>>>>
>>>>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>> }
>>>>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>>>>> +/**
>>>>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>>>>>> + * @dev: Device to import into
>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>> + *
>>>>>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>>>>>> + * implementation.
>>>>>>>>>>> + */
>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>> +{
>>>>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>>>>> + size_t size;
>>>>>>>>>>> + int ret;
>>>>>>>>>>> +
>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>> + /*
>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>> + */
>>>>>>>>>>> + obj = dma_buf->priv;
>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>> + return obj;
>>>>>>>>>>> + }
>>>>>>>>>>> +
>>>>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>>>>> + if (IS_ERR(attach))
>>>>>>>>>>> + return ERR_CAST(attach);
>>>>>>>>>>> +
>>>>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>>>>> +
>>>>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>>>>> +
>>>>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>>>>> + goto fail_detach;
>>>>>>>>>>> + }
>>>>>>>>>>> +
>>>>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>>>>> +
>>>>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>>>>> +
>>>>>>>>>>> + return &shmem->base;
>>>>>>>>>>> +
>>>>>>>>>>> +fail_detach:
>>>>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>>>>> +
>>>>>>>>>>> + return ERR_PTR(ret);
>>>>>>>>>>> +}
>>>>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>>>>> +
>>>>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>> }
>>>>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>>>>> +
>>>>>>>>>>> +/**
>>>>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>>>>>> + * @dev: drm_device to check against
>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>> + *
>>>>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>>>>>> + * to @dev, false otherwise.
>>>>>>>>>>> + */
>>>>>>>>>>> +
>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>> +{
>>>>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>>>>> +
>>>>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>>>>>> +}
>>>>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>>>>> +
>>>>>>>>>>> /**
>>>>>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>>>>>> * @dev: drm_device to import into
>>>>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>> struct drm_gem_object *obj;
>>>>>>>>>>> int ret;
>>>>>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>> + /*
>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>> + */
>>>>>>>>>>> obj = dma_buf->priv;
>>>>>>>>>>> - if (obj->dev == dev) {
>>>>>>>>>>> - /*
>>>>>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>> - */
>>>>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>>>>> - return obj;
>>>>>>>>>>> - }
>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>> + return obj;
>>>>>>>>>>> }
>>>>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>> struct sg_table *sgt);
>>>>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>> + struct dma_buf *buf);
>>>>>>>>>>> /**
>>>>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>> +/**
>>>>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>>>>>> + * without mapping sg_table on
>>>>>>>>>>> + * imported buffer.
>>>>>>>>>>> + *
>>>>>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>>>>>> + * imported buffers.
>>>>>>>>>>> + */
>>>>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>> +
>>>>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>>>>> /* helper functions for importing */
>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>>>>> +
>>>>>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>>>>> struct device *attach_dev);
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-14 13:16 ` Christian König
@ 2025-08-15 12:46 ` Thomas Zimmermann
2025-08-15 13:28 ` Christian König
0 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-15 12:46 UTC (permalink / raw)
To: Christian König, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi Christian
Am 14.08.25 um 15:16 schrieb Christian König:
[...]
>
>
>> Another point to keep in mind is that other drivers besides amdgpu might also be affected. Most drivers appear to be using drm_gem_prime_export(), which ends up with drm_gem_dmabuf_vmap(). So a fix there would benefit them.
> Yeah, good point as well. I quickly checked and Xe and virtgpu seem to have the same problem.
>
> So we indeed need to put it somewhere into common code.
Turns out that fixing this problem is tricky.
1) Putting a pin call into drm_gem_dmabuf_vmap() won't work easily, as
amdgpu does not have a GEM pin callback. Adding one might have side
effects elsewhere.
2) One solution that works is to implement a custom version of dma_buf's
vmap op for amdgpu. It does the pin and unpin around the vmap/vunmap.
But it solves the problem in the wrong place and would require similar
changes in other drivers.
3) Another solution is to call the dma_buf_pin() from GEM-SHMEM's vmap
code. The issue here is that dma_buf_pin() is only for dynamic importers
and GEM-SHMEM is none. Hence this doesn't work easily.
So I took a step back to better understand why the pinning doesn't
happen. Please correct if I got something wrong. The vmap'ing is valid
while the buffer is either pinned or while the caller holds the resv
lock. And neither is the case for udl's imported buffer. With the old
code, pinning happens during import from within drm_gem_map_attach() [1]
or from within dma_buf_map_attachment() [2]. Now, pinning is supposed to
happen during the commit's prepare_fb step, but GEM-SHMEM doesn't
implement this. Amdgpu get's this right. [3]
[1]
https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_prime.c#L617
[2]
https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1116
[3]
https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c#L971
GEM_SHMEM behaves like a dynamic importer, but isn't one. So I think the
best solution for now is to implement dynamic importing for GEM-SHMEM
and do the pinning in drm_gem_shmem_vmap_locked(). [4] This works well
in a prototype fix I have. A later patch series would move the
pinning/unpinning into prepare_fb/cleanup_fb. That requires an update to
each driver using GEM-SHEM, so it needs a separate series.
[4]
https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_gem_shmem_helper.c#L352
Best regards
Thomas
>
> Regards,
> Christian.
>
>> Best regards
>> Thomas
>>
>>> Regards,
>>> Christian.
>>>
>>>> Best regards
>>>> Thomas
>>>>
>>>>> Regards,
>>>>> Christian.
>>>>>
>>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>>>>>
>>>>>> Best regards
>>>>>> Thomas
>>>>>>
>>>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>>>>>
>>>>>>> Best regards
>>>>>>> Thomas
>>>>>>>
>>>>>>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>>>>>>
>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Christian.
>>>>>>>>
>>>>>>>>> Best regards
>>>>>>>>> Thomas
>>>>>>>>>
>>>>>>>>>> Best regards,
>>>>>>>>>> Shixiong
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>> c1
>>>>>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>> [ 168.922170] Call Trace:
>>>>>>>>>>> [ 168.924616] <TASK>
>>>>>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>>>>>> 00
>>>>>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>>>>>> [ 169.192525] </TASK>
>>>>>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>> c1
>>>>>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>>>>>>> [ 175.343111] ==================================================================
>>>>>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>>>>>>> [ 175.364738]
>>>>>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>>>>>> [ 175.366249] Call Trace:
>>>>>>>>>>> [ 175.366251] <TASK>
>>>>>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>> [ 175.366459] </TASK>
>>>>>>>>>>> [ 175.366460]
>>>>>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>> [ 175.677014]
>>>>>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>> [ 175.733980]
>>>>>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>> [ 175.775608]
>>>>>>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>> [ 175.830343]
>>>>>>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>>>>>>> [ 175.856969]
>>>>>>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>>>>>>> [ 175.946283]
>>>>>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>>>>>>> [ 175.974353] ^
>>>>>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>>> [ 175.995755] ==================================================================
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>>
>>>>>>>>>>>> [WHY]
>>>>>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>>>>>>> sg_table import.
>>>>>>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>>>>>>> kernel virtual address.
>>>>>>>>>>>>
>>>>>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>>>>>>> errors like:
>>>>>>>>>>>>
>>>>>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>>>>>
>>>>>>>>>>>> [HOW]
>>>>>>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>>>>>>> require sg_table can adopt this.
>>>>>>>>>>>>
>>>>>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>> ---
>>>>>>>>>>>> v1->v2:
>>>>>>>>>>>> Patch rebase.
>>>>>>>>>>>> v2->v3:
>>>>>>>>>>>> Rename the import callback function.
>>>>>>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>>>>>> v3->v4:
>>>>>>>>>>>> Separate the test from the policy.
>>>>>>>>>>>> Rename the macro.
>>>>>>>>>>>> v4->v5:
>>>>>>>>>>>> Rename some functions.
>>>>>>>>>>>>
>>>>>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>>>>>
>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>> }
>>>>>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>>>>>> +/**
>>>>>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>>>>>>> + * @dev: Device to import into
>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>>>>>>> + * implementation.
>>>>>>>>>>>> + */
>>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>> +{
>>>>>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>>>>>> + size_t size;
>>>>>>>>>>>> + int ret;
>>>>>>>>>>>> +
>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>> + /*
>>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>> + */
>>>>>>>>>>>> + obj = dma_buf->priv;
>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>> + return obj;
>>>>>>>>>>>> + }
>>>>>>>>>>>> +
>>>>>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>>>>>> + if (IS_ERR(attach))
>>>>>>>>>>>> + return ERR_CAST(attach);
>>>>>>>>>>>> +
>>>>>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>>>>>> +
>>>>>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>>>>>> +
>>>>>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>>>>>> + goto fail_detach;
>>>>>>>>>>>> + }
>>>>>>>>>>>> +
>>>>>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>>>>>> +
>>>>>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>>>>>> +
>>>>>>>>>>>> + return &shmem->base;
>>>>>>>>>>>> +
>>>>>>>>>>>> +fail_detach:
>>>>>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>>>>>> +
>>>>>>>>>>>> + return ERR_PTR(ret);
>>>>>>>>>>>> +}
>>>>>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>>>>>> +
>>>>>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>> }
>>>>>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>>>>>> +
>>>>>>>>>>>> +/**
>>>>>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>>>>>>> + * @dev: drm_device to check against
>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>>>>>>> + * to @dev, false otherwise.
>>>>>>>>>>>> + */
>>>>>>>>>>>> +
>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>> +{
>>>>>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>>>>>> +
>>>>>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>>>>>>> +}
>>>>>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>>>>>> +
>>>>>>>>>>>> /**
>>>>>>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>>>>>>> * @dev: drm_device to import into
>>>>>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>> struct drm_gem_object *obj;
>>>>>>>>>>>> int ret;
>>>>>>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>> + /*
>>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>> + */
>>>>>>>>>>>> obj = dma_buf->priv;
>>>>>>>>>>>> - if (obj->dev == dev) {
>>>>>>>>>>>> - /*
>>>>>>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>> - */
>>>>>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>>>>>> - return obj;
>>>>>>>>>>>> - }
>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>> + return obj;
>>>>>>>>>>>> }
>>>>>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>> struct sg_table *sgt);
>>>>>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>> + struct dma_buf *buf);
>>>>>>>>>>>> /**
>>>>>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>>> +/**
>>>>>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>>>>>>> + * without mapping sg_table on
>>>>>>>>>>>> + * imported buffer.
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>>>>>>> + * imported buffers.
>>>>>>>>>>>> + */
>>>>>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>>> +
>>>>>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>>>>>> /* helper functions for importing */
>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>>>>>> +
>>>>>>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>>>>>> struct device *attach_dev);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-15 12:46 ` Thomas Zimmermann
@ 2025-08-15 13:28 ` Christian König
2025-08-15 13:48 ` Thomas Zimmermann
0 siblings, 1 reply; 22+ messages in thread
From: Christian König @ 2025-08-15 13:28 UTC (permalink / raw)
To: Thomas Zimmermann, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
On 15.08.25 14:46, Thomas Zimmermann wrote:
> Hi Christian
>
> Am 14.08.25 um 15:16 schrieb Christian König:
> [...]
>>
>>
>>> Another point to keep in mind is that other drivers besides amdgpu might also be affected. Most drivers appear to be using drm_gem_prime_export(), which ends up with drm_gem_dmabuf_vmap(). So a fix there would benefit them.
>> Yeah, good point as well. I quickly checked and Xe and virtgpu seem to have the same problem.
>>
>> So we indeed need to put it somewhere into common code.
>
> Turns out that fixing this problem is tricky.
>
> 1) Putting a pin call into drm_gem_dmabuf_vmap() won't work easily, as amdgpu does not have a GEM pin callback. Adding one might have side effects elsewhere.
>
> 2) One solution that works is to implement a custom version of dma_buf's vmap op for amdgpu. It does the pin and unpin around the vmap/vunmap. But it solves the problem in the wrong place and would require similar changes in other drivers.
Agree, a driver specific solution is something we should try to avoid.
>
> 3) Another solution is to call the dma_buf_pin() from GEM-SHMEM's vmap code. The issue here is that dma_buf_pin() is only for dynamic importers and GEM-SHMEM is none. Hence this doesn't work easily.
Ah, yes we have a WARN_ON(!attach->importer_ops) in there.
> So I took a step back to better understand why the pinning doesn't happen. Please correct if I got something wrong. The vmap'ing is valid while the buffer is either pinned or while the caller holds the resv lock.
Well, question is which vmap'ing? The problem is that we have different semantics between the TTM vmap and the DMA-buf vmap.
For TTM vmap what you wrote is correct. The vmap stays valid as long as the buffer is either pinned or while the caller hold the resv lock.
For DMA-buf the expectation is that the vmap stays valid until the importer explicitely calls dma_buf_vunmap().
> And neither is the case for udl's imported buffer. With the old code, pinning happens during import from within drm_gem_map_attach() [1] or from within dma_buf_map_attachment() [2]. Now, pinning is supposed to happen during the commit's prepare_fb step, but GEM-SHMEM doesn't implement this. Amdgpu get's this right. [3]
>
Not quite, the problem is that we use the TTM vmap functions to implement the DMA-buf vmap functionality and the two have different semantics and expectations on the caller.
We could define the DMA-buf vmap semantics differently, that might have actually some value, but that is not something I would recommend for a bug fix.
So I think we either need to implementing the GEM pin callbacks for amdgpu or find a different solution.
What if we just add a call to ttm_bo_pin() into drm_gem_ttm_vmap? That is bypassing amdgpus pin logic, but that is not necessarily needed here.
Regards,
Christian.
> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_prime.c#L617
> [2] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1116
> [3] https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c#L971
>
> GEM_SHMEM behaves like a dynamic importer, but isn't one. So I think the best solution for now is to implement dynamic importing for GEM-SHMEM and do the pinning in drm_gem_shmem_vmap_locked(). [4] This works well in a prototype fix I have. A later patch series would move the pinning/unpinning into prepare_fb/cleanup_fb. That requires an update to each driver using GEM-SHEM, so it needs a separate series.
>
> [4] https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_gem_shmem_helper.c#L352
>
> Best regards
> Thomas
>
>
>>
>> Regards,
>> Christian.
>>
>>> Best regards
>>> Thomas
>>>
>>>> Regards,
>>>> Christian.
>>>>
>>>>> Best regards
>>>>> Thomas
>>>>>
>>>>>> Regards,
>>>>>> Christian.
>>>>>>
>>>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>>>>>>
>>>>>>> Best regards
>>>>>>> Thomas
>>>>>>>
>>>>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>>>>>>
>>>>>>>> Best regards
>>>>>>>> Thomas
>>>>>>>>
>>>>>>>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>>>>>>>
>>>>>>>>
>>>>>>>>> Regards,
>>>>>>>>> Christian.
>>>>>>>>>
>>>>>>>>>> Best regards
>>>>>>>>>> Thomas
>>>>>>>>>>
>>>>>>>>>>> Best regards,
>>>>>>>>>>> Shixiong
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>>> c1
>>>>>>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>>> [ 168.922170] Call Trace:
>>>>>>>>>>>> [ 168.924616] <TASK>
>>>>>>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>>>>>>> 00
>>>>>>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>>>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>>>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>>>>>>> [ 169.192525] </TASK>
>>>>>>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>>> c1
>>>>>>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>>>>>>>> [ 175.343111] ==================================================================
>>>>>>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>>>>>>>> [ 175.364738]
>>>>>>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>>>>>>> [ 175.366249] Call Trace:
>>>>>>>>>>>> [ 175.366251] <TASK>
>>>>>>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>>> [ 175.366459] </TASK>
>>>>>>>>>>>> [ 175.366460]
>>>>>>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>>> [ 175.677014]
>>>>>>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>>> [ 175.733980]
>>>>>>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>>> [ 175.775608]
>>>>>>>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>>> [ 175.830343]
>>>>>>>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>>>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>>>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>>>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>>>>>>>> [ 175.856969]
>>>>>>>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>>>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>>>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>>>>>>>> [ 175.946283]
>>>>>>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>>>>>>>> [ 175.974353] ^
>>>>>>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>>>> [ 175.995755] ==================================================================
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>>>
>>>>>>>>>>>>> [WHY]
>>>>>>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>>>>>>>> sg_table import.
>>>>>>>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>>>>>>>> kernel virtual address.
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>>>>>>>> errors like:
>>>>>>>>>>>>>
>>>>>>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>>>>>>
>>>>>>>>>>>>> [HOW]
>>>>>>>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>>>>>>>> require sg_table can adopt this.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>>> ---
>>>>>>>>>>>>> v1->v2:
>>>>>>>>>>>>> Patch rebase.
>>>>>>>>>>>>> v2->v3:
>>>>>>>>>>>>> Rename the import callback function.
>>>>>>>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>>>>>>> v3->v4:
>>>>>>>>>>>>> Separate the test from the policy.
>>>>>>>>>>>>> Rename the macro.
>>>>>>>>>>>>> v4->v5:
>>>>>>>>>>>>> Rename some functions.
>>>>>>>>>>>>>
>>>>>>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>>>>>>
>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>>> }
>>>>>>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>>>>>>> +/**
>>>>>>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>>>>>>>> + * @dev: Device to import into
>>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>>> + *
>>>>>>>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>>>>>>>> + * implementation.
>>>>>>>>>>>>> + */
>>>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>>> +{
>>>>>>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>>>>>>> + size_t size;
>>>>>>>>>>>>> + int ret;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>>> + /*
>>>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>>> + */
>>>>>>>>>>>>> + obj = dma_buf->priv;
>>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>>> + return obj;
>>>>>>>>>>>>> + }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>>>>>>> + if (IS_ERR(attach))
>>>>>>>>>>>>> + return ERR_CAST(attach);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>>>>>>> + goto fail_detach;
>>>>>>>>>>>>> + }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + return &shmem->base;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +fail_detach:
>>>>>>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + return ERR_PTR(ret);
>>>>>>>>>>>>> +}
>>>>>>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>>> }
>>>>>>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +/**
>>>>>>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>>>>>>>> + * @dev: drm_device to check against
>>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>>> + *
>>>>>>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>>>>>>>> + * to @dev, false otherwise.
>>>>>>>>>>>>> + */
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>>> +{
>>>>>>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>>>>>>>> +}
>>>>>>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> /**
>>>>>>>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>>>>>>>> * @dev: drm_device to import into
>>>>>>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>>> struct drm_gem_object *obj;
>>>>>>>>>>>>> int ret;
>>>>>>>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>>> + /*
>>>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>>> + */
>>>>>>>>>>>>> obj = dma_buf->priv;
>>>>>>>>>>>>> - if (obj->dev == dev) {
>>>>>>>>>>>>> - /*
>>>>>>>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>>> - */
>>>>>>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>>>>>>> - return obj;
>>>>>>>>>>>>> - }
>>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>>> + return obj;
>>>>>>>>>>>>> }
>>>>>>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>>> struct sg_table *sgt);
>>>>>>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>>> + struct dma_buf *buf);
>>>>>>>>>>>>> /**
>>>>>>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>>>> +/**
>>>>>>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>>>>>>>> + * without mapping sg_table on
>>>>>>>>>>>>> + * imported buffer.
>>>>>>>>>>>>> + *
>>>>>>>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>>>>>>>> + * imported buffers.
>>>>>>>>>>>>> + */
>>>>>>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>>>> +
>>>>>>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>>>>>>> /* helper functions for importing */
>>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>>>>>>> struct device *attach_dev);
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-15 13:28 ` Christian König
@ 2025-08-15 13:48 ` Thomas Zimmermann
2025-08-18 8:45 ` Thomas Zimmermann
0 siblings, 1 reply; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-15 13:48 UTC (permalink / raw)
To: Christian König, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Hi
Am 15.08.25 um 15:28 schrieb Christian König:
> On 15.08.25 14:46, Thomas Zimmermann wrote:
>> Hi Christian
>>
>> Am 14.08.25 um 15:16 schrieb Christian König:
>> [...]
>>>
>>>> Another point to keep in mind is that other drivers besides amdgpu might also be affected. Most drivers appear to be using drm_gem_prime_export(), which ends up with drm_gem_dmabuf_vmap(). So a fix there would benefit them.
>>> Yeah, good point as well. I quickly checked and Xe and virtgpu seem to have the same problem.
>>>
>>> So we indeed need to put it somewhere into common code.
>> Turns out that fixing this problem is tricky.
>>
>> 1) Putting a pin call into drm_gem_dmabuf_vmap() won't work easily, as amdgpu does not have a GEM pin callback. Adding one might have side effects elsewhere.
>>
>> 2) One solution that works is to implement a custom version of dma_buf's vmap op for amdgpu. It does the pin and unpin around the vmap/vunmap. But it solves the problem in the wrong place and would require similar changes in other drivers.
> Agree, a driver specific solution is something we should try to avoid.
>
>> 3) Another solution is to call the dma_buf_pin() from GEM-SHMEM's vmap code. The issue here is that dma_buf_pin() is only for dynamic importers and GEM-SHMEM is none. Hence this doesn't work easily.
> Ah, yes we have a WARN_ON(!attach->importer_ops) in there.
>
>> So I took a step back to better understand why the pinning doesn't happen. Please correct if I got something wrong. The vmap'ing is valid while the buffer is either pinned or while the caller holds the resv lock.
> Well, question is which vmap'ing? The problem is that we have different semantics between the TTM vmap and the DMA-buf vmap.
>
> For TTM vmap what you wrote is correct. The vmap stays valid as long as the buffer is either pinned or while the caller hold the resv lock.
>
> For DMA-buf the expectation is that the vmap stays valid until the importer explicitely calls dma_buf_vunmap().
OK, I see. This has not been implemented correctly in the case of most
TTM-based drivers. It's just the the pinning happens at import time, so
we never noticed.
>
>> And neither is the case for udl's imported buffer. With the old code, pinning happens during import from within drm_gem_map_attach() [1] or from within dma_buf_map_attachment() [2]. Now, pinning is supposed to happen during the commit's prepare_fb step, but GEM-SHMEM doesn't implement this. Amdgpu get's this right. [3]
>>
> Not quite, the problem is that we use the TTM vmap functions to implement the DMA-buf vmap functionality and the two have different semantics and expectations on the caller.
>
> We could define the DMA-buf vmap semantics differently, that might have actually some value, but that is not something I would recommend for a bug fix.
Agreed.
>
> So I think we either need to implementing the GEM pin callbacks for amdgpu or find a different solution.
>
> What if we just add a call to ttm_bo_pin() into drm_gem_ttm_vmap? That is bypassing amdgpus pin logic, but that is not necessarily needed here.
Makes sense to me. I'll go with my option 2 then: implement a custom
dma-buf vmap for amdgpu. It's pin + vmap and trivial. We don't even have
to care about the location of the BO as long as it's vmap-able. Given
your comment on semantics, this is the correct solution. I have a
prototype patch that works already and I'll go through the other
TTM-based drivers as well.
Best regards
Thomas
>
> Regards,
> Christian.
>
>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_prime.c#L617
>> [2] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1116
>> [3] https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c#L971
>>
>> GEM_SHMEM behaves like a dynamic importer, but isn't one. So I think the best solution for now is to implement dynamic importing for GEM-SHMEM and do the pinning in drm_gem_shmem_vmap_locked(). [4] This works well in a prototype fix I have. A later patch series would move the pinning/unpinning into prepare_fb/cleanup_fb. That requires an update to each driver using GEM-SHEM, so it needs a separate series.
>>
>> [4] https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_gem_shmem_helper.c#L352
>>
>> Best regards
>> Thomas
>>
>>
>>> Regards,
>>> Christian.
>>>
>>>> Best regards
>>>> Thomas
>>>>
>>>>> Regards,
>>>>> Christian.
>>>>>
>>>>>> Best regards
>>>>>> Thomas
>>>>>>
>>>>>>> Regards,
>>>>>>> Christian.
>>>>>>>
>>>>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>>>>>>>
>>>>>>>> Best regards
>>>>>>>> Thomas
>>>>>>>>
>>>>>>>>> [1] https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>>>>>>>
>>>>>>>>> Best regards
>>>>>>>>> Thomas
>>>>>>>>>
>>>>>>>>> (*) White lie: we had problems on exotic architectures, such as sparc, but never on x86.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> Regards,
>>>>>>>>>> Christian.
>>>>>>>>>>
>>>>>>>>>>> Best regards
>>>>>>>>>>> Thomas
>>>>>>>>>>>
>>>>>>>>>>>> Best regards,
>>>>>>>>>>>> Shixiong
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>> [ 168.785445] BUG: unable to handle page fault for address: ffffc9012b800000
>>>>>>>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS thread Tainted: G E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>>>>>>>> [ 168.827458] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>>>> c1
>>>>>>>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>>>> [ 168.887046] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>>>> [ 168.922170] Call Trace:
>>>>>>>>>>>>> [ 168.924616] <TASK>
>>>>>>>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>>>>>>>> [ 168.957077] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>>>> [ 168.962721] udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>>>>>>>> [ 168.969145] ? __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>>>>>>>> [ 168.980357] ? drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>>>>>>>> [ 168.987044] ? drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>>>>>>>> 00
>>>>>>>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
>>>>>>>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX: 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI: 00000000c03864bc RDI: 0000000000000010
>>>>>>>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08: 0000000000001310 R09: 00007f465c044cf0
>>>>>>>>>>>>> [ 169.178194] R10: 0000000000000002 R11: 0000000000000246 R12: 00000000c03864bc
>>>>>>>>>>>>> [ 169.185358] R13: 0000000000000010 R14: 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>>>>>>>> [ 169.192525] </TASK>
>>>>>>>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E) nf_tables(E) iptable_filter(E) binfmt_misc(E) intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E) asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E) snd_hda_codec_generic(E) sparse_keymap(E) x86_pkg_temp_thermal(E) iTCO_vendor_support(E) snd_hda_scodec_component(
>>>>>>>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E) platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E) battery(E) snd_hda_intel(E) i2c_smbus(E) snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E) intel_wmi_thunder
>>>>>>>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E) snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E) acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E) nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E) i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E) hid_generic(E)
>>>>>>>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E) ghash_clmulni_intel(E) sha512_ssse3(E) video(E) sha1_ssse3(E) aesni_intel(E) usbhid(E) drm_panel_backlight_quirks(E) drm_buddy(E) drm_display_helper(E) cec(E) w
>>>>>>>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E) msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940 [udl]
>>>>>>>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>>>> c1
>>>>>>>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX: 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08: ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>>>> [ 169.485800] R10: 0000000000000002 R11: ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14: ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000) GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>>>>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3: 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs disabled
>>>>>>>>>>>>> [ 175.343111] ==================================================================
>>>>>>>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by task kworker/5:0/49
>>>>>>>>>>>>> [ 175.364738]
>>>>>>>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0 Tainted: G D E 6.16.0-rc5-1-default+ #4080 PREEMPT(voluntary)
>>>>>>>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>>>>>>>> [ 175.366242] Hardware name: System manufacturer System Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>>>>>>>> [ 175.366249] Call Trace:
>>>>>>>>>>>>> [ 175.366251] <TASK>
>>>>>>>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>> [ 175.366261] print_address_description.constprop.0+0x88/0x380
>>>>>>>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>>>>>>>> [ 175.366316] ? __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>>>>>>>> [ 175.366366] ? __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>>>>>>>> [ 175.366375] ? __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>> [ 175.366439] ? lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>>>> [ 175.366459] </TASK>
>>>>>>>>>>>>> [ 175.366460]
>>>>>>>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>>>> [ 175.677014]
>>>>>>>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>>>> [ 175.733980]
>>>>>>>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>>>> [ 175.775608]
>>>>>>>>>>>>> [ 175.777113] Second to last potentially related work creation:
>>>>>>>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>>>> [ 175.830343]
>>>>>>>>>>>>> [ 175.831849] The buggy address belongs to the object at ffff8881172dafc0
>>>>>>>>>>>>> [ 175.831849] which belongs to the cache task_struct of size 11968
>>>>>>>>>>>>> [ 175.844582] The buggy address is located 52 bytes inside of
>>>>>>>>>>>>> [ 175.844582] freed 11968-byte region [ffff8881172dafc0, ffff8881172dde80)
>>>>>>>>>>>>> [ 175.856969]
>>>>>>>>>>>>> [ 175.858474] The buggy address belongs to the physical page:
>>>>>>>>>>>>> [ 175.864070] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
>>>>>>>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>>>>>>>> [ 175.883209] anon flags: 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500 0000000000000000 0000000000000001
>>>>>>>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002 00000000f5000000 ffff88811068a301
>>>>>>>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601 00000000ffffffff 00000000ffffffff
>>>>>>>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
>>>>>>>>>>>>> [ 175.940685] page dumped because: kasan: bad access detected
>>>>>>>>>>>>> [ 175.946283]
>>>>>>>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>>>>>>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>>>>>>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
>>>>>>>>>>>>> [ 175.974353] ^
>>>>>>>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>>>>>>>>>>>> [ 175.995755] ==================================================================
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> [WHY]
>>>>>>>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do not require
>>>>>>>>>>>>>> sg_table import.
>>>>>>>>>>>>>> They only need dma_buf_vmap() to access the shared buffer's
>>>>>>>>>>>>>> kernel virtual address.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of 0xffff_ffff may
>>>>>>>>>>>>>> trigger SWIOTLB during dmabuf import. However, IO_TLB_SEGSIZE
>>>>>>>>>>>>>> restricts the maximum DMA streaming mapping memory, resulting in
>>>>>>>>>>>>>> errors like:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz: 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> [HOW]
>>>>>>>>>>>>>> Provide a gem_prime_import implementation without sg_table mapping
>>>>>>>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full"). Drivers that do not
>>>>>>>>>>>>>> require sg_table can adopt this.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>> v1->v2:
>>>>>>>>>>>>>> Patch rebase.
>>>>>>>>>>>>>> v2->v3:
>>>>>>>>>>>>>> Rename the import callback function.
>>>>>>>>>>>>>> Remove drm_gem_shmem_prime_export() and separate some codes
>>>>>>>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>>>>>>>> v3->v4:
>>>>>>>>>>>>>> Separate the test from the policy.
>>>>>>>>>>>>>> Rename the macro.
>>>>>>>>>>>>>> v4->v5:
>>>>>>>>>>>>>> Rename some functions.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57 ++++++++++++++++++++++++++
>>>>>>>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>>> @@ -800,6 +800,63 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>>>>>>>> +/**
>>>>>>>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
>>>>>>>>>>>>>> + * @dev: Device to import into
>>>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>>>> + *
>>>>>>>>>>>>>> + * Drivers that use the shmem helpers but also wants to import dmabuf without
>>>>>>>>>>>>>> + * mapping its sg_table can use this as their &drm_driver.gem_prime_import
>>>>>>>>>>>>>> + * implementation.
>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>>>> +{
>>>>>>>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>>>>>>>> + size_t size;
>>>>>>>>>>>>>> + int ret;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>>>> + /*
>>>>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>> + obj = dma_buf->priv;
>>>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>>>> + return obj;
>>>>>>>>>>>>>> + }
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>>>>>>>> + if (IS_ERR(attach))
>>>>>>>>>>>>>> + return ERR_CAST(attach);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>>>>>>>> + goto fail_detach;
>>>>>>>>>>>>>> + }
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + return &shmem->base;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +fail_detach:
>>>>>>>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + return ERR_PTR(ret);
>>>>>>>>>>>>>> +}
>>>>>>>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
>>>>>>>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +/**
>>>>>>>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object belonging to @dev.
>>>>>>>>>>>>>> + * @dev: drm_device to check against
>>>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>>>> + *
>>>>>>>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM object belonging
>>>>>>>>>>>>>> + * to @dev, false otherwise.
>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>>>> +{
>>>>>>>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops) && (obj->dev == dev);
>>>>>>>>>>>>>> +}
>>>>>>>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> /**
>>>>>>>>>>>>>> * drm_gem_prime_import_dev - core implementation of the import callback
>>>>>>>>>>>>>> * @dev: drm_device to import into
>>>>>>>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>>>> struct drm_gem_object *obj;
>>>>>>>>>>>>>> int ret;
>>>>>>>>>>>>>> - if (dma_buf->ops == &drm_gem_prime_dmabuf_ops) {
>>>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>>>> + /*
>>>>>>>>>>>>>> + * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>>>> + * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>> obj = dma_buf->priv;
>>>>>>>>>>>>>> - if (obj->dev == dev) {
>>>>>>>>>>>>>> - /*
>>>>>>>>>>>>>> - * Importing dmabuf exported from our own gem increases
>>>>>>>>>>>>>> - * refcount on gem itself instead of f_count of dmabuf.
>>>>>>>>>>>>>> - */
>>>>>>>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>>>>>>>> - return obj;
>>>>>>>>>>>>>> - }
>>>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>>>> + return obj;
>>>>>>>>>>>>>> }
>>>>>>>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>>> @@ -287,6 +287,8 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>>>> struct sg_table *sgt);
>>>>>>>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>>>>> struct drm_mode_create_dumb *args);
>>>>>>>>>>>>>> +struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>>>> + struct dma_buf *buf);
>>>>>>>>>>>>>> /**
>>>>>>>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
>>>>>>>>>>>>>> @@ -298,4 +300,17 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
>>>>>>>>>>>>>> .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, \
>>>>>>>>>>>>>> .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>>>>> +/**
>>>>>>>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM operations
>>>>>>>>>>>>>> + * without mapping sg_table on
>>>>>>>>>>>>>> + * imported buffer.
>>>>>>>>>>>>>> + *
>>>>>>>>>>>>>> + * This macro provides a shortcut for setting the shmem GEM operations in
>>>>>>>>>>>>>> + * the &drm_driver structure for drivers that do not require a sg_table on
>>>>>>>>>>>>>> + * imported buffers.
>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>>>>>>>> + .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
>>>>>>>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>>>>>>>> diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
>>>>>>>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>>>> unsigned long drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>>>>>>>> /* helper functions for importing */
>>>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct drm_device *dev,
>>>>>>>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>>>>>>>> +
>>>>>>>>>>>>>> struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>>>>>>>> struct device *attach_dev);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table
2025-08-15 13:48 ` Thomas Zimmermann
@ 2025-08-18 8:45 ` Thomas Zimmermann
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Zimmermann @ 2025-08-18 8:45 UTC (permalink / raw)
To: Christian König, Shixiong Ou
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
Sean Paul, Jocelyn Falempe, dri-devel, linux-kernel, Shixiong Ou
Am 15.08.25 um 15:48 schrieb Thomas Zimmermann:
> Makes sense to me. I'll go with my option 2 then: implement a custom
> dma-buf vmap for amdgpu. It's pin + vmap and trivial. We don't even
> have to care about the location of the BO as long as it's vmap-able.
> Given your comment on semantics, this is the correct solution. I have
> a prototype patch that works already and I'll go through the other
> TTM-based drivers as well.
Patch is at
https://lore.kernel.org/dri-devel/20250818084148.212443-1-tzimmermann@suse.de/
>
> Best regards
> Thomas
>
>>
>> Regards,
>> Christian.
>>
>>> [1]
>>> https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_prime.c#L617
>>> [2]
>>> https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1116
>>> [3]
>>> https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c#L971
>>>
>>> GEM_SHMEM behaves like a dynamic importer, but isn't one. So I think
>>> the best solution for now is to implement dynamic importing for
>>> GEM-SHMEM and do the pinning in drm_gem_shmem_vmap_locked(). [4]
>>> This works well in a prototype fix I have. A later patch series
>>> would move the pinning/unpinning into prepare_fb/cleanup_fb. That
>>> requires an update to each driver using GEM-SHEM, so it needs a
>>> separate series.
>>>
>>> [4]
>>> https://elixir.bootlin.com/linux/v6.16/source/drivers/gpu/drm/drm_gem_shmem_helper.c#L352
>>>
>>> Best regards
>>> Thomas
>>>
>>>
>>>> Regards,
>>>> Christian.
>>>>
>>>>> Best regards
>>>>> Thomas
>>>>>
>>>>>> Regards,
>>>>>> Christian.
>>>>>>
>>>>>>> Best regards
>>>>>>> Thomas
>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Christian.
>>>>>>>>
>>>>>>>>> [1]
>>>>>>>>> https://elixir.bootlin.com/linux/v6.16/source/drivers/dma-buf/dma-buf.c#L1115
>>>>>>>>>
>>>>>>>>> Best regards
>>>>>>>>> Thomas
>>>>>>>>>
>>>>>>>>>> [1]
>>>>>>>>>> https://elixir.bootlin.com/linux/v6.16/source/include/linux/iosys-map.h#L110
>>>>>>>>>>
>>>>>>>>>> Best regards
>>>>>>>>>> Thomas
>>>>>>>>>>
>>>>>>>>>> (*) White lie: we had problems on exotic architectures, such
>>>>>>>>>> as sparc, but never on x86.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> Regards,
>>>>>>>>>>> Christian.
>>>>>>>>>>>
>>>>>>>>>>>> Best regards
>>>>>>>>>>>> Thomas
>>>>>>>>>>>>
>>>>>>>>>>>>> Best regards,
>>>>>>>>>>>>> Shixiong
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> [ 168.785445] BUG: unable to handle page fault for
>>>>>>>>>>>>>> address: ffffc9012b800000
>>>>>>>>>>>>>> [ 168.792311] #PF: supervisor read access in kernel mode
>>>>>>>>>>>>>> [ 168.797452] #PF: error_code(0x0000) - not-present page
>>>>>>>>>>>>>> [ 168.802586] PGD 100000067 P4D 100000067 PUD 0
>>>>>>>>>>>>>> [ 168.807042] Oops: Oops: 0000 [#1] SMP KASAN PTI
>>>>>>>>>>>>>> [ 168.811573] CPU: 2 UID: 1000 PID: 2380 Comm: KMS
>>>>>>>>>>>>>> thread Tainted: G E 6.16.0-rc5-1-default+
>>>>>>>>>>>>>> #4080 PREEMPT(voluntary)
>>>>>>>>>>>>>> [ 168.823537] Tainted: [E]=UNSIGNED_MODULE
>>>>>>>>>>>>>> [ 168.827458] Hardware name: System manufacturer System
>>>>>>>>>>>>>> Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>>>>> [ 168.836125] RIP: 0010:udl_compress_hline16+0x219/0x940
>>>>>>>>>>>>>> [udl]
>>>>>>>>>>>>>> [ 168.841779] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0
>>>>>>>>>>>>>> 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0
>>>>>>>>>>>>>> 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24
>>>>>>>>>>>>>> 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>>>>> c1
>>>>>>>>>>>>>> [ 168.860476] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>>>>> [ 168.865697] RAX: 0000000000000003 RBX:
>>>>>>>>>>>>>> 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>>>>> [ 168.872815] RDX: 0000000000000000 RSI:
>>>>>>>>>>>>>> 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>>>>> [ 168.879934] RBP: dffffc0000000000 R08:
>>>>>>>>>>>>>> ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>>>>> [ 168.887046] R10: 0000000000000002 R11:
>>>>>>>>>>>>>> ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>>>>> [ 168.894155] R13: ffffc9012b800400 R14:
>>>>>>>>>>>>>> ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>>>>> [ 168.901266] FS: 00007f4685f3b6c0(0000)
>>>>>>>>>>>>>> GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>>>>> [ 168.909330] CS: 0010 DS: 0000 ES: 0000 CR0:
>>>>>>>>>>>>>> 0000000080050033
>>>>>>>>>>>>>> [ 168.915058] CR2: ffffc9012b800000 CR3:
>>>>>>>>>>>>>> 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>>>>> [ 168.922170] Call Trace:
>>>>>>>>>>>>>> [ 168.924616] <TASK>
>>>>>>>>>>>>>> [ 168.926714] ? validate_chain+0x24e/0x5e0
>>>>>>>>>>>>>> [ 168.930718] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>>>>> [ 168.934725] udl_render_hline+0x165/0x33b [udl]
>>>>>>>>>>>>>> [ 168.939256] ? __pfx_udl_render_hline+0x10/0x10 [udl]
>>>>>>>>>>>>>> [ 168.944297] ? local_clock_noinstr+0xb/0x100
>>>>>>>>>>>>>> [ 168.948557] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>>>>> [ 168.953162] ? mark_held_locks+0x40/0x70
>>>>>>>>>>>>>> [ 168.957077] ?
>>>>>>>>>>>>>> lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>>>>> [ 168.962721]
>>>>>>>>>>>>>> udl_primary_plane_helper_atomic_update+0x432/0x670 [udl]
>>>>>>>>>>>>>> [ 168.969145] ?
>>>>>>>>>>>>>> __pfx_udl_primary_plane_helper_atomic_update+0x10/0x10 [udl]
>>>>>>>>>>>>>> [ 168.976089] ? __pfx___drm_dev_dbg+0x10/0x10
>>>>>>>>>>>>>> [ 168.980357] ?
>>>>>>>>>>>>>> drm_atomic_helper_calc_timestamping_constants+0x141/0x200
>>>>>>>>>>>>>> [ 168.987044] ?
>>>>>>>>>>>>>> drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>>>>> [ 168.992599] drm_atomic_helper_commit_planes+0x3b6/0x1030
>>>>>>>>>>>>>> [ 168.997987] drm_atomic_helper_commit_tail+0x41/0xb0
>>>>>>>>>>>>>> [ 169.002943] commit_tail+0x204/0x330
>>>>>>>>>>>>>> [ 169.006513] drm_atomic_helper_commit+0x242/0x2e0
>>>>>>>>>>>>>> [ 169.011203] ? __pfx_drm_atomic_helper_commit+0x10/0x10
>>>>>>>>>>>>>> [ 169.016413] drm_atomic_commit+0x1e1/0x290
>>>>>>>>>>>>>> [ 169.020500] ? prepare_signaling+0x355/0xda0
>>>>>>>>>>>>>> [ 169.024769] ? __pfx_drm_atomic_commit+0x10/0x10
>>>>>>>>>>>>>> [ 169.029372] ? __pfx___drm_printfn_info+0x10/0x10
>>>>>>>>>>>>>> [ 169.034069] drm_mode_atomic_ioctl+0x8ff/0xe40
>>>>>>>>>>>>>> [ 169.038510] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>>> [ 169.043466] ? find_held_lock+0x2b/0x80
>>>>>>>>>>>>>> [ 169.047295] ? __lock_acquire+0x568/0xae0
>>>>>>>>>>>>>> [ 169.051293] ? mark_usage+0x65/0x180
>>>>>>>>>>>>>> [ 169.054870] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>>> [ 169.059823] ? do_raw_spin_unlock+0x55/0x230
>>>>>>>>>>>>>> [ 169.064081] ? drm_is_current_master+0x26/0x30
>>>>>>>>>>>>>> [ 169.068517] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>>> [ 169.073465] drm_ioctl_kernel+0x141/0x2b0
>>>>>>>>>>>>>> [ 169.077468] ? __pfx_drm_ioctl_kernel+0x10/0x10
>>>>>>>>>>>>>> [ 169.081987] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>>>>> [ 169.086249] drm_ioctl+0x481/0xb50
>>>>>>>>>>>>>> [ 169.089653] ? __pfx_drm_mode_atomic_ioctl+0x10/0x10
>>>>>>>>>>>>>> [ 169.094610] ? __pfx_drm_ioctl+0x10/0x10
>>>>>>>>>>>>>> [ 169.098525] ? find_held_lock+0x2b/0x80
>>>>>>>>>>>>>> [ 169.102356] ? lock_release.part.0+0x47/0x90
>>>>>>>>>>>>>> [ 169.106621] ? __fget_files+0x1aa/0x2f0
>>>>>>>>>>>>>> [ 169.110450] ? __fget_files+0x1b4/0x2f0
>>>>>>>>>>>>>> [ 169.114281] __x64_sys_ioctl+0x135/0x1c0
>>>>>>>>>>>>>> [ 169.118201] do_syscall_64+0x68/0x2a0
>>>>>>>>>>>>>> [ 169.121856] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>>>>> [ 169.126892] RIP: 0033:0x7f469391a53f
>>>>>>>>>>>>>> [ 169.130460] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24
>>>>>>>>>>>>>> 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48
>>>>>>>>>>>>>> 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff
>>>>>>>>>>>>>> 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00
>>>>>>>>>>>>>> 00
>>>>>>>>>>>>>> [ 169.149151] RSP: 002b:00007f4685f39a80 EFLAGS:
>>>>>>>>>>>>>> 00000246 ORIG_RAX: 0000000000000010
>>>>>>>>>>>>>> [ 169.156703] RAX: ffffffffffffffda RBX:
>>>>>>>>>>>>>> 00007f465c002da0 RCX: 00007f469391a53f
>>>>>>>>>>>>>> [ 169.163868] RDX: 00007f4685f39b20 RSI:
>>>>>>>>>>>>>> 00000000c03864bc RDI: 0000000000000010
>>>>>>>>>>>>>> [ 169.171029] RBP: 00007f4685f39b20 R08:
>>>>>>>>>>>>>> 0000000000001310 R09: 00007f465c044cf0
>>>>>>>>>>>>>> [ 169.178194] R10: 0000000000000002 R11:
>>>>>>>>>>>>>> 0000000000000246 R12: 00000000c03864bc
>>>>>>>>>>>>>> [ 169.185358] R13: 0000000000000010 R14:
>>>>>>>>>>>>>> 00007f465c0284b0 R15: 00007f45d402b110
>>>>>>>>>>>>>> [ 169.192525] </TASK>
>>>>>>>>>>>>>> [ 169.194732] Modules linked in: udl(E) snd_seq_dummy(E)
>>>>>>>>>>>>>> snd_hrtimer(E) snd_seq(E) snd_seq_device(E) af_packet(E)
>>>>>>>>>>>>>> nf_tables(E) iptable_filter(E) binfmt_misc(E)
>>>>>>>>>>>>>> intel_rapl_msr(E) nls_iso8859_1(E) eeepc_wmi(E) nls
>>>>>>>>>>>>>> _cp437(E) intel_rapl_common(E) snd_hda_codec_realtek(E)
>>>>>>>>>>>>>> asus_wmi(E) iTCO_wdt(E) vfat(E) ee1004(E)
>>>>>>>>>>>>>> snd_hda_codec_generic(E) sparse_keymap(E)
>>>>>>>>>>>>>> x86_pkg_temp_thermal(E) iTCO_vendor_support(E)
>>>>>>>>>>>>>> snd_hda_scodec_component(
>>>>>>>>>>>>>> E) intel_powerclamp(E) snd_hda_codec_hdmi(E)
>>>>>>>>>>>>>> platform_profile(E) fat(E) e1000e(E) i2c_i801(E) ptp(E)
>>>>>>>>>>>>>> battery(E) snd_hda_intel(E) i2c_smbus(E)
>>>>>>>>>>>>>> snd_intel_dspcfg(E) mxm_wmi(E) rfkill(E) wmi_bmof(E)
>>>>>>>>>>>>>> intel_wmi_thunder
>>>>>>>>>>>>>> bolt(E) coretemp(E) pps_core(E) i2c_mux(E) pcspkr(E)
>>>>>>>>>>>>>> snd_hda_codec(E) xfs(E) snd_hda_core(E) snd_hwdep(E)
>>>>>>>>>>>>>> snd_pcm(E) snd_timer(E) snd(E) soundcore(E) mei_me(E)
>>>>>>>>>>>>>> acpi_pad(E) button(E) mei(E) joydev(E) nvme_fabrics(
>>>>>>>>>>>>>> E) loop(E) fuse(E) efi_pstore(E) dm_mod(E) configfs(E)
>>>>>>>>>>>>>> nfnetlink(E) ip_tables(E) x_tables(E) amdgpu(E) amdxcp(E)
>>>>>>>>>>>>>> i2c_algo_bit(E) drm_ttm_helper(E) ttm(E) drm_exec(E)
>>>>>>>>>>>>>> hid_generic(E)
>>>>>>>>>>>>>> [ 169.194874] gpu_sched(E) drm_suballoc_helper(E)
>>>>>>>>>>>>>> ghash_clmulni_intel(E) sha512_ssse3(E) video(E)
>>>>>>>>>>>>>> sha1_ssse3(E) aesni_intel(E) usbhid(E)
>>>>>>>>>>>>>> drm_panel_backlight_quirks(E) drm_buddy(E)
>>>>>>>>>>>>>> drm_display_helper(E) cec(E) w
>>>>>>>>>>>>>> mi(E) btrfs(E) blake2b_generic(E) xor(E) raid6_pq(E)
>>>>>>>>>>>>>> msr(E) i2c_dev(E) efivarfs(E) dmi_sysfs(E)
>>>>>>>>>>>>>> [ 169.311501] CR2: ffffc9012b800000
>>>>>>>>>>>>>> [ 169.314835] ---[ end trace 0000000000000000 ]---
>>>>>>>>>>>>>> [ 169.434549] RIP: 0010:udl_compress_hline16+0x219/0x940
>>>>>>>>>>>>>> [udl]
>>>>>>>>>>>>>> [ 169.440237] Code: 0f b6 34 28 4c 89 d8 49 d3 e5 83 e0
>>>>>>>>>>>>>> 07 4d 01 dd 83 f9 01 0f 84 4a 03 00 00 83 c0 03 40 38 f0
>>>>>>>>>>>>>> 7c 09 40 84 f6 0f 85 82 05 00 00 <41> 8b 03 4c 63 7c 24
>>>>>>>>>>>>>> 78 4c 89 5c 24 08 89 c6 41 89 c4 c1 e8 08
>>>>>>>>>>>>>> c1
>>>>>>>>>>>>>> [ 169.459062] RSP: 0018:ffff88811c7e75c0 EFLAGS: 00010246
>>>>>>>>>>>>>> [ 169.464309] RAX: 0000000000000003 RBX:
>>>>>>>>>>>>>> 0000000000000000 RCX: 0000000000000002
>>>>>>>>>>>>>> [ 169.471474] RDX: 0000000000000000 RSI:
>>>>>>>>>>>>>> 0000000000000000 RDI: 0000000000000100
>>>>>>>>>>>>>> [ 169.478635] RBP: dffffc0000000000 R08:
>>>>>>>>>>>>>> ffff8881082efe00 R09: ffff8881082e0000
>>>>>>>>>>>>>> [ 169.485800] R10: 0000000000000002 R11:
>>>>>>>>>>>>>> ffffc9012b800000 R12: ffff88811c7e76f8
>>>>>>>>>>>>>> [ 169.492962] R13: ffffc9012b800400 R14:
>>>>>>>>>>>>>> ffff8881082e0007 R15: 0000000000000000
>>>>>>>>>>>>>> [ 169.500126] FS: 00007f4685f3b6c0(0000)
>>>>>>>>>>>>>> GS:ffff88846c690000(0000) knlGS:0000000000000000
>>>>>>>>>>>>>> [ 169.508246] CS: 0010 DS: 0000 ES: 0000 CR0:
>>>>>>>>>>>>>> 0000000080050033
>>>>>>>>>>>>>> [ 169.514014] CR2: ffffc9012b800000 CR3:
>>>>>>>>>>>>>> 0000000117944004 CR4: 00000000003706f0
>>>>>>>>>>>>>> [ 169.521180] note: KMS thread[2380] exited with irqs
>>>>>>>>>>>>>> disabled
>>>>>>>>>>>>>> [ 175.343111]
>>>>>>>>>>>>>> ==================================================================
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> [ 175.350342] BUG: KASAN: slab-use-after-free in
>>>>>>>>>>>>>> mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>>> [ 175.357886] Read of size 4 at addr ffff8881172daff4 by
>>>>>>>>>>>>>> task kworker/5:0/49
>>>>>>>>>>>>>> [ 175.364738]
>>>>>>>>>>>>>> [ 175.366235] CPU: 5 UID: 0 PID: 49 Comm: kworker/5:0
>>>>>>>>>>>>>> Tainted: G D E 6.16.0-rc5-1-default+ #4080
>>>>>>>>>>>>>> PREEMPT(voluntary)
>>>>>>>>>>>>>> [ 175.366240] Tainted: [D]=DIE, [E]=UNSIGNED_MODULE
>>>>>>>>>>>>>> [ 175.366242] Hardware name: System manufacturer System
>>>>>>>>>>>>>> Product Name/Z170-A, BIOS 3802 03/15/2018
>>>>>>>>>>>>>> [ 175.366244] Workqueue: events output_poll_execute
>>>>>>>>>>>>>> [ 175.366249] Call Trace:
>>>>>>>>>>>>>> [ 175.366251] <TASK>
>>>>>>>>>>>>>> [ 175.366254] dump_stack_lvl+0x68/0x90
>>>>>>>>>>>>>> [ 175.366259] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>>> [ 175.366261]
>>>>>>>>>>>>>> print_address_description.constprop.0+0x88/0x380
>>>>>>>>>>>>>> [ 175.366266] ? lock_acquire+0xf2/0x140
>>>>>>>>>>>>>> [ 175.366269] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>>> [ 175.366272] print_report+0xf8/0x1e2
>>>>>>>>>>>>>> [ 175.366275] ? __virt_addr_valid+0x22e/0x500
>>>>>>>>>>>>>> [ 175.366279] ? kasan_addr_to_slab+0x9/0x90
>>>>>>>>>>>>>> [ 175.366282] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>>> [ 175.366284] kasan_report+0xd8/0x190
>>>>>>>>>>>>>> [ 175.366288] ? mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>>> [ 175.366294] mutex_can_spin_on_owner+0x1a6/0x1c0
>>>>>>>>>>>>>> [ 175.366297] __ww_mutex_lock.constprop.0+0x2f8/0x34d0
>>>>>>>>>>>>>> [ 175.366301] ? do_raw_spin_trylock+0xa2/0x160
>>>>>>>>>>>>>> [ 175.366304] ? __pfx_do_raw_spin_trylock+0x10/0x10
>>>>>>>>>>>>>> [ 175.366308] ? get_nohz_timer_target+0x28/0x3d0
>>>>>>>>>>>>>> [ 175.366311] ? modeset_lock+0x3c6/0x640
>>>>>>>>>>>>>> [ 175.366316] ?
>>>>>>>>>>>>>> __pfx___ww_mutex_lock.constprop.0+0x10/0x10
>>>>>>>>>>>>>> [ 175.366320] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>>> [ 175.366323] ? timerqueue_add+0x154/0x3c0
>>>>>>>>>>>>>> [ 175.366328] ? __hrtimer_start_range_ns+0x2e1/0x750
>>>>>>>>>>>>>> [ 175.366331] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>>> [ 175.366334] ? lock_acquired+0xb6/0xf0
>>>>>>>>>>>>>> [ 175.366337] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>>> [ 175.366340] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>>> [ 175.366342] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>>>>> [ 175.366345] ? lock_acquire+0xf2/0x140
>>>>>>>>>>>>>> [ 175.366349] ? ww_mutex_lock+0x27/0x150
>>>>>>>>>>>>>> [ 175.366352] ? drm_helper_probe_detect_ctx+0x6d/0x1a0
>>>>>>>>>>>>>> [ 175.366355] ww_mutex_lock+0x27/0x150
>>>>>>>>>>>>>> [ 175.366358] modeset_lock+0x3c6/0x640
>>>>>>>>>>>>>> [ 175.366362] drm_helper_probe_detect_ctx+0xa6/0x1a0
>>>>>>>>>>>>>> [ 175.366366] ?
>>>>>>>>>>>>>> __pfx_drm_helper_probe_detect_ctx+0x10/0x10
>>>>>>>>>>>>>> [ 175.366375] ?
>>>>>>>>>>>>>> __pfx_drm_connector_list_iter_next+0x10/0x10
>>>>>>>>>>>>>> [ 175.366381] output_poll_execute+0x29b/0x760
>>>>>>>>>>>>>> [ 175.366387] ? trace_hardirqs_on+0x14/0x150
>>>>>>>>>>>>>> [ 175.366391] ? __pfx_output_poll_execute+0x10/0x10
>>>>>>>>>>>>>> [ 175.366396] process_one_work+0x7b5/0x1390
>>>>>>>>>>>>>> [ 175.366404] ? __pfx_process_one_work+0x10/0x10
>>>>>>>>>>>>>> [ 175.366409] ? assign_work+0x156/0x390
>>>>>>>>>>>>>> [ 175.366413] worker_thread+0x58d/0xf60
>>>>>>>>>>>>>> [ 175.366420] ? __pfx_worker_thread+0x10/0x10
>>>>>>>>>>>>>> [ 175.366422] kthread+0x370/0x720
>>>>>>>>>>>>>> [ 175.366425] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>>>> [ 175.366428] ? local_clock_noinstr+0x56/0x100
>>>>>>>>>>>>>> [ 175.366431] ? local_clock+0x11/0x30
>>>>>>>>>>>>>> [ 175.366433] ? __lock_release.isra.0+0x16c/0x2e0
>>>>>>>>>>>>>> [ 175.366437] ? rcu_is_watching+0x11/0xb0
>>>>>>>>>>>>>> [ 175.366439] ?
>>>>>>>>>>>>>> lockdep_hardirqs_on_prepare.part.0+0x92/0x170
>>>>>>>>>>>>>> [ 175.366442] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>>>> [ 175.366445] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>>>>> [ 175.366448] ? __pfx_kthread+0x10/0x10
>>>>>>>>>>>>>> [ 175.366450] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>>>>> [ 175.366459] </TASK>
>>>>>>>>>>>>>> [ 175.366460]
>>>>>>>>>>>>>> [ 175.632772] Allocated by task 2342:
>>>>>>>>>>>>>> [ 175.636282] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>>> [ 175.640137] kasan_save_track+0x10/0x30
>>>>>>>>>>>>>> [ 175.643992] __kasan_slab_alloc+0x5f/0x70
>>>>>>>>>>>>>> [ 175.648023] kmem_cache_alloc_node_noprof+0x13a/0x380
>>>>>>>>>>>>>> [ 175.653097] dup_task_struct+0x32/0x730
>>>>>>>>>>>>>> [ 175.656952] copy_process+0x2d8/0x5380
>>>>>>>>>>>>>> [ 175.660720] kernel_clone+0x9f/0x5e0
>>>>>>>>>>>>>> [ 175.664318] __do_sys_clone3+0x135/0x180
>>>>>>>>>>>>>> [ 175.668258] do_syscall_64+0x68/0x2a0
>>>>>>>>>>>>>> [ 175.671940] entry_SYSCALL_64_after_hwframe+0x76/0x7e
>>>>>>>>>>>>>> [ 175.677014]
>>>>>>>>>>>>>> [ 175.678520] Freed by task 0:
>>>>>>>>>>>>>> [ 175.681418] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>>> [ 175.685273] kasan_save_track+0x10/0x30
>>>>>>>>>>>>>> [ 175.689130] kasan_save_free_info+0x37/0x70
>>>>>>>>>>>>>> [ 175.693333] __kasan_slab_free+0x33/0x40
>>>>>>>>>>>>>> [ 175.697278] kmem_cache_free+0x10b/0x4d0
>>>>>>>>>>>>>> [ 175.701221] delayed_put_task_struct+0x15e/0x1e0
>>>>>>>>>>>>>> [ 175.705858] rcu_do_batch+0x2e3/0xb30
>>>>>>>>>>>>>> [ 175.709542] rcu_core+0x51d/0xb60
>>>>>>>>>>>>>> [ 175.712873] handle_softirqs+0x1a2/0x6b0
>>>>>>>>>>>>>> [ 175.716817] __irq_exit_rcu+0xf7/0x160
>>>>>>>>>>>>>> [ 175.720585] irq_exit_rcu+0xa/0x30
>>>>>>>>>>>>>> [ 175.724006] sysvec_apic_timer_interrupt+0x9d/0xc0
>>>>>>>>>>>>>> [ 175.728820] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>>>>> [ 175.733980]
>>>>>>>>>>>>>> [ 175.735486] Last potentially related work creation:
>>>>>>>>>>>>>> [ 175.740385] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>>> [ 175.744243] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>>>>> [ 175.748618] __call_rcu_common.constprop.0+0x77/0x850
>>>>>>>>>>>>>> [ 175.753693] __schedule+0x887/0x1d00
>>>>>>>>>>>>>> [ 175.757287] schedule+0xd0/0x260
>>>>>>>>>>>>>> [ 175.760533] smpboot_thread_fn+0x583/0x7a0
>>>>>>>>>>>>>> [ 175.764650] kthread+0x370/0x720
>>>>>>>>>>>>>> [ 175.767896] ret_from_fork+0x1f4/0x2f0
>>>>>>>>>>>>>> [ 175.771665] ret_from_fork_asm+0x1a/0x30
>>>>>>>>>>>>>> [ 175.775608]
>>>>>>>>>>>>>> [ 175.777113] Second to last potentially related work
>>>>>>>>>>>>>> creation:
>>>>>>>>>>>>>> [ 175.782886] kasan_save_stack+0x1c/0x40
>>>>>>>>>>>>>> [ 175.786739] kasan_record_aux_stack+0x88/0xa0
>>>>>>>>>>>>>> [ 175.791118] task_work_add+0x1b1/0x270
>>>>>>>>>>>>>> [ 175.794886] sched_tick+0x226/0x6f0
>>>>>>>>>>>>>> [ 175.798394] update_process_times+0xe9/0x1f0
>>>>>>>>>>>>>> [ 175.802685] tick_nohz_handler+0x1a6/0x4b0
>>>>>>>>>>>>>> [ 175.806801] __hrtimer_run_queues+0x161/0x960
>>>>>>>>>>>>>> [ 175.811181] hrtimer_interrupt+0x33e/0x880
>>>>>>>>>>>>>> [ 175.815295] __sysvec_apic_timer_interrupt+0xf6/0x390
>>>>>>>>>>>>>> [ 175.820370] sysvec_apic_timer_interrupt+0x98/0xc0
>>>>>>>>>>>>>> [ 175.825183] asm_sysvec_apic_timer_interrupt+0x16/0x20
>>>>>>>>>>>>>> [ 175.830343]
>>>>>>>>>>>>>> [ 175.831849] The buggy address belongs to the object at
>>>>>>>>>>>>>> ffff8881172dafc0
>>>>>>>>>>>>>> [ 175.831849] which belongs to the cache task_struct of
>>>>>>>>>>>>>> size 11968
>>>>>>>>>>>>>> [ 175.844582] The buggy address is located 52 bytes
>>>>>>>>>>>>>> inside of
>>>>>>>>>>>>>> [ 175.844582] freed 11968-byte region
>>>>>>>>>>>>>> [ffff8881172dafc0, ffff8881172dde80)
>>>>>>>>>>>>>> [ 175.856969]
>>>>>>>>>>>>>> [ 175.858474] The buggy address belongs to the physical
>>>>>>>>>>>>>> page:
>>>>>>>>>>>>>> [ 175.864070] page: refcount:0 mapcount:0
>>>>>>>>>>>>>> mapping:0000000000000000 index:0x0 pfn:0x1172d8
>>>>>>>>>>>>>> [ 175.872104] head: order:3 mapcount:0 entire_mapcount:0
>>>>>>>>>>>>>> nr_pages_mapped:0 pincount:0
>>>>>>>>>>>>>> [ 175.879788] memcg:ffff88811068a301
>>>>>>>>>>>>>> [ 175.883209] anon flags:
>>>>>>>>>>>>>> 0x2ffff800000040(head|node=0|zone=2|lastcpupid=0x1ffff)
>>>>>>>>>>>>>> [ 175.890547] page_type: f5(slab)
>>>>>>>>>>>>>> [ 175.893706] raw: 002ffff800000040 ffff888100930500
>>>>>>>>>>>>>> 0000000000000000 0000000000000001
>>>>>>>>>>>>>> [ 175.901479] raw: 0000000000000000 0000000000020002
>>>>>>>>>>>>>> 00000000f5000000 ffff88811068a301
>>>>>>>>>>>>>> [ 175.909249] head: 002ffff800000040 ffff888100930500
>>>>>>>>>>>>>> 0000000000000000 0000000000000001
>>>>>>>>>>>>>> [ 175.917109] head: 0000000000000000 0000000000020002
>>>>>>>>>>>>>> 00000000f5000000 ffff88811068a301
>>>>>>>>>>>>>> [ 175.924968] head: 002ffff800000003 ffffea00045cb601
>>>>>>>>>>>>>> 00000000ffffffff 00000000ffffffff
>>>>>>>>>>>>>> [ 175.932827] head: ffffffffffffffff 0000000000000000
>>>>>>>>>>>>>> 00000000ffffffff 0000000000000008
>>>>>>>>>>>>>> [ 175.940685] page dumped because: kasan: bad access
>>>>>>>>>>>>>> detected
>>>>>>>>>>>>>> [ 175.946283]
>>>>>>>>>>>>>> [ 175.947787] Memory state around the buggy address:
>>>>>>>>>>>>>> [ 175.952603] ffff8881172dae80: fb fb fb fb fb fb fb fb
>>>>>>>>>>>>>> fc fc fc fc fc fc fc fc
>>>>>>>>>>>>>> [ 175.959854] ffff8881172daf00: fc fc fc fc fc fc fc fc
>>>>>>>>>>>>>> fc fc fc fc fc fc fc fc
>>>>>>>>>>>>>> [ 175.967101] >ffff8881172daf80: fc fc fc fc fc fc fc fc
>>>>>>>>>>>>>> fa fb fb fb fb fb fb fb
>>>>>>>>>>>>>> [ 175.974353] ^
>>>>>>>>>>>>>> [ 175.981256] ffff8881172db000: fb fb fb fb fb fb fb fb
>>>>>>>>>>>>>> fb fb fb fb fb fb fb fb
>>>>>>>>>>>>>> [ 175.988504] ffff8881172db080: fb fb fb fb fb fb fb fb
>>>>>>>>>>>>>> fb fb fb fb fb fb fb fb
>>>>>>>>>>>>>> [ 175.995755]
>>>>>>>>>>>>>> ==================================================================
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Am 22.05.25 um 09:07 schrieb oushixiong1025@163.com:
>>>>>>>>>>>>>>> From: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> [WHY]
>>>>>>>>>>>>>>> 1. Drivers using DRM_GEM_SHADOW_PLANE_HELPER_FUNCS and
>>>>>>>>>>>>>>> DRM_GEM_SHMEM_DRIVER_OPS (e.g., udl, ast) do
>>>>>>>>>>>>>>> not require
>>>>>>>>>>>>>>> sg_table import.
>>>>>>>>>>>>>>> They only need dma_buf_vmap() to access the
>>>>>>>>>>>>>>> shared buffer's
>>>>>>>>>>>>>>> kernel virtual address.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> 2. On certain Aspeed-based boards, a dma_mask of
>>>>>>>>>>>>>>> 0xffff_ffff may
>>>>>>>>>>>>>>> trigger SWIOTLB during dmabuf import. However,
>>>>>>>>>>>>>>> IO_TLB_SEGSIZE
>>>>>>>>>>>>>>> restricts the maximum DMA streaming mapping
>>>>>>>>>>>>>>> memory, resulting in
>>>>>>>>>>>>>>> errors like:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ast 0000:07:00.0: swiotlb buffer is full (sz:
>>>>>>>>>>>>>>> 3145728 bytes), total 32768 (slots), used 0 (slots)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> [HOW]
>>>>>>>>>>>>>>> Provide a gem_prime_import implementation without
>>>>>>>>>>>>>>> sg_table mapping
>>>>>>>>>>>>>>> to avoid issues (e.g., "swiotlb buffer is full").
>>>>>>>>>>>>>>> Drivers that do not
>>>>>>>>>>>>>>> require sg_table can adopt this.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> v1->v2:
>>>>>>>>>>>>>>> Patch rebase.
>>>>>>>>>>>>>>> v2->v3:
>>>>>>>>>>>>>>> Rename the import callback function.
>>>>>>>>>>>>>>> Remove drm_gem_shmem_prime_export() and
>>>>>>>>>>>>>>> separate some codes
>>>>>>>>>>>>>>> to drm_gem_prime_import_self().
>>>>>>>>>>>>>>> v3->v4:
>>>>>>>>>>>>>>> Separate the test from the policy.
>>>>>>>>>>>>>>> Rename the macro.
>>>>>>>>>>>>>>> v4->v5:
>>>>>>>>>>>>>>> Rename some functions.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> drivers/gpu/drm/drm_gem_shmem_helper.c | 57
>>>>>>>>>>>>>>> ++++++++++++++++++++++++++
>>>>>>>>>>>>>>> drivers/gpu/drm/drm_prime.c | 36 ++++++++++++----
>>>>>>>>>>>>>>> include/drm/drm_gem_shmem_helper.h | 15 +++++++
>>>>>>>>>>>>>>> include/drm/drm_prime.h | 3 ++
>>>>>>>>>>>>>>> 4 files changed, 102 insertions(+), 9 deletions(-)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>>>> b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>>>> index aa43265f4f4f..126aa79042ad 100644
>>>>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>>>>>>>>>>>>>> @@ -800,6 +800,63 @@
>>>>>>>>>>>>>>> drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>> EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
>>>>>>>>>>>>>>> +/**
>>>>>>>>>>>>>>> + * drm_gem_shmem_prime_import_no_map - Import dmabuf
>>>>>>>>>>>>>>> without mapping its sg_table
>>>>>>>>>>>>>>> + * @dev: Device to import into
>>>>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>>>>> + *
>>>>>>>>>>>>>>> + * Drivers that use the shmem helpers but also wants to
>>>>>>>>>>>>>>> import dmabuf without
>>>>>>>>>>>>>>> + * mapping its sg_table can use this as their
>>>>>>>>>>>>>>> &drm_driver.gem_prime_import
>>>>>>>>>>>>>>> + * implementation.
>>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>>> +struct drm_gem_object
>>>>>>>>>>>>>>> *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>>>>> +{
>>>>>>>>>>>>>>> + struct dma_buf_attachment *attach;
>>>>>>>>>>>>>>> + struct drm_gem_shmem_object *shmem;
>>>>>>>>>>>>>>> + struct drm_gem_object *obj;
>>>>>>>>>>>>>>> + size_t size;
>>>>>>>>>>>>>>> + int ret;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>>>>> + /*
>>>>>>>>>>>>>>> + * Importing dmabuf exported from our own gem
>>>>>>>>>>>>>>> increases
>>>>>>>>>>>>>>> + * refcount on gem itself instead of f_count of
>>>>>>>>>>>>>>> dmabuf.
>>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>>> + obj = dma_buf->priv;
>>>>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>>>>> + return obj;
>>>>>>>>>>>>>>> + }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + attach = dma_buf_attach(dma_buf, dev->dev);
>>>>>>>>>>>>>>> + if (IS_ERR(attach))
>>>>>>>>>>>>>>> + return ERR_CAST(attach);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + get_dma_buf(dma_buf);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + size = PAGE_ALIGN(attach->dmabuf->size);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + shmem = __drm_gem_shmem_create(dev, size, true, NULL);
>>>>>>>>>>>>>>> + if (IS_ERR(shmem)) {
>>>>>>>>>>>>>>> + ret = PTR_ERR(shmem);
>>>>>>>>>>>>>>> + goto fail_detach;
>>>>>>>>>>>>>>> + }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + drm_dbg_prime(dev, "size = %zu\n", size);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + shmem->base.import_attach = attach;
>>>>>>>>>>>>>>> + shmem->base.resv = dma_buf->resv;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + return &shmem->base;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +fail_detach:
>>>>>>>>>>>>>>> + dma_buf_detach(dma_buf, attach);
>>>>>>>>>>>>>>> + dma_buf_put(dma_buf);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + return ERR_PTR(ret);
>>>>>>>>>>>>>>> +}
>>>>>>>>>>>>>>> +EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> MODULE_DESCRIPTION("DRM SHMEM memory-management
>>>>>>>>>>>>>>> helpers");
>>>>>>>>>>>>>>> MODULE_IMPORT_NS("DMA_BUF");
>>>>>>>>>>>>>>> MODULE_LICENSE("GPL v2");
>>>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>>>> b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>>>> index d828502268b8..b825b71038d6 100644
>>>>>>>>>>>>>>> --- a/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>>>> +++ b/drivers/gpu/drm/drm_prime.c
>>>>>>>>>>>>>>> @@ -910,6 +910,26 @@ struct dma_buf
>>>>>>>>>>>>>>> *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>> EXPORT_SYMBOL(drm_gem_prime_export);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +/**
>>>>>>>>>>>>>>> + * drm_gem_is_prime_exported_dma_buf -
>>>>>>>>>>>>>>> + * checks if the DMA-BUF was exported from a GEM object
>>>>>>>>>>>>>>> belonging to @dev.
>>>>>>>>>>>>>>> + * @dev: drm_device to check against
>>>>>>>>>>>>>>> + * @dma_buf: dma-buf object to import
>>>>>>>>>>>>>>> + *
>>>>>>>>>>>>>>> + * Return: true if the DMA-BUF was exported from a GEM
>>>>>>>>>>>>>>> object belonging
>>>>>>>>>>>>>>> + * to @dev, false otherwise.
>>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct
>>>>>>>>>>>>>>> drm_device *dev,
>>>>>>>>>>>>>>> + struct dma_buf *dma_buf)
>>>>>>>>>>>>>>> +{
>>>>>>>>>>>>>>> + struct drm_gem_object *obj = dma_buf->priv;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> + return (dma_buf->ops == &drm_gem_prime_dmabuf_ops)
>>>>>>>>>>>>>>> && (obj->dev == dev);
>>>>>>>>>>>>>>> +}
>>>>>>>>>>>>>>> +EXPORT_SYMBOL(drm_gem_is_prime_exported_dma_buf);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> /**
>>>>>>>>>>>>>>> * drm_gem_prime_import_dev - core implementation
>>>>>>>>>>>>>>> of the import callback
>>>>>>>>>>>>>>> * @dev: drm_device to import into
>>>>>>>>>>>>>>> @@ -933,16 +953,14 @@ struct drm_gem_object
>>>>>>>>>>>>>>> *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>>>>> struct drm_gem_object *obj;
>>>>>>>>>>>>>>> int ret;
>>>>>>>>>>>>>>> - if (dma_buf->ops ==
>>>>>>>>>>>>>>> &drm_gem_prime_dmabuf_ops) {
>>>>>>>>>>>>>>> + if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
>>>>>>>>>>>>>>> + /*
>>>>>>>>>>>>>>> + * Importing dmabuf exported from our own gem
>>>>>>>>>>>>>>> increases
>>>>>>>>>>>>>>> + * refcount on gem itself instead of f_count of
>>>>>>>>>>>>>>> dmabuf.
>>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>>> obj = dma_buf->priv;
>>>>>>>>>>>>>>> - if (obj->dev == dev) {
>>>>>>>>>>>>>>> - /*
>>>>>>>>>>>>>>> - * Importing dmabuf exported from our own
>>>>>>>>>>>>>>> gem increases
>>>>>>>>>>>>>>> - * refcount on gem itself instead of
>>>>>>>>>>>>>>> f_count of dmabuf.
>>>>>>>>>>>>>>> - */
>>>>>>>>>>>>>>> - drm_gem_object_get(obj);
>>>>>>>>>>>>>>> - return obj;
>>>>>>>>>>>>>>> - }
>>>>>>>>>>>>>>> + drm_gem_object_get(obj);
>>>>>>>>>>>>>>> + return obj;
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>> if (!dev->driver->gem_prime_import_sg_table)
>>>>>>>>>>>>>>> diff --git a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>>>> b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>>>> index b4f993da3cae..35f7466dca84 100644
>>>>>>>>>>>>>>> --- a/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>>>> +++ b/include/drm/drm_gem_shmem_helper.h
>>>>>>>>>>>>>>> @@ -287,6 +287,8 @@
>>>>>>>>>>>>>>> drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
>>>>>>>>>>>>>>> struct sg_table *sgt);
>>>>>>>>>>>>>>> int drm_gem_shmem_dumb_create(struct drm_file
>>>>>>>>>>>>>>> *file, struct drm_device *dev,
>>>>>>>>>>>>>>> struct drm_mode_create_dumb
>>>>>>>>>>>>>>> *args);
>>>>>>>>>>>>>>> +struct drm_gem_object
>>>>>>>>>>>>>>> *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>>>>>>>>>>>>>>> + struct dma_buf *buf);
>>>>>>>>>>>>>>> /**
>>>>>>>>>>>>>>> * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM
>>>>>>>>>>>>>>> operations
>>>>>>>>>>>>>>> @@ -298,4 +300,17 @@ int
>>>>>>>>>>>>>>> drm_gem_shmem_dumb_create(struct drm_file *file, struct
>>>>>>>>>>>>>>> drm_device *dev,
>>>>>>>>>>>>>>> .gem_prime_import_sg_table =
>>>>>>>>>>>>>>> drm_gem_shmem_prime_import_sg_table, \
>>>>>>>>>>>>>>> .dumb_create =
>>>>>>>>>>>>>>> drm_gem_shmem_dumb_create
>>>>>>>>>>>>>>> +/**
>>>>>>>>>>>>>>> + * DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT - shmem GEM
>>>>>>>>>>>>>>> operations
>>>>>>>>>>>>>>> + * without mapping sg_table on
>>>>>>>>>>>>>>> + * imported buffer.
>>>>>>>>>>>>>>> + *
>>>>>>>>>>>>>>> + * This macro provides a shortcut for setting the shmem
>>>>>>>>>>>>>>> GEM operations in
>>>>>>>>>>>>>>> + * the &drm_driver structure for drivers that do not
>>>>>>>>>>>>>>> require a sg_table on
>>>>>>>>>>>>>>> + * imported buffers.
>>>>>>>>>>>>>>> + */
>>>>>>>>>>>>>>> +#define DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT \
>>>>>>>>>>>>>>> + .gem_prime_import =
>>>>>>>>>>>>>>> drm_gem_shmem_prime_import_no_map, \
>>>>>>>>>>>>>>> + .dumb_create = drm_gem_shmem_dumb_create
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> #endif /* __DRM_GEM_SHMEM_HELPER_H__ */
>>>>>>>>>>>>>>> diff --git a/include/drm/drm_prime.h
>>>>>>>>>>>>>>> b/include/drm/drm_prime.h
>>>>>>>>>>>>>>> index fa085c44d4ca..f50f862f0d8b 100644
>>>>>>>>>>>>>>> --- a/include/drm/drm_prime.h
>>>>>>>>>>>>>>> +++ b/include/drm/drm_prime.h
>>>>>>>>>>>>>>> @@ -100,6 +100,9 @@ struct dma_buf
>>>>>>>>>>>>>>> *drm_gem_prime_export(struct drm_gem_object *obj,
>>>>>>>>>>>>>>> unsigned long
>>>>>>>>>>>>>>> drm_prime_get_contiguous_size(struct sg_table *sgt);
>>>>>>>>>>>>>>> /* helper functions for importing */
>>>>>>>>>>>>>>> +bool drm_gem_is_prime_exported_dma_buf(struct
>>>>>>>>>>>>>>> drm_device *dev,
>>>>>>>>>>>>>>> + struct dma_buf *dma_buf);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> struct drm_gem_object
>>>>>>>>>>>>>>> *drm_gem_prime_import_dev(struct drm_device *dev,
>>>>>>>>>>>>>>> struct dma_buf *dma_buf,
>>>>>>>>>>>>>>> struct device *attach_dev);
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2025-08-18 8:46 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-22 7:07 [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table oushixiong1025
2025-05-22 7:07 ` [PATCH v5 RESEND 2/3] drm/ast: use DRM_GEM_SHMEM_DRIVER_OPS_NO_MAP_SGT oushixiong1025
2025-05-26 13:56 ` Thomas Zimmermann
2025-05-22 7:07 ` [PATCH v5 RESEND 3/3] drm/udl: " oushixiong1025
2025-05-26 13:57 ` Thomas Zimmermann
2025-05-26 15:00 ` [PATCH v5 RESEND 1/3] drm/shmem-helper: Import dmabuf without mapping its sg_table Thomas Zimmermann
2025-06-03 7:49 ` Thomas Zimmermann
2025-07-11 14:16 ` Thomas Zimmermann
[not found] ` <7d974eaa-d8a4-4430-a999-7b06c4e17a81@163.com>
2025-07-14 10:47 ` Thomas Zimmermann
2025-08-13 9:25 ` Thomas Zimmermann
2025-08-13 11:18 ` Christian König
2025-08-13 12:08 ` Thomas Zimmermann
2025-08-13 12:16 ` Thomas Zimmermann
2025-08-13 13:35 ` Christian König
2025-08-13 14:06 ` Thomas Zimmermann
2025-08-14 10:22 ` Christian König
2025-08-14 12:51 ` Thomas Zimmermann
2025-08-14 13:16 ` Christian König
2025-08-15 12:46 ` Thomas Zimmermann
2025-08-15 13:28 ` Christian König
2025-08-15 13:48 ` Thomas Zimmermann
2025-08-18 8:45 ` Thomas Zimmermann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).