summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_prime.c
diff options
context:
space:
mode:
authorShixiong Ou <oushixiong@kylinos.cn>2025-05-22 15:07:12 +0800
committerThomas Zimmermann <tzimmermann@suse.de>2025-06-03 09:21:01 +0200
commit660cd44659a05c5fbfce6d2bb1ce448aa0f35594 (patch)
tree0f69608e085745b2ee892d02e7b5de63621ef372 /drivers/gpu/drm/drm_prime.c
parent6048f5587614bb4919c54966913452c1a0a43138 (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.c36
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)