diff options
| author | Shixiong Ou <oushixiong@kylinos.cn> | 2025-05-22 15:07:12 +0800 |
|---|---|---|
| committer | Thomas Zimmermann <tzimmermann@suse.de> | 2025-06-03 09:21:01 +0200 |
| commit | 660cd44659a05c5fbfce6d2bb1ce448aa0f35594 (patch) | |
| tree | 0f69608e085745b2ee892d02e7b5de63621ef372 /drivers/gpu/drm/drm_prime.c | |
| parent | 6048f5587614bb4919c54966913452c1a0a43138 (diff) | |
drm/shmem-helper: Import dmabuf without mapping its sg_table
[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>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20250522070714.439824-1-oushixiong1025@163.com
Diffstat (limited to 'drivers/gpu/drm/drm_prime.c')
| -rw-r--r-- | drivers/gpu/drm/drm_prime.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index a1852c02f512..b703f83874e1 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -928,6 +928,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 @@ -951,16 +971,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) |