public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/4] Panthor BO tagging and GEMS debug display
@ 2025-04-11 15:03 Adrián Larumbe
  2025-04-11 15:03 ` [PATCH v7 1/4] drm/panthor: Introduce BO labeling Adrián Larumbe
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Adrián Larumbe @ 2025-04-11 15:03 UTC (permalink / raw)
  To: To : Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, Adrián Larumbe, dri-devel, linux-kernel, linux-media,
	linaro-mm-sig

This patch series is aimed at providing UM with detailed memory profiling
information in debug builds. It is achieved through a device-wide list of
DRM GEM objects, and also implementing the ability to label BO's from UM
through a new IOCTL.

The new debugfs file shows a list of driver DRM GEM objects in tabular mode.
To visualise it, cat sudo cat /sys/kernel/debug/dri/*.gpu/gems.
To test this functionality from UM, please refer to this Mesa patch series:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34224

Discussion of previous revision of this patch series can be found at:
https://lore.kernel.org/dri-devel/20250409212233.2036154-1-adrian.larumbe@collabora.com/T/#t

Changelog:
v7:
 - Improved formating of DebugFS GEM's status and usage flags
 - Deleted some spurious white spaces
 - Renamed usage flags setting function

v6:
 - Replaced some mutex calls with scoped guards
 - Documented data size limits in the label ioctl
 - Simplified GEMS status flags treatment (Panthor doesn't use madvise)
 - Fixed some array size and string bugs
 - Improved the naming of GEM status and usage flags to reflect their meaning
 - Improved the formatting of the output table

v5:
 - Kept case and naming of kernel BO's consistent
 - Increased the driver minor after new ioctl
 - Now adds BO to debugfs GEMs list at GEM object creation time
 - No longer try to hide BO creator's name when it's a workqueue or modprobe
 - Reworked the procedure for printing GEM state and kernel BO flags
 - Turned kernel BO flags and GEM state flags into bit enums
 - Wait until BO state is marked as initialied for debugfs display

v4:
 - Labelled all kernel BO's, not just heap chunks.
 - Refactored DebugGFs GEMs list handling functions
 - Added debugfs GEMS node mask to tell different kinds of BO's

Adrián Larumbe (4):
  drm/panthor: Introduce BO labeling
  drm/panthor: Add driver IOCTL for setting BO labels
  drm/panthor: Label all kernel BO's
  drm/panthor: show device-wide list of DRM GEM objects over DebugFS

 drivers/gpu/drm/panthor/panthor_device.c |   5 +
 drivers/gpu/drm/panthor/panthor_device.h |  11 ++
 drivers/gpu/drm/panthor/panthor_drv.c    |  68 ++++++-
 drivers/gpu/drm/panthor/panthor_fw.c     |   8 +-
 drivers/gpu/drm/panthor/panthor_gem.c    | 225 ++++++++++++++++++++++-
 drivers/gpu/drm/panthor/panthor_gem.h    |  80 +++++++-
 drivers/gpu/drm/panthor/panthor_heap.c   |   6 +-
 drivers/gpu/drm/panthor/panthor_sched.c  |   9 +-
 include/uapi/drm/panthor_drm.h           |  23 +++
 9 files changed, 424 insertions(+), 11 deletions(-)

--
2.48.1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v7 1/4] drm/panthor: Introduce BO labeling
  2025-04-11 15:03 [PATCH v7 0/4] Panthor BO tagging and GEMS debug display Adrián Larumbe
@ 2025-04-11 15:03 ` Adrián Larumbe
  2025-04-14  9:50   ` Steven Price
  2025-04-11 15:03 ` [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels Adrián Larumbe
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Adrián Larumbe @ 2025-04-11 15:03 UTC (permalink / raw)
  To: To : Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, Adrián Larumbe, dri-devel, linux-kernel, linux-media,
	linaro-mm-sig

Add a new character string Panthor BO field, and a function that allows
setting it from within the driver.

Driver takes care of freeing the string when it's replaced or no longer
needed at object destruction time, but allocating it is the responsibility
of callers.

Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/gpu/drm/panthor/panthor_gem.c | 39 +++++++++++++++++++++++++++
 drivers/gpu/drm/panthor/panthor_gem.h | 17 ++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index 8244a4e6c2a2..af0ac17f357f 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -2,6 +2,7 @@
 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
 /* Copyright 2023 Collabora ltd. */
 
+#include <linux/cleanup.h>
 #include <linux/dma-buf.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
@@ -18,6 +19,14 @@ static void panthor_gem_free_object(struct drm_gem_object *obj)
 	struct panthor_gem_object *bo = to_panthor_bo(obj);
 	struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem;
 
+	/*
+	 * Label might have been allocated with kstrdup_const(),
+	 * we need to take that into account when freeing the memory
+	 */
+	kfree_const(bo->label.str);
+
+	mutex_destroy(&bo->label.lock);
+
 	drm_gem_free_mmap_offset(&bo->base.base);
 	mutex_destroy(&bo->gpuva_list_lock);
 	drm_gem_shmem_free(&bo->base);
@@ -196,6 +205,7 @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t
 	obj->base.map_wc = !ptdev->coherent;
 	mutex_init(&obj->gpuva_list_lock);
 	drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock);
+	mutex_init(&obj->label.lock);
 
 	return &obj->base.base;
 }
@@ -247,3 +257,32 @@ panthor_gem_create_with_handle(struct drm_file *file,
 
 	return ret;
 }
+
+void
+panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label)
+{
+	struct panthor_gem_object *bo = to_panthor_bo(obj);
+	const char *old_label;
+
+	scoped_guard(mutex, &bo->label.lock) {
+		old_label = bo->label.str;
+		bo->label.str = label;
+	}
+
+	kfree(old_label);
+}
+
+void
+panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label)
+{
+	const char *str;
+
+	str = kstrdup_const(label, GFP_KERNEL);
+	if (!str) {
+		/* Failing to allocate memory for a label isn't a fatal condition */
+		drm_warn(bo->obj->dev, "Not enough memory to allocate BO label");
+		return;
+	}
+
+	panthor_gem_bo_set_label(bo->obj, str);
+}
diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
index 1a363bb814f4..af0d77338860 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.h
+++ b/drivers/gpu/drm/panthor/panthor_gem.h
@@ -46,6 +46,20 @@ struct panthor_gem_object {
 
 	/** @flags: Combination of drm_panthor_bo_flags flags. */
 	u32 flags;
+
+	/**
+	 * @label: BO tagging fields. The label can be assigned within the
+	 * driver itself or through a specific IOCTL.
+	 */
+	struct {
+		/**
+		 * @label.str: Pointer to NULL-terminated string,
+		 */
+		const char *str;
+
+		/** @lock.str: Protects access to the @label.str field. */
+		struct mutex lock;
+	} label;
 };
 
 /**
@@ -91,6 +105,9 @@ panthor_gem_create_with_handle(struct drm_file *file,
 			       struct panthor_vm *exclusive_vm,
 			       u64 *size, u32 flags, uint32_t *handle);
 
+void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label);
+void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label);
+
 static inline u64
 panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo)
 {
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels
  2025-04-11 15:03 [PATCH v7 0/4] Panthor BO tagging and GEMS debug display Adrián Larumbe
  2025-04-11 15:03 ` [PATCH v7 1/4] drm/panthor: Introduce BO labeling Adrián Larumbe
@ 2025-04-11 15:03 ` Adrián Larumbe
  2025-04-14 10:01   ` Steven Price
  2025-04-15 11:07   ` Daniel Stone
  2025-04-11 15:03 ` [PATCH v7 3/4] drm/panthor: Label all kernel BO's Adrián Larumbe
  2025-04-11 15:03 ` [PATCH v7 4/4] drm/panthor: show device-wide list of DRM GEM objects over DebugFS Adrián Larumbe
  3 siblings, 2 replies; 14+ messages in thread
From: Adrián Larumbe @ 2025-04-11 15:03 UTC (permalink / raw)
  To: To : Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, Adrián Larumbe, dri-devel, linux-kernel, linux-media,
	linaro-mm-sig

Allow UM to label a BO for which it possesses a DRM handle.

Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/gpu/drm/panthor/panthor_drv.c | 42 ++++++++++++++++++++++++++-
 drivers/gpu/drm/panthor/panthor_gem.h |  2 ++
 include/uapi/drm/panthor_drm.h        | 23 +++++++++++++++
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index 06fe46e32073..983b24f1236c 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -1331,6 +1331,44 @@ static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data,
 	return 0;
 }
 
+static int panthor_ioctl_bo_set_label(struct drm_device *ddev, void *data,
+				  struct drm_file *file)
+{
+	struct drm_panthor_bo_set_label *args = data;
+	struct drm_gem_object *obj;
+	const char *label;
+	int ret = 0;
+
+	obj = drm_gem_object_lookup(file, args->handle);
+	if (!obj)
+		return -ENOENT;
+
+	if (args->size && args->label) {
+		if (args->size > PANTHOR_BO_LABEL_MAXLEN) {
+			ret = -E2BIG;
+			goto err_label;
+		}
+
+		label = strndup_user(u64_to_user_ptr(args->label), args->size);
+		if (IS_ERR(label)) {
+			ret = PTR_ERR(label);
+			goto err_label;
+		}
+	} else if (args->size && !args->label) {
+		ret = -EINVAL;
+		goto err_label;
+	} else {
+		label = NULL;
+	}
+
+	panthor_gem_bo_set_label(obj, label);
+
+err_label:
+	drm_gem_object_put(obj);
+
+	return ret;
+}
+
 static int
 panthor_open(struct drm_device *ddev, struct drm_file *file)
 {
@@ -1400,6 +1438,7 @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = {
 	PANTHOR_IOCTL(TILER_HEAP_CREATE, tiler_heap_create, DRM_RENDER_ALLOW),
 	PANTHOR_IOCTL(TILER_HEAP_DESTROY, tiler_heap_destroy, DRM_RENDER_ALLOW),
 	PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW),
+	PANTHOR_IOCTL(BO_SET_LABEL, bo_set_label, DRM_RENDER_ALLOW),
 };
 
 static int panthor_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -1509,6 +1548,7 @@ static void panthor_debugfs_init(struct drm_minor *minor)
  * - 1.2 - adds DEV_QUERY_GROUP_PRIORITIES_INFO query
  *       - adds PANTHOR_GROUP_PRIORITY_REALTIME priority
  * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag
+ * - 1.4 - adds DRM_IOCTL_PANTHOR_BO_SET_LABEL ioctl
  */
 static const struct drm_driver panthor_drm_driver = {
 	.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ |
@@ -1522,7 +1562,7 @@ static const struct drm_driver panthor_drm_driver = {
 	.name = "panthor",
 	.desc = "Panthor DRM driver",
 	.major = 1,
-	.minor = 3,
+	.minor = 4,
 
 	.gem_create_object = panthor_gem_create_object,
 	.gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
index af0d77338860..beba066b4974 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.h
+++ b/drivers/gpu/drm/panthor/panthor_gem.h
@@ -13,6 +13,8 @@
 
 struct panthor_vm;
 
+#define PANTHOR_BO_LABEL_MAXLEN	PAGE_SIZE
+
 /**
  * struct panthor_gem_object - Driver specific GEM object.
  */
diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
index 97e2c4510e69..12b1994499a9 100644
--- a/include/uapi/drm/panthor_drm.h
+++ b/include/uapi/drm/panthor_drm.h
@@ -127,6 +127,9 @@ enum drm_panthor_ioctl_id {
 
 	/** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */
 	DRM_PANTHOR_TILER_HEAP_DESTROY,
+
+	/** @DRM_PANTHOR_BO_SET_LABEL: Label a BO. */
+	DRM_PANTHOR_BO_SET_LABEL,
 };
 
 /**
@@ -977,6 +980,24 @@ struct drm_panthor_tiler_heap_destroy {
 	__u32 pad;
 };
 
+/**
+ * struct drm_panthor_bo_set_label - Arguments passed to DRM_IOCTL_PANTHOR_BO_SET_LABEL
+ */
+struct drm_panthor_bo_set_label {
+	/** @handle: Handle of the buffer object to label. */
+	__u32 handle;
+
+	/**
+	 * @size: Length of the label, including the NULL terminator.
+	 *
+	 * Cannot be greater than the OS page size.
+	 */
+	__u32 size;
+
+	/** @label: User pointer to a NULL-terminated string */
+	__u64 label;
+};
+
 /**
  * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number
  * @__access: Access type. Must be R, W or RW.
@@ -1019,6 +1040,8 @@ enum {
 		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create),
 	DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY =
 		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy),
+	DRM_IOCTL_PANTHOR_BO_SET_LABEL =
+		DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label),
 };
 
 #if defined(__cplusplus)
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 3/4] drm/panthor: Label all kernel BO's
  2025-04-11 15:03 [PATCH v7 0/4] Panthor BO tagging and GEMS debug display Adrián Larumbe
  2025-04-11 15:03 ` [PATCH v7 1/4] drm/panthor: Introduce BO labeling Adrián Larumbe
  2025-04-11 15:03 ` [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels Adrián Larumbe
@ 2025-04-11 15:03 ` Adrián Larumbe
  2025-04-14 10:01   ` Steven Price
  2025-04-14 13:38   ` kernel test robot
  2025-04-11 15:03 ` [PATCH v7 4/4] drm/panthor: show device-wide list of DRM GEM objects over DebugFS Adrián Larumbe
  3 siblings, 2 replies; 14+ messages in thread
From: Adrián Larumbe @ 2025-04-11 15:03 UTC (permalink / raw)
  To: To : Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, Adrián Larumbe, dri-devel, linux-kernel, linux-media,
	linaro-mm-sig

Kernel BO's aren't exposed to UM, so labelling them is the responsibility
of the driver itself. This kind of tagging will prove useful in further
commits when want to expose these objects through DebugFS.

Expand panthor_kernel_bo_create() interface to take a NULL-terminated
string. No bounds checking is done because all label strings are given
as statically-allocated literals, but if a more complex kernel BO naming
scheme with explicit memory allocation and formatting was desired in the
future, this would have to change.

Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
---
 drivers/gpu/drm/panthor/panthor_fw.c    | 8 +++++---
 drivers/gpu/drm/panthor/panthor_gem.c   | 4 +++-
 drivers/gpu/drm/panthor/panthor_gem.h   | 2 +-
 drivers/gpu/drm/panthor/panthor_heap.c  | 6 ++++--
 drivers/gpu/drm/panthor/panthor_sched.c | 9 ++++++---
 5 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c
index 0f52766a3120..a7fdc4d8020d 100644
--- a/drivers/gpu/drm/panthor/panthor_fw.c
+++ b/drivers/gpu/drm/panthor/panthor_fw.c
@@ -449,7 +449,8 @@ panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev,
 				       DRM_PANTHOR_BO_NO_MMAP,
 				       DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
 				       DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
-				       PANTHOR_VM_KERNEL_AUTO_VA);
+				       PANTHOR_VM_KERNEL_AUTO_VA,
+				       "Queue FW interface");
 	if (IS_ERR(mem))
 		return mem;
 
@@ -481,7 +482,8 @@ panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size)
 	return panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), size,
 					DRM_PANTHOR_BO_NO_MMAP,
 					DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
-					PANTHOR_VM_KERNEL_AUTO_VA);
+					PANTHOR_VM_KERNEL_AUTO_VA,
+					"FW suspend buffer");
 }
 
 static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
@@ -601,7 +603,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
 		section->mem = panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev),
 							section_size,
 							DRM_PANTHOR_BO_NO_MMAP,
-							vm_map_flags, va);
+							vm_map_flags, va, "FW section");
 		if (IS_ERR(section->mem))
 			return PTR_ERR(section->mem);
 
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index af0ac17f357f..3c5fc854356e 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -82,7 +82,7 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo)
 struct panthor_kernel_bo *
 panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
 			 size_t size, u32 bo_flags, u32 vm_map_flags,
-			 u64 gpu_va)
+			 u64 gpu_va, const char *name)
 {
 	struct drm_gem_shmem_object *obj;
 	struct panthor_kernel_bo *kbo;
@@ -106,6 +106,8 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
 	kbo->obj = &obj->base;
 	bo->flags = bo_flags;
 
+	panthor_gem_kernel_bo_set_label(kbo, name);
+
 	/* The system and GPU MMU page size might differ, which becomes a
 	 * problem for FW sections that need to be mapped at explicit address
 	 * since our PAGE_SIZE alignment might cover a VA range that's
diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
index beba066b4974..62aea06dbc6d 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.h
+++ b/drivers/gpu/drm/panthor/panthor_gem.h
@@ -153,7 +153,7 @@ panthor_kernel_bo_vunmap(struct panthor_kernel_bo *bo)
 struct panthor_kernel_bo *
 panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
 			 size_t size, u32 bo_flags, u32 vm_map_flags,
-			 u64 gpu_va);
+			 u64 gpu_va, const char *name);
 
 void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo);
 
diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c
index 3bdf61c14264..d236e9ceade4 100644
--- a/drivers/gpu/drm/panthor/panthor_heap.c
+++ b/drivers/gpu/drm/panthor/panthor_heap.c
@@ -151,7 +151,8 @@ static int panthor_alloc_heap_chunk(struct panthor_heap_pool *pool,
 	chunk->bo = panthor_kernel_bo_create(pool->ptdev, pool->vm, heap->chunk_size,
 					     DRM_PANTHOR_BO_NO_MMAP,
 					     DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
-					     PANTHOR_VM_KERNEL_AUTO_VA);
+					     PANTHOR_VM_KERNEL_AUTO_VA,
+					     "Tiler heap chunk");
 	if (IS_ERR(chunk->bo)) {
 		ret = PTR_ERR(chunk->bo);
 		goto err_free_chunk;
@@ -555,7 +556,8 @@ panthor_heap_pool_create(struct panthor_device *ptdev, struct panthor_vm *vm)
 	pool->gpu_contexts = panthor_kernel_bo_create(ptdev, vm, bosize,
 						      DRM_PANTHOR_BO_NO_MMAP,
 						      DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
-						      PANTHOR_VM_KERNEL_AUTO_VA);
+						      PANTHOR_VM_KERNEL_AUTO_VA,
+						      "Heap pool");
 	if (IS_ERR(pool->gpu_contexts)) {
 		ret = PTR_ERR(pool->gpu_contexts);
 		goto err_destroy_pool;
diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
index 446ec780eb4a..43ee57728de5 100644
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -3332,7 +3332,8 @@ group_create_queue(struct panthor_group *group,
 						  DRM_PANTHOR_BO_NO_MMAP,
 						  DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
 						  DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
-						  PANTHOR_VM_KERNEL_AUTO_VA);
+						  PANTHOR_VM_KERNEL_AUTO_VA,
+						  "CS ring buffer");
 	if (IS_ERR(queue->ringbuf)) {
 		ret = PTR_ERR(queue->ringbuf);
 		goto err_free_queue;
@@ -3362,7 +3363,8 @@ group_create_queue(struct panthor_group *group,
 					 DRM_PANTHOR_BO_NO_MMAP,
 					 DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
 					 DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
-					 PANTHOR_VM_KERNEL_AUTO_VA);
+					 PANTHOR_VM_KERNEL_AUTO_VA,
+					 "Group job stats");
 
 	if (IS_ERR(queue->profiling.slots)) {
 		ret = PTR_ERR(queue->profiling.slots);
@@ -3493,7 +3495,8 @@ int panthor_group_create(struct panthor_file *pfile,
 						   DRM_PANTHOR_BO_NO_MMAP,
 						   DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
 						   DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
-						   PANTHOR_VM_KERNEL_AUTO_VA);
+						   PANTHOR_VM_KERNEL_AUTO_VA,
+						   "Group sync objects");
 	if (IS_ERR(group->syncobjs)) {
 		ret = PTR_ERR(group->syncobjs);
 		goto err_put_group;
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 4/4] drm/panthor: show device-wide list of DRM GEM objects over DebugFS
  2025-04-11 15:03 [PATCH v7 0/4] Panthor BO tagging and GEMS debug display Adrián Larumbe
                   ` (2 preceding siblings ...)
  2025-04-11 15:03 ` [PATCH v7 3/4] drm/panthor: Label all kernel BO's Adrián Larumbe
@ 2025-04-11 15:03 ` Adrián Larumbe
  3 siblings, 0 replies; 14+ messages in thread
From: Adrián Larumbe @ 2025-04-11 15:03 UTC (permalink / raw)
  To: To : Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, Adrián Larumbe, dri-devel, linux-kernel, linux-media,
	linaro-mm-sig

Add a device DebugFS file that displays a complete list of all the DRM
GEM objects that are exposed to UM through a DRM handle.

Since leaking object identifiers that might belong to a different NS is
inadmissible, this functionality is only made available in debug builds
with DEBUGFS support enabled.

File format is that of a table, with each entry displaying a variety of
fields with information about each GEM object.

Each GEM object entry in the file displays the following information
fields: Client PID, BO's global name, reference count, BO virtual size,
BO resize size, VM address in its DRM-managed range, BO label and a GEM
state flags.

There's also a usage flags field for the type of BO, which tells us
whether it's a kernel BO and/or mapped onto the FW's address space.

Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 drivers/gpu/drm/panthor/panthor_device.c |   5 +
 drivers/gpu/drm/panthor/panthor_device.h |  11 ++
 drivers/gpu/drm/panthor/panthor_drv.c    |  26 ++++
 drivers/gpu/drm/panthor/panthor_gem.c    | 182 +++++++++++++++++++++++
 drivers/gpu/drm/panthor/panthor_gem.h    |  59 ++++++++
 5 files changed, 283 insertions(+)

diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
index a9da1d1eeb70..b776e1a2e4f3 100644
--- a/drivers/gpu/drm/panthor/panthor_device.c
+++ b/drivers/gpu/drm/panthor/panthor_device.c
@@ -184,6 +184,11 @@ int panthor_device_init(struct panthor_device *ptdev)
 	if (ret)
 		return ret;
 
+#ifdef CONFIG_DEBUG_FS
+	drmm_mutex_init(&ptdev->base, &ptdev->gems.lock);
+	INIT_LIST_HEAD(&ptdev->gems.node);
+#endif
+
 	atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED);
 	p = alloc_page(GFP_KERNEL | __GFP_ZERO);
 	if (!p)
diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
index da6574021664..86206a961b38 100644
--- a/drivers/gpu/drm/panthor/panthor_device.h
+++ b/drivers/gpu/drm/panthor/panthor_device.h
@@ -205,6 +205,17 @@ struct panthor_device {
 
 	/** @fast_rate: Maximum device clock frequency. Set by DVFS */
 	unsigned long fast_rate;
+
+#ifdef CONFIG_DEBUG_FS
+	/** @gems: Device-wide list of GEM objects owned by at least one file. */
+	struct {
+		/** @gems.lock: Protects the device-wide list of GEM objects. */
+		struct mutex lock;
+
+		/** @node: Used to keep track of all the device's DRM objects */
+		struct list_head node;
+	} gems;
+#endif
 };
 
 struct panthor_gpu_usage {
diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index 983b24f1236c..4d3f2eb29a47 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -1535,9 +1535,35 @@ static const struct file_operations panthor_drm_driver_fops = {
 };
 
 #ifdef CONFIG_DEBUG_FS
+static int panthor_gems_show(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct panthor_device *ptdev = container_of(dev, struct panthor_device, base);
+
+	panthor_gem_debugfs_print_bos(ptdev, m);
+
+	return 0;
+}
+
+
+static struct drm_info_list panthor_debugfs_list[] = {
+	{"gems", panthor_gems_show, 0, NULL},
+};
+
+static int panthor_gems_debugfs_init(struct drm_minor *minor)
+{
+	drm_debugfs_create_files(panthor_debugfs_list,
+				 ARRAY_SIZE(panthor_debugfs_list),
+				 minor->debugfs_root, minor);
+
+	return 0;
+}
+
 static void panthor_debugfs_init(struct drm_minor *minor)
 {
 	panthor_mmu_debugfs_init(minor);
+	panthor_gems_debugfs_init(minor);
 }
 #endif
 
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index 3c5fc854356e..fab7a11ab71f 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -11,14 +11,51 @@
 #include <drm/panthor_drm.h>
 
 #include "panthor_device.h"
+#include "panthor_fw.h"
 #include "panthor_gem.h"
 #include "panthor_mmu.h"
 
+#ifdef CONFIG_DEBUG_FS
+static void panthor_gem_debugfs_bo_add(struct panthor_device *ptdev,
+				       struct panthor_gem_object *bo)
+{
+	INIT_LIST_HEAD(&bo->debugfs.node);
+
+	bo->debugfs.creator.tgid = current->group_leader->pid;
+	get_task_comm(bo->debugfs.creator.process_name, current->group_leader);
+
+	mutex_lock(&ptdev->gems.lock);
+	list_add_tail(&bo->debugfs.node, &ptdev->gems.node);
+	mutex_unlock(&ptdev->gems.lock);
+}
+
+static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo)
+{
+	struct panthor_device *ptdev = container_of(bo->base.base.dev,
+						    struct panthor_device, base);
+
+	if (list_empty(&bo->debugfs.node))
+		return;
+
+	mutex_lock(&ptdev->gems.lock);
+	list_del_init(&bo->debugfs.node);
+	mutex_unlock(&ptdev->gems.lock);
+}
+
+#else
+static void panthor_gem_debugfs_bo_add(struct panthor_device *ptdev,
+				       struct panthor_gem_object *bo)
+{}
+static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) {}
+#endif
+
 static void panthor_gem_free_object(struct drm_gem_object *obj)
 {
 	struct panthor_gem_object *bo = to_panthor_bo(obj);
 	struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem;
 
+	panthor_gem_debugfs_bo_rm(bo);
+
 	/*
 	 * Label might have been allocated with kstrdup_const(),
 	 * we need to take that into account when freeing the memory
@@ -87,6 +124,7 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
 	struct drm_gem_shmem_object *obj;
 	struct panthor_kernel_bo *kbo;
 	struct panthor_gem_object *bo;
+	u32 debug_flags = PANTHOR_DEBUGFS_GEM_USAGE_FLAG_KERNEL;
 	int ret;
 
 	if (drm_WARN_ON(&ptdev->base, !vm))
@@ -106,7 +144,11 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
 	kbo->obj = &obj->base;
 	bo->flags = bo_flags;
 
+	if (vm == panthor_fw_vm(ptdev))
+		debug_flags |= PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED;
+
 	panthor_gem_kernel_bo_set_label(kbo, name);
+	panthor_gem_debugfs_set_usage_flags(to_panthor_bo(kbo->obj), debug_flags);
 
 	/* The system and GPU MMU page size might differ, which becomes a
 	 * problem for FW sections that need to be mapped at explicit address
@@ -209,6 +251,8 @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t
 	drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock);
 	mutex_init(&obj->label.lock);
 
+	panthor_gem_debugfs_bo_add(ptdev, obj);
+
 	return &obj->base.base;
 }
 
@@ -257,6 +301,12 @@ panthor_gem_create_with_handle(struct drm_file *file,
 	/* drop reference from allocate - handle holds it now. */
 	drm_gem_object_put(&shmem->base);
 
+	/*
+	 * No explicit flags are needed in the call below, since the
+	 * function internally sets the INITIALIZED bit for us.
+	 */
+	panthor_gem_debugfs_set_usage_flags(bo, 0);
+
 	return ret;
 }
 
@@ -288,3 +338,135 @@ panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label)
 
 	panthor_gem_bo_set_label(bo->obj, str);
 }
+
+#ifdef CONFIG_DEBUG_FS
+static void
+panthor_gem_debugfs_format_flags(char flags_str[], int flags_len,
+				 const char * const names[], u32 name_count,
+				 u32 flags)
+{
+	bool first = true;
+	int offset = 0;
+
+#define ACC_FLAGS(...) \
+	({ \
+		offset += snprintf(flags_str + offset, flags_len - offset, ##__VA_ARGS__); \
+		if (offset == flags_len) \
+			return; \
+	})
+
+	ACC_FLAGS("%c", '(');
+
+	if (!flags)
+		ACC_FLAGS("%s", "none");
+
+	while (flags) {
+		u32 bit = fls(flags) - 1;
+		u32 idx = bit + 1;
+
+		if (!first)
+			ACC_FLAGS("%s", ",");
+
+		if (idx < name_count && names[idx])
+			ACC_FLAGS("%s", names[idx]);
+
+		first = false;
+		flags &= ~BIT(bit);
+	}
+
+	ACC_FLAGS("%c", ')');
+
+#undef ACC_FLAGS
+}
+
+struct gem_size_totals {
+	size_t size;
+	size_t resident;
+	size_t reclaimable;
+};
+
+static void panthor_gem_debugfs_bo_print(struct panthor_gem_object *bo,
+					 struct seq_file *m,
+					 struct gem_size_totals *totals)
+{
+	unsigned int refcount = kref_read(&bo->base.base.refcount);
+	char creator_info[32] = {};
+	size_t resident_size;
+	char gem_state_str[64] = {};
+	char gem_usage_str[64] = {};
+	u32 gem_usage_flags = bo->debugfs.flags & (u32)~PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED;
+	u32 gem_state_flags = 0;
+
+	static const char * const gem_state_flags_names[] = {
+		[PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED] = "imported",
+		[PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED] = "exported",
+	};
+
+	static const char * const gem_usage_flags_names[] = {
+		[PANTHOR_DEBUGFS_GEM_USAGE_FLAG_KERNEL] = "kernel",
+		[PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED] = "fw-mapped",
+	};
+
+	/* Skip BOs being destroyed. */
+	if (!refcount)
+		return;
+
+	resident_size = bo->base.pages != NULL ? bo->base.base.size : 0;
+
+	snprintf(creator_info, sizeof(creator_info),
+		 "%s/%d", bo->debugfs.creator.process_name, bo->debugfs.creator.tgid);
+	seq_printf(m, "%-32s%-16d%-16d%-16zd%-16zd%-16lx",
+		   creator_info,
+		   bo->base.base.name,
+		   refcount,
+		   bo->base.base.size,
+		   resident_size,
+		   drm_vma_node_start(&bo->base.base.vma_node));
+
+	if (bo->base.base.import_attach != NULL)
+		gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED;
+	if (bo->base.base.dma_buf != NULL)
+		gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED;
+
+	panthor_gem_debugfs_format_flags(gem_state_str, sizeof(gem_state_str),
+					 gem_state_flags_names, ARRAY_SIZE(gem_state_flags_names),
+					 gem_state_flags);
+	panthor_gem_debugfs_format_flags(gem_usage_str, sizeof(gem_usage_str),
+					 gem_usage_flags_names, ARRAY_SIZE(gem_usage_flags_names),
+					 gem_usage_flags);
+
+	seq_printf(m, "%-64s%-64s", gem_state_str, gem_usage_str);
+
+	scoped_guard(mutex, &bo->label.lock) {
+		seq_printf(m, "%s", bo->label.str ? : "");
+	}
+
+	seq_puts(m, "\n");
+
+	totals->size += bo->base.base.size;
+	totals->resident += resident_size;
+	if (bo->base.madv > 0)
+		totals->reclaimable += resident_size;
+}
+
+void panthor_gem_debugfs_print_bos(struct panthor_device *ptdev,
+				   struct seq_file *m)
+{
+	struct gem_size_totals totals = {0};
+	struct panthor_gem_object *bo;
+
+	seq_puts(m, "created-by                      global-name     refcount        size            resident-size   file-offset     state                                                           usage                                                           label\n");
+	seq_puts(m, "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
+
+	scoped_guard(mutex, &ptdev->gems.lock) {
+		list_for_each_entry(bo, &ptdev->gems.node, debugfs.node) {
+			if (bo->debugfs.flags & PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED)
+				panthor_gem_debugfs_bo_print(bo, m, &totals);
+		}
+	}
+
+	seq_puts(m, "=====================================================================================================================================================================================================================================================\n");
+	seq_printf(m, "Total size: %zd, Total resident: %zd, Total reclaimable: %zd\n",
+		   totals.size, totals.resident, totals.reclaimable);
+}
+#endif
diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
index 62aea06dbc6d..03aec800cac5 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.h
+++ b/drivers/gpu/drm/panthor/panthor_gem.h
@@ -15,6 +15,48 @@ struct panthor_vm;
 
 #define PANTHOR_BO_LABEL_MAXLEN	PAGE_SIZE
 
+enum panthor_debugfs_gem_state_flags {
+	/** @PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED: GEM BO is PRIME imported. */
+	PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED = BIT(0),
+
+	/** @PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED: GEM BO is PRIME exported. */
+	PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED = BIT(1),
+};
+
+enum panthor_debugfs_gem_usage_flags {
+	/** @PANTHOR_DEBUGFS_GEM_USAGE_FLAG_KERNEL: BO is for kernel use only. */
+	PANTHOR_DEBUGFS_GEM_USAGE_FLAG_KERNEL = BIT(0),
+
+	/** @PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED: BO is mapped on the FW VM. */
+	PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED = BIT(1),
+
+	/** @PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED: BO is ready for DebugFS display. */
+	PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED = BIT(31),
+};
+
+/**
+ * struct panthor_gem_debugfs - GEM object's DebugFS list information
+ */
+struct panthor_gem_debugfs {
+	/**
+	 * @node: Node used to insert the object in the device-wide list of
+	 * GEM objects, to display information about it through a DebugFS file.
+	 */
+	struct list_head node;
+
+	/** @creator: Information about the UM process which created the GEM. */
+	struct {
+		/** @creator.process_name: Group leader name in owning thread's process */
+		char process_name[TASK_COMM_LEN];
+
+		/** @creator.tgid: PID of the thread's group leader within its process */
+		pid_t tgid;
+	} creator;
+
+	/** @flags: Combination of panthor_debugfs_gem_usage_flags flags */
+	u32 flags;
+};
+
 /**
  * struct panthor_gem_object - Driver specific GEM object.
  */
@@ -62,6 +104,10 @@ struct panthor_gem_object {
 		/** @lock.str: Protects access to the @label.str field. */
 		struct mutex lock;
 	} label;
+
+#ifdef CONFIG_DEBUG_FS
+	struct panthor_gem_debugfs debugfs;
+#endif
 };
 
 /**
@@ -157,4 +203,17 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
 
 void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo);
 
+#ifdef CONFIG_DEBUG_FS
+void panthor_gem_debugfs_print_bos(struct panthor_device *pfdev,
+				   struct seq_file *m);
+static inline void
+panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags)
+{
+	bo->debugfs.flags = usage_flags | PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED;
+}
+
+#else
+void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) {};
+#endif
+
 #endif /* __PANTHOR_GEM_H__ */
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 1/4] drm/panthor: Introduce BO labeling
  2025-04-11 15:03 ` [PATCH v7 1/4] drm/panthor: Introduce BO labeling Adrián Larumbe
@ 2025-04-14  9:50   ` Steven Price
  2025-04-14 19:43     ` Adrián Larumbe
  0 siblings, 1 reply; 14+ messages in thread
From: Steven Price @ 2025-04-14  9:50 UTC (permalink / raw)
  To: Adrián Larumbe, To : Boris Brezillon, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, dri-devel, linux-kernel, linux-media, linaro-mm-sig

Hi Adrián,

On 11/04/2025 16:03, Adrián Larumbe wrote:
> Add a new character string Panthor BO field, and a function that allows
> setting it from within the driver.
> 
> Driver takes care of freeing the string when it's replaced or no longer
> needed at object destruction time, but allocating it is the responsibility
> of callers.
> 
> Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
>  drivers/gpu/drm/panthor/panthor_gem.c | 39 +++++++++++++++++++++++++++
>  drivers/gpu/drm/panthor/panthor_gem.h | 17 ++++++++++++
>  2 files changed, 56 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
> index 8244a4e6c2a2..af0ac17f357f 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.c
> +++ b/drivers/gpu/drm/panthor/panthor_gem.c
> @@ -2,6 +2,7 @@
>  /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
>  /* Copyright 2023 Collabora ltd. */
>  
> +#include <linux/cleanup.h>
>  #include <linux/dma-buf.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/err.h>
> @@ -18,6 +19,14 @@ static void panthor_gem_free_object(struct drm_gem_object *obj)
>  	struct panthor_gem_object *bo = to_panthor_bo(obj);
>  	struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem;
>  
> +	/*
> +	 * Label might have been allocated with kstrdup_const(),
> +	 * we need to take that into account when freeing the memory
> +	 */
> +	kfree_const(bo->label.str);
> +
> +	mutex_destroy(&bo->label.lock);
> +
>  	drm_gem_free_mmap_offset(&bo->base.base);
>  	mutex_destroy(&bo->gpuva_list_lock);
>  	drm_gem_shmem_free(&bo->base);
> @@ -196,6 +205,7 @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t
>  	obj->base.map_wc = !ptdev->coherent;
>  	mutex_init(&obj->gpuva_list_lock);
>  	drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock);
> +	mutex_init(&obj->label.lock);
>  
>  	return &obj->base.base;
>  }
> @@ -247,3 +257,32 @@ panthor_gem_create_with_handle(struct drm_file *file,
>  
>  	return ret;
>  }
> +
> +void
> +panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label)
> +{
> +	struct panthor_gem_object *bo = to_panthor_bo(obj);
> +	const char *old_label;
> +
> +	scoped_guard(mutex, &bo->label.lock) {
> +		old_label = bo->label.str;
> +		bo->label.str = label;
> +	}
> +
> +	kfree(old_label);

Shouldn't this be kfree_const()? I suspect as things stand we can't
trigger this bug but it's inconsistent.

> +}
> +
> +void
> +panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label)
> +{
> +	const char *str;
> +
> +	str = kstrdup_const(label, GFP_KERNEL);
> +	if (!str) {

In the next patch you permit user space to clear the label
(args->size==0) which means label==NULL and AFAICT kstrdup_const() will
return NULL in this case triggering this warning.

Thanks,
Steve

> +		/* Failing to allocate memory for a label isn't a fatal condition */
> +		drm_warn(bo->obj->dev, "Not enough memory to allocate BO label");
> +		return;
> +	}
> +
> +	panthor_gem_bo_set_label(bo->obj, str);
> +}
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
> index 1a363bb814f4..af0d77338860 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.h
> +++ b/drivers/gpu/drm/panthor/panthor_gem.h
> @@ -46,6 +46,20 @@ struct panthor_gem_object {
>  
>  	/** @flags: Combination of drm_panthor_bo_flags flags. */
>  	u32 flags;
> +
> +	/**
> +	 * @label: BO tagging fields. The label can be assigned within the
> +	 * driver itself or through a specific IOCTL.
> +	 */
> +	struct {
> +		/**
> +		 * @label.str: Pointer to NULL-terminated string,
> +		 */
> +		const char *str;
> +
> +		/** @lock.str: Protects access to the @label.str field. */
> +		struct mutex lock;
> +	} label;
>  };
>  
>  /**
> @@ -91,6 +105,9 @@ panthor_gem_create_with_handle(struct drm_file *file,
>  			       struct panthor_vm *exclusive_vm,
>  			       u64 *size, u32 flags, uint32_t *handle);
>  
> +void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label);
> +void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label);
> +
>  static inline u64
>  panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo)
>  {


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels
  2025-04-11 15:03 ` [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels Adrián Larumbe
@ 2025-04-14 10:01   ` Steven Price
  2025-04-14 20:41     ` Adrián Larumbe
  2025-04-15 11:07   ` Daniel Stone
  1 sibling, 1 reply; 14+ messages in thread
From: Steven Price @ 2025-04-14 10:01 UTC (permalink / raw)
  To: Adrián Larumbe, To : Boris Brezillon, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, dri-devel, linux-kernel, linux-media, linaro-mm-sig

On 11/04/2025 16:03, Adrián Larumbe wrote:
> Allow UM to label a BO for which it possesses a DRM handle.
> 
> Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

Reviewed-by: Steven Price <steven.price@arm.com>

Although very minor NITs below which you can consider.

> ---
>  drivers/gpu/drm/panthor/panthor_drv.c | 42 ++++++++++++++++++++++++++-
>  drivers/gpu/drm/panthor/panthor_gem.h |  2 ++
>  include/uapi/drm/panthor_drm.h        | 23 +++++++++++++++
>  3 files changed, 66 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
> index 06fe46e32073..983b24f1236c 100644
> --- a/drivers/gpu/drm/panthor/panthor_drv.c
> +++ b/drivers/gpu/drm/panthor/panthor_drv.c
> @@ -1331,6 +1331,44 @@ static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data,
>  	return 0;
>  }
>  
> +static int panthor_ioctl_bo_set_label(struct drm_device *ddev, void *data,
> +				  struct drm_file *file)
> +{
> +	struct drm_panthor_bo_set_label *args = data;
> +	struct drm_gem_object *obj;
> +	const char *label;
> +	int ret = 0;
> +
> +	obj = drm_gem_object_lookup(file, args->handle);
> +	if (!obj)
> +		return -ENOENT;
> +
> +	if (args->size && args->label) {
> +		if (args->size > PANTHOR_BO_LABEL_MAXLEN) {
> +			ret = -E2BIG;
> +			goto err_label;
> +		}
> +
> +		label = strndup_user(u64_to_user_ptr(args->label), args->size);
> +		if (IS_ERR(label)) {
> +			ret = PTR_ERR(label);
> +			goto err_label;
> +		}
> +	} else if (args->size && !args->label) {
> +		ret = -EINVAL;
> +		goto err_label;
> +	} else {
> +		label = NULL;
> +	}
> +
> +	panthor_gem_bo_set_label(obj, label);
> +
> +err_label:
> +	drm_gem_object_put(obj);
> +
> +	return ret;
> +}
> +
>  static int
>  panthor_open(struct drm_device *ddev, struct drm_file *file)
>  {
> @@ -1400,6 +1438,7 @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = {
>  	PANTHOR_IOCTL(TILER_HEAP_CREATE, tiler_heap_create, DRM_RENDER_ALLOW),
>  	PANTHOR_IOCTL(TILER_HEAP_DESTROY, tiler_heap_destroy, DRM_RENDER_ALLOW),
>  	PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW),
> +	PANTHOR_IOCTL(BO_SET_LABEL, bo_set_label, DRM_RENDER_ALLOW),
>  };
>  
>  static int panthor_mmap(struct file *filp, struct vm_area_struct *vma)
> @@ -1509,6 +1548,7 @@ static void panthor_debugfs_init(struct drm_minor *minor)
>   * - 1.2 - adds DEV_QUERY_GROUP_PRIORITIES_INFO query
>   *       - adds PANTHOR_GROUP_PRIORITY_REALTIME priority
>   * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag
> + * - 1.4 - adds DRM_IOCTL_PANTHOR_BO_SET_LABEL ioctl
>   */
>  static const struct drm_driver panthor_drm_driver = {
>  	.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ |
> @@ -1522,7 +1562,7 @@ static const struct drm_driver panthor_drm_driver = {
>  	.name = "panthor",
>  	.desc = "Panthor DRM driver",
>  	.major = 1,
> -	.minor = 3,
> +	.minor = 4,
>  
>  	.gem_create_object = panthor_gem_create_object,
>  	.gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
> index af0d77338860..beba066b4974 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.h
> +++ b/drivers/gpu/drm/panthor/panthor_gem.h
> @@ -13,6 +13,8 @@
>  
>  struct panthor_vm;
>  
> +#define PANTHOR_BO_LABEL_MAXLEN	PAGE_SIZE
> +
>  /**
>   * struct panthor_gem_object - Driver specific GEM object.
>   */
> diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
> index 97e2c4510e69..12b1994499a9 100644
> --- a/include/uapi/drm/panthor_drm.h
> +++ b/include/uapi/drm/panthor_drm.h
> @@ -127,6 +127,9 @@ enum drm_panthor_ioctl_id {
>  
>  	/** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */
>  	DRM_PANTHOR_TILER_HEAP_DESTROY,
> +
> +	/** @DRM_PANTHOR_BO_SET_LABEL: Label a BO. */
> +	DRM_PANTHOR_BO_SET_LABEL,
>  };
>  
>  /**
> @@ -977,6 +980,24 @@ struct drm_panthor_tiler_heap_destroy {
>  	__u32 pad;
>  };
>  
> +/**
> + * struct drm_panthor_bo_set_label - Arguments passed to DRM_IOCTL_PANTHOR_BO_SET_LABEL
> + */
> +struct drm_panthor_bo_set_label {
> +	/** @handle: Handle of the buffer object to label. */
> +	__u32 handle;
> +
> +	/**
> +	 * @size: Length of the label, including the NULL terminator.
> +	 *
> +	 * Cannot be greater than the OS page size.
> +	 */
> +	__u32 size;
> +
> +	/** @label: User pointer to a NULL-terminated string */
> +	__u64 label;
> +};

First very minor NIT:
 * NULL is a pointer, i.e. (void*)0
 * NUL is the ASCII code point '\0'.
So it's a NUL-terminated string.

Second NIT: We don't actually need 'size' - since the string is
NUL-terminated we can just strndup_user(__user_pointer__, PAGE_SIZE).
As things stand we validate that strlen(label) < size <= PAGE_SIZE -
which is a little odd (user space might as well just pass PAGE_SIZE
rather than calculate the actual length).

Thanks,
Steve

> +
>  /**
>   * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number
>   * @__access: Access type. Must be R, W or RW.
> @@ -1019,6 +1040,8 @@ enum {
>  		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create),
>  	DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY =
>  		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy),
> +	DRM_IOCTL_PANTHOR_BO_SET_LABEL =
> +		DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label),
>  };
>  
>  #if defined(__cplusplus)


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 3/4] drm/panthor: Label all kernel BO's
  2025-04-11 15:03 ` [PATCH v7 3/4] drm/panthor: Label all kernel BO's Adrián Larumbe
@ 2025-04-14 10:01   ` Steven Price
  2025-04-14 13:38   ` kernel test robot
  1 sibling, 0 replies; 14+ messages in thread
From: Steven Price @ 2025-04-14 10:01 UTC (permalink / raw)
  To: Adrián Larumbe, To : Boris Brezillon, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König
  Cc: kernel, dri-devel, linux-kernel, linux-media, linaro-mm-sig

On 11/04/2025 16:03, Adrián Larumbe wrote:
> Kernel BO's aren't exposed to UM, so labelling them is the responsibility
> of the driver itself. This kind of tagging will prove useful in further
> commits when want to expose these objects through DebugFS.
> 
> Expand panthor_kernel_bo_create() interface to take a NULL-terminated

NIT: s/NULL/NUL/

> string. No bounds checking is done because all label strings are given
> as statically-allocated literals, but if a more complex kernel BO naming
> scheme with explicit memory allocation and formatting was desired in the
> future, this would have to change.

I'm not sure I follow why bounds-checking would be an issue for strings
from the kernel. But as you state these are all literals so definitely
not a problem.

> 
> Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>

Reviewed-by: Steven Price <steven.price@arm.com>

> ---
>  drivers/gpu/drm/panthor/panthor_fw.c    | 8 +++++---
>  drivers/gpu/drm/panthor/panthor_gem.c   | 4 +++-
>  drivers/gpu/drm/panthor/panthor_gem.h   | 2 +-
>  drivers/gpu/drm/panthor/panthor_heap.c  | 6 ++++--
>  drivers/gpu/drm/panthor/panthor_sched.c | 9 ++++++---
>  5 files changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c
> index 0f52766a3120..a7fdc4d8020d 100644
> --- a/drivers/gpu/drm/panthor/panthor_fw.c
> +++ b/drivers/gpu/drm/panthor/panthor_fw.c
> @@ -449,7 +449,8 @@ panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev,
>  				       DRM_PANTHOR_BO_NO_MMAP,
>  				       DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
>  				       DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
> -				       PANTHOR_VM_KERNEL_AUTO_VA);
> +				       PANTHOR_VM_KERNEL_AUTO_VA,
> +				       "Queue FW interface");
>  	if (IS_ERR(mem))
>  		return mem;
>  
> @@ -481,7 +482,8 @@ panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size)
>  	return panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), size,
>  					DRM_PANTHOR_BO_NO_MMAP,
>  					DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
> -					PANTHOR_VM_KERNEL_AUTO_VA);
> +					PANTHOR_VM_KERNEL_AUTO_VA,
> +					"FW suspend buffer");
>  }
>  
>  static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
> @@ -601,7 +603,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
>  		section->mem = panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev),
>  							section_size,
>  							DRM_PANTHOR_BO_NO_MMAP,
> -							vm_map_flags, va);
> +							vm_map_flags, va, "FW section");
>  		if (IS_ERR(section->mem))
>  			return PTR_ERR(section->mem);
>  
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
> index af0ac17f357f..3c5fc854356e 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.c
> +++ b/drivers/gpu/drm/panthor/panthor_gem.c
> @@ -82,7 +82,7 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo)
>  struct panthor_kernel_bo *
>  panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
>  			 size_t size, u32 bo_flags, u32 vm_map_flags,
> -			 u64 gpu_va)
> +			 u64 gpu_va, const char *name)
>  {
>  	struct drm_gem_shmem_object *obj;
>  	struct panthor_kernel_bo *kbo;
> @@ -106,6 +106,8 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
>  	kbo->obj = &obj->base;
>  	bo->flags = bo_flags;
>  
> +	panthor_gem_kernel_bo_set_label(kbo, name);
> +
>  	/* The system and GPU MMU page size might differ, which becomes a
>  	 * problem for FW sections that need to be mapped at explicit address
>  	 * since our PAGE_SIZE alignment might cover a VA range that's
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
> index beba066b4974..62aea06dbc6d 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.h
> +++ b/drivers/gpu/drm/panthor/panthor_gem.h
> @@ -153,7 +153,7 @@ panthor_kernel_bo_vunmap(struct panthor_kernel_bo *bo)
>  struct panthor_kernel_bo *
>  panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
>  			 size_t size, u32 bo_flags, u32 vm_map_flags,
> -			 u64 gpu_va);
> +			 u64 gpu_va, const char *name);
>  
>  void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo);
>  
> diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c
> index 3bdf61c14264..d236e9ceade4 100644
> --- a/drivers/gpu/drm/panthor/panthor_heap.c
> +++ b/drivers/gpu/drm/panthor/panthor_heap.c
> @@ -151,7 +151,8 @@ static int panthor_alloc_heap_chunk(struct panthor_heap_pool *pool,
>  	chunk->bo = panthor_kernel_bo_create(pool->ptdev, pool->vm, heap->chunk_size,
>  					     DRM_PANTHOR_BO_NO_MMAP,
>  					     DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
> -					     PANTHOR_VM_KERNEL_AUTO_VA);
> +					     PANTHOR_VM_KERNEL_AUTO_VA,
> +					     "Tiler heap chunk");
>  	if (IS_ERR(chunk->bo)) {
>  		ret = PTR_ERR(chunk->bo);
>  		goto err_free_chunk;
> @@ -555,7 +556,8 @@ panthor_heap_pool_create(struct panthor_device *ptdev, struct panthor_vm *vm)
>  	pool->gpu_contexts = panthor_kernel_bo_create(ptdev, vm, bosize,
>  						      DRM_PANTHOR_BO_NO_MMAP,
>  						      DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC,
> -						      PANTHOR_VM_KERNEL_AUTO_VA);
> +						      PANTHOR_VM_KERNEL_AUTO_VA,
> +						      "Heap pool");
>  	if (IS_ERR(pool->gpu_contexts)) {
>  		ret = PTR_ERR(pool->gpu_contexts);
>  		goto err_destroy_pool;
> diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
> index 446ec780eb4a..43ee57728de5 100644
> --- a/drivers/gpu/drm/panthor/panthor_sched.c
> +++ b/drivers/gpu/drm/panthor/panthor_sched.c
> @@ -3332,7 +3332,8 @@ group_create_queue(struct panthor_group *group,
>  						  DRM_PANTHOR_BO_NO_MMAP,
>  						  DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
>  						  DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
> -						  PANTHOR_VM_KERNEL_AUTO_VA);
> +						  PANTHOR_VM_KERNEL_AUTO_VA,
> +						  "CS ring buffer");
>  	if (IS_ERR(queue->ringbuf)) {
>  		ret = PTR_ERR(queue->ringbuf);
>  		goto err_free_queue;
> @@ -3362,7 +3363,8 @@ group_create_queue(struct panthor_group *group,
>  					 DRM_PANTHOR_BO_NO_MMAP,
>  					 DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
>  					 DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
> -					 PANTHOR_VM_KERNEL_AUTO_VA);
> +					 PANTHOR_VM_KERNEL_AUTO_VA,
> +					 "Group job stats");
>  
>  	if (IS_ERR(queue->profiling.slots)) {
>  		ret = PTR_ERR(queue->profiling.slots);
> @@ -3493,7 +3495,8 @@ int panthor_group_create(struct panthor_file *pfile,
>  						   DRM_PANTHOR_BO_NO_MMAP,
>  						   DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC |
>  						   DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED,
> -						   PANTHOR_VM_KERNEL_AUTO_VA);
> +						   PANTHOR_VM_KERNEL_AUTO_VA,
> +						   "Group sync objects");
>  	if (IS_ERR(group->syncobjs)) {
>  		ret = PTR_ERR(group->syncobjs);
>  		goto err_put_group;


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 3/4] drm/panthor: Label all kernel BO's
  2025-04-11 15:03 ` [PATCH v7 3/4] drm/panthor: Label all kernel BO's Adrián Larumbe
  2025-04-14 10:01   ` Steven Price
@ 2025-04-14 13:38   ` kernel test robot
  1 sibling, 0 replies; 14+ messages in thread
From: kernel test robot @ 2025-04-14 13:38 UTC (permalink / raw)
  To: Adrián Larumbe, To : Boris Brezillon, Steven Price,
	Liviu Dudau, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Simona Vetter, Sumit Semwal, Christian König
  Cc: oe-kbuild-all, kernel, Adrián Larumbe, dri-devel,
	linux-kernel, linux-media, linaro-mm-sig

Hi Adrián,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.15-rc2 next-20250414]
[cannot apply to drm-misc/drm-misc-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Adri-n-Larumbe/drm-panthor-Introduce-BO-labeling/20250414-101541
base:   linus/master
patch link:    https://lore.kernel.org/r/20250411150357.3308921-4-adrian.larumbe%40collabora.com
patch subject: [PATCH v7 3/4] drm/panthor: Label all kernel BO's
config: i386-buildonly-randconfig-006-20250414 (https://download.01.org/0day-ci/archive/20250414/202504142148.NBAyzLuE-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250414/202504142148.NBAyzLuE-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504142148.NBAyzLuE-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/panthor/panthor_gem.c:86: warning: Function parameter or struct member 'name' not described in 'panthor_kernel_bo_create'


vim +86 drivers/gpu/drm/panthor/panthor_gem.c

8a1cc07578bf42 Boris Brezillon 2024-02-29   67  
8a1cc07578bf42 Boris Brezillon 2024-02-29   68  /**
8a1cc07578bf42 Boris Brezillon 2024-02-29   69   * panthor_kernel_bo_create() - Create and map a GEM object to a VM
8a1cc07578bf42 Boris Brezillon 2024-02-29   70   * @ptdev: Device.
8a1cc07578bf42 Boris Brezillon 2024-02-29   71   * @vm: VM to map the GEM to. If NULL, the kernel object is not GPU mapped.
8a1cc07578bf42 Boris Brezillon 2024-02-29   72   * @size: Size of the buffer object.
8a1cc07578bf42 Boris Brezillon 2024-02-29   73   * @bo_flags: Combination of drm_panthor_bo_flags flags.
8a1cc07578bf42 Boris Brezillon 2024-02-29   74   * @vm_map_flags: Combination of drm_panthor_vm_bind_op_flags (only those
8a1cc07578bf42 Boris Brezillon 2024-02-29   75   * that are related to map operations).
8a1cc07578bf42 Boris Brezillon 2024-02-29   76   * @gpu_va: GPU address assigned when mapping to the VM.
8a1cc07578bf42 Boris Brezillon 2024-02-29   77   * If gpu_va == PANTHOR_VM_KERNEL_AUTO_VA, the virtual address will be
8a1cc07578bf42 Boris Brezillon 2024-02-29   78   * automatically allocated.
8a1cc07578bf42 Boris Brezillon 2024-02-29   79   *
8a1cc07578bf42 Boris Brezillon 2024-02-29   80   * Return: A valid pointer in case of success, an ERR_PTR() otherwise.
8a1cc07578bf42 Boris Brezillon 2024-02-29   81   */
8a1cc07578bf42 Boris Brezillon 2024-02-29   82  struct panthor_kernel_bo *
8a1cc07578bf42 Boris Brezillon 2024-02-29   83  panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
8a1cc07578bf42 Boris Brezillon 2024-02-29   84  			 size_t size, u32 bo_flags, u32 vm_map_flags,
f48f05d54f7696 Adrián Larumbe  2025-04-11   85  			 u64 gpu_va, const char *name)
8a1cc07578bf42 Boris Brezillon 2024-02-29  @86  {
8a1cc07578bf42 Boris Brezillon 2024-02-29   87  	struct drm_gem_shmem_object *obj;
8a1cc07578bf42 Boris Brezillon 2024-02-29   88  	struct panthor_kernel_bo *kbo;
8a1cc07578bf42 Boris Brezillon 2024-02-29   89  	struct panthor_gem_object *bo;
8a1cc07578bf42 Boris Brezillon 2024-02-29   90  	int ret;
8a1cc07578bf42 Boris Brezillon 2024-02-29   91  
8a1cc07578bf42 Boris Brezillon 2024-02-29   92  	if (drm_WARN_ON(&ptdev->base, !vm))
8a1cc07578bf42 Boris Brezillon 2024-02-29   93  		return ERR_PTR(-EINVAL);
8a1cc07578bf42 Boris Brezillon 2024-02-29   94  
8a1cc07578bf42 Boris Brezillon 2024-02-29   95  	kbo = kzalloc(sizeof(*kbo), GFP_KERNEL);
8a1cc07578bf42 Boris Brezillon 2024-02-29   96  	if (!kbo)
8a1cc07578bf42 Boris Brezillon 2024-02-29   97  		return ERR_PTR(-ENOMEM);
8a1cc07578bf42 Boris Brezillon 2024-02-29   98  
8a1cc07578bf42 Boris Brezillon 2024-02-29   99  	obj = drm_gem_shmem_create(&ptdev->base, size);
8a1cc07578bf42 Boris Brezillon 2024-02-29  100  	if (IS_ERR(obj)) {
8a1cc07578bf42 Boris Brezillon 2024-02-29  101  		ret = PTR_ERR(obj);
8a1cc07578bf42 Boris Brezillon 2024-02-29  102  		goto err_free_bo;
8a1cc07578bf42 Boris Brezillon 2024-02-29  103  	}
8a1cc07578bf42 Boris Brezillon 2024-02-29  104  
8a1cc07578bf42 Boris Brezillon 2024-02-29  105  	bo = to_panthor_bo(&obj->base);
8a1cc07578bf42 Boris Brezillon 2024-02-29  106  	kbo->obj = &obj->base;
8a1cc07578bf42 Boris Brezillon 2024-02-29  107  	bo->flags = bo_flags;
8a1cc07578bf42 Boris Brezillon 2024-02-29  108  
f48f05d54f7696 Adrián Larumbe  2025-04-11  109  	panthor_gem_kernel_bo_set_label(kbo, name);
f48f05d54f7696 Adrián Larumbe  2025-04-11  110  
5d01b56f0518d8 Boris Brezillon 2024-10-30  111  	/* The system and GPU MMU page size might differ, which becomes a
5d01b56f0518d8 Boris Brezillon 2024-10-30  112  	 * problem for FW sections that need to be mapped at explicit address
5d01b56f0518d8 Boris Brezillon 2024-10-30  113  	 * since our PAGE_SIZE alignment might cover a VA range that's
5d01b56f0518d8 Boris Brezillon 2024-10-30  114  	 * expected to be used for another section.
5d01b56f0518d8 Boris Brezillon 2024-10-30  115  	 * Make sure we never map more than we need.
5d01b56f0518d8 Boris Brezillon 2024-10-30  116  	 */
5d01b56f0518d8 Boris Brezillon 2024-10-30  117  	size = ALIGN(size, panthor_vm_page_size(vm));
8a1cc07578bf42 Boris Brezillon 2024-02-29  118  	ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node);
8a1cc07578bf42 Boris Brezillon 2024-02-29  119  	if (ret)
8a1cc07578bf42 Boris Brezillon 2024-02-29  120  		goto err_put_obj;
8a1cc07578bf42 Boris Brezillon 2024-02-29  121  
8a1cc07578bf42 Boris Brezillon 2024-02-29  122  	ret = panthor_vm_map_bo_range(vm, bo, 0, size, kbo->va_node.start, vm_map_flags);
8a1cc07578bf42 Boris Brezillon 2024-02-29  123  	if (ret)
8a1cc07578bf42 Boris Brezillon 2024-02-29  124  		goto err_free_va;
8a1cc07578bf42 Boris Brezillon 2024-02-29  125  
ff60c8da0aaf7e Boris Brezillon 2024-05-02  126  	kbo->vm = panthor_vm_get(vm);
8a1cc07578bf42 Boris Brezillon 2024-02-29  127  	bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm);
8a1cc07578bf42 Boris Brezillon 2024-02-29  128  	drm_gem_object_get(bo->exclusive_vm_root_gem);
8a1cc07578bf42 Boris Brezillon 2024-02-29  129  	bo->base.base.resv = bo->exclusive_vm_root_gem->resv;
8a1cc07578bf42 Boris Brezillon 2024-02-29  130  	return kbo;
8a1cc07578bf42 Boris Brezillon 2024-02-29  131  
8a1cc07578bf42 Boris Brezillon 2024-02-29  132  err_free_va:
8a1cc07578bf42 Boris Brezillon 2024-02-29  133  	panthor_vm_free_va(vm, &kbo->va_node);
8a1cc07578bf42 Boris Brezillon 2024-02-29  134  
8a1cc07578bf42 Boris Brezillon 2024-02-29  135  err_put_obj:
8a1cc07578bf42 Boris Brezillon 2024-02-29  136  	drm_gem_object_put(&obj->base);
8a1cc07578bf42 Boris Brezillon 2024-02-29  137  
8a1cc07578bf42 Boris Brezillon 2024-02-29  138  err_free_bo:
8a1cc07578bf42 Boris Brezillon 2024-02-29  139  	kfree(kbo);
8a1cc07578bf42 Boris Brezillon 2024-02-29  140  	return ERR_PTR(ret);
8a1cc07578bf42 Boris Brezillon 2024-02-29  141  }
8a1cc07578bf42 Boris Brezillon 2024-02-29  142  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 1/4] drm/panthor: Introduce BO labeling
  2025-04-14  9:50   ` Steven Price
@ 2025-04-14 19:43     ` Adrián Larumbe
  2025-04-16  9:14       ` Steven Price
  0 siblings, 1 reply; 14+ messages in thread
From: Adrián Larumbe @ 2025-04-14 19:43 UTC (permalink / raw)
  To: Steven Price
  Cc: Boris Brezillon, Liviu Dudau, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Sumit Semwal,
	Christian König, kernel, dri-devel, linux-kernel,
	linux-media, linaro-mm-sig

Hi Steven,

On 14.04.2025 10:50, Steven Price wrote:
> Hi Adrián,
>
> On 11/04/2025 16:03, Adrián Larumbe wrote:
> > Add a new character string Panthor BO field, and a function that allows
> > setting it from within the driver.
> >
> > Driver takes care of freeing the string when it's replaced or no longer
> > needed at object destruction time, but allocating it is the responsibility
> > of callers.
> >
> > Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
> > Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
> > ---
> >  drivers/gpu/drm/panthor/panthor_gem.c | 39 +++++++++++++++++++++++++++
> >  drivers/gpu/drm/panthor/panthor_gem.h | 17 ++++++++++++
> >  2 files changed, 56 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
> > index 8244a4e6c2a2..af0ac17f357f 100644
> > --- a/drivers/gpu/drm/panthor/panthor_gem.c
> > +++ b/drivers/gpu/drm/panthor/panthor_gem.c
> > @@ -2,6 +2,7 @@
> >  /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
> >  /* Copyright 2023 Collabora ltd. */
> >
> > +#include <linux/cleanup.h>
> >  #include <linux/dma-buf.h>
> >  #include <linux/dma-mapping.h>
> >  #include <linux/err.h>
> > @@ -18,6 +19,14 @@ static void panthor_gem_free_object(struct drm_gem_object *obj)
> >  	struct panthor_gem_object *bo = to_panthor_bo(obj);
> >  	struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem;
> >
> > +	/*
> > +	 * Label might have been allocated with kstrdup_const(),
> > +	 * we need to take that into account when freeing the memory
> > +	 */
> > +	kfree_const(bo->label.str);
> > +
> > +	mutex_destroy(&bo->label.lock);
> > +
> >  	drm_gem_free_mmap_offset(&bo->base.base);
> >  	mutex_destroy(&bo->gpuva_list_lock);
> >  	drm_gem_shmem_free(&bo->base);
> > @@ -196,6 +205,7 @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t
> >  	obj->base.map_wc = !ptdev->coherent;
> >  	mutex_init(&obj->gpuva_list_lock);
> >  	drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock);
> > +	mutex_init(&obj->label.lock);
> >
> >  	return &obj->base.base;
> >  }
> > @@ -247,3 +257,32 @@ panthor_gem_create_with_handle(struct drm_file *file,
> >
> >  	return ret;
> >  }
> > +
> > +void
> > +panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label)
> > +{
> > +	struct panthor_gem_object *bo = to_panthor_bo(obj);
> > +	const char *old_label;
> > +
> > +	scoped_guard(mutex, &bo->label.lock) {
> > +		old_label = bo->label.str;
> > +		bo->label.str = label;
> > +	}
> > +
> > +	kfree(old_label);
>
> Shouldn't this be kfree_const()? I suspect as things stand we can't
> trigger this bug but it's inconsistent.

This could only be called either from the set_label() ioctl, in which case
old_label could be NULL or a pointer to a string obtained from strdup(); or from
panthor_gem_kernel_bo_set_label(). In the latter case, it could only ever be
NULL, since we don't reassign kernel BO labels, so it'd be safe too.

However I do agree that it's not consistent, and then in the future perhaps
relabelling kernel BO's might be justified, so I'll change it to kfree_const().

> > +}
> > +
> > +void
> > +panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label)
> > +{
> > +	const char *str;
> > +
> > +	str = kstrdup_const(label, GFP_KERNEL);
> > +	if (!str) {
>
> In the next patch you permit user space to clear the label
> (args->size==0) which means label==NULL and AFAICT kstrdup_const() will
> return NULL in this case triggering this warning.

Kernel and UM-exposed BO's should never experience cross-labelling, so in theory
this scenario ought to be impossible. The only way panthor_gem_kernel_bo_set_label()
might take NULL in the 'label' argument is that someone called panthor_kernel_bo_create()
with NULL for its name 'argument'.

I think as a defensive check, I could do something as follows

void
panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label)
{
	const char *str;

	/* We should never attempt labelling a UM-exposed GEM object */
	if (drm_WARN_ON(bo->obj->dev, &bo->obj->handle_count > 0))
		return;

	if (!label)
		return;

       [...]
}

> Thanks,
> Steve
>
> > +		/* Failing to allocate memory for a label isn't a fatal condition */
> > +		drm_warn(bo->obj->dev, "Not enough memory to allocate BO label");
> > +		return;
> > +	}
> > +
> > +	panthor_gem_bo_set_label(bo->obj, str);
> > +}
> > diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
> > index 1a363bb814f4..af0d77338860 100644
> > --- a/drivers/gpu/drm/panthor/panthor_gem.h
> > +++ b/drivers/gpu/drm/panthor/panthor_gem.h
> > @@ -46,6 +46,20 @@ struct panthor_gem_object {
> >
> >  	/** @flags: Combination of drm_panthor_bo_flags flags. */
> >  	u32 flags;
> > +
> > +	/**
> > +	 * @label: BO tagging fields. The label can be assigned within the
> > +	 * driver itself or through a specific IOCTL.
> > +	 */
> > +	struct {
> > +		/**
> > +		 * @label.str: Pointer to NULL-terminated string,
> > +		 */
> > +		const char *str;
> > +
> > +		/** @lock.str: Protects access to the @label.str field. */
> > +		struct mutex lock;
> > +	} label;
> >  };
> >
> >  /**
> > @@ -91,6 +105,9 @@ panthor_gem_create_with_handle(struct drm_file *file,
> >  			       struct panthor_vm *exclusive_vm,
> >  			       u64 *size, u32 flags, uint32_t *handle);
> >
> > +void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label);
> > +void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label);
> > +
> >  static inline u64
> >  panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo)
> >  {

Adrian Larumbe

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels
  2025-04-14 10:01   ` Steven Price
@ 2025-04-14 20:41     ` Adrián Larumbe
  2025-04-16  9:22       ` Steven Price
  0 siblings, 1 reply; 14+ messages in thread
From: Adrián Larumbe @ 2025-04-14 20:41 UTC (permalink / raw)
  To: Steven Price
  Cc: Boris Brezillon, Liviu Dudau, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Sumit Semwal,
	Christian König, kernel, dri-devel, linux-kernel,
	linux-media, linaro-mm-sig

On 14.04.2025 11:01, Steven Price wrote:
> On 11/04/2025 16:03, Adrián Larumbe wrote:
> > Allow UM to label a BO for which it possesses a DRM handle.
> >
> > Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
> > Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
> > Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
>
> Reviewed-by: Steven Price <steven.price@arm.com>
>
> Although very minor NITs below which you can consider.
>
> > ---
> >  drivers/gpu/drm/panthor/panthor_drv.c | 42 ++++++++++++++++++++++++++-
> >  drivers/gpu/drm/panthor/panthor_gem.h |  2 ++
> >  include/uapi/drm/panthor_drm.h        | 23 +++++++++++++++
> >  3 files changed, 66 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
> > index 06fe46e32073..983b24f1236c 100644
> > --- a/drivers/gpu/drm/panthor/panthor_drv.c
> > +++ b/drivers/gpu/drm/panthor/panthor_drv.c
> > @@ -1331,6 +1331,44 @@ static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data,
> >  	return 0;
> >  }
> >
> > +static int panthor_ioctl_bo_set_label(struct drm_device *ddev, void *data,
> > +				  struct drm_file *file)
> > +{
> > +	struct drm_panthor_bo_set_label *args = data;
> > +	struct drm_gem_object *obj;
> > +	const char *label;
> > +	int ret = 0;
> > +
> > +	obj = drm_gem_object_lookup(file, args->handle);
> > +	if (!obj)
> > +		return -ENOENT;
> > +
> > +	if (args->size && args->label) {
> > +		if (args->size > PANTHOR_BO_LABEL_MAXLEN) {
> > +			ret = -E2BIG;
> > +			goto err_label;
> > +		}
> > +
> > +		label = strndup_user(u64_to_user_ptr(args->label), args->size);
> > +		if (IS_ERR(label)) {
> > +			ret = PTR_ERR(label);
> > +			goto err_label;
> > +		}
> > +	} else if (args->size && !args->label) {
> > +		ret = -EINVAL;
> > +		goto err_label;
> > +	} else {
> > +		label = NULL;
> > +	}
> > +
> > +	panthor_gem_bo_set_label(obj, label);
> > +
> > +err_label:
> > +	drm_gem_object_put(obj);
> > +
> > +	return ret;
> > +}
> > +
> >  static int
> >  panthor_open(struct drm_device *ddev, struct drm_file *file)
> >  {
> > @@ -1400,6 +1438,7 @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = {
> >  	PANTHOR_IOCTL(TILER_HEAP_CREATE, tiler_heap_create, DRM_RENDER_ALLOW),
> >  	PANTHOR_IOCTL(TILER_HEAP_DESTROY, tiler_heap_destroy, DRM_RENDER_ALLOW),
> >  	PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW),
> > +	PANTHOR_IOCTL(BO_SET_LABEL, bo_set_label, DRM_RENDER_ALLOW),
> >  };
> >
> >  static int panthor_mmap(struct file *filp, struct vm_area_struct *vma)
> > @@ -1509,6 +1548,7 @@ static void panthor_debugfs_init(struct drm_minor *minor)
> >   * - 1.2 - adds DEV_QUERY_GROUP_PRIORITIES_INFO query
> >   *       - adds PANTHOR_GROUP_PRIORITY_REALTIME priority
> >   * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag
> > + * - 1.4 - adds DRM_IOCTL_PANTHOR_BO_SET_LABEL ioctl
> >   */
> >  static const struct drm_driver panthor_drm_driver = {
> >  	.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ |
> > @@ -1522,7 +1562,7 @@ static const struct drm_driver panthor_drm_driver = {
> >  	.name = "panthor",
> >  	.desc = "Panthor DRM driver",
> >  	.major = 1,
> > -	.minor = 3,
> > +	.minor = 4,
> >
> >  	.gem_create_object = panthor_gem_create_object,
> >  	.gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
> > diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
> > index af0d77338860..beba066b4974 100644
> > --- a/drivers/gpu/drm/panthor/panthor_gem.h
> > +++ b/drivers/gpu/drm/panthor/panthor_gem.h
> > @@ -13,6 +13,8 @@
> >
> >  struct panthor_vm;
> >
> > +#define PANTHOR_BO_LABEL_MAXLEN	PAGE_SIZE
> > +
> >  /**
> >   * struct panthor_gem_object - Driver specific GEM object.
> >   */
> > diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
> > index 97e2c4510e69..12b1994499a9 100644
> > --- a/include/uapi/drm/panthor_drm.h
> > +++ b/include/uapi/drm/panthor_drm.h
> > @@ -127,6 +127,9 @@ enum drm_panthor_ioctl_id {
> >
> >  	/** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */
> >  	DRM_PANTHOR_TILER_HEAP_DESTROY,
> > +
> > +	/** @DRM_PANTHOR_BO_SET_LABEL: Label a BO. */
> > +	DRM_PANTHOR_BO_SET_LABEL,
> >  };
> >
> >  /**
> > @@ -977,6 +980,24 @@ struct drm_panthor_tiler_heap_destroy {
> >  	__u32 pad;
> >  };
> >
> > +/**
> > + * struct drm_panthor_bo_set_label - Arguments passed to DRM_IOCTL_PANTHOR_BO_SET_LABEL
> > + */
> > +struct drm_panthor_bo_set_label {
> > +	/** @handle: Handle of the buffer object to label. */
> > +	__u32 handle;
> > +
> > +	/**
> > +	 * @size: Length of the label, including the NULL terminator.
> > +	 *
> > +	 * Cannot be greater than the OS page size.
> > +	 */
> > +	__u32 size;
> > +
> > +	/** @label: User pointer to a NULL-terminated string */
> > +	__u64 label;
> > +};
>
> First very minor NIT:
>  * NULL is a pointer, i.e. (void*)0
>  * NUL is the ASCII code point '\0'.
> So it's a NUL-terminated string.

Fixed

> Second NIT: We don't actually need 'size' - since the string is
> NUL-terminated we can just strndup_user(__user_pointer__, PAGE_SIZE).
> As things stand we validate that strlen(label) < size <= PAGE_SIZE -
> which is a little odd (user space might as well just pass PAGE_SIZE
> rather than calculate the actual length).

The snag I see in this approach is that the only way to make sure
strlen(label) + 1 <= PAGE_SIZE would be doing something like

label = strndup_user(u64_to_user_ptr(args->label), args->size);
if (strlen(label) + 1 <= PAGE_SIZE) {
   kfree(label)
   return -E2BIG;
}

In the meantime, we've duplicated the string and traversed a whole page
of bytes, all to be discarded at once.

In this case, I think it's alright to expect some cooperation from UM
in supplying the actual size, although I'm really not an expert in
designing elegant uAPIs, so if you think this looks very odd I'd be
glad to replace it with.

Actually, as I was writing this, I realised that strndup_user() calls
strnlen_user(), which is publicly available for other drivers, so
I might check the length first, and if it falls within bounds, do
the actual user stringdup.

I shall also mention the size bound on the uAPI for the 'label' pointer.

> Thanks,
> Steve
>
> +
>  /**
>   * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number
>   * @__access: Access type. Must be R, W or RW.
> @@ -1019,6 +1040,8 @@ enum {
>  		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create),
>  	DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY =
>  		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy),
> +	DRM_IOCTL_PANTHOR_BO_SET_LABEL =
> +		DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label),
>  };
>
>  #if defined(__cplusplus)


Adrian Larumbe

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels
  2025-04-11 15:03 ` [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels Adrián Larumbe
  2025-04-14 10:01   ` Steven Price
@ 2025-04-15 11:07   ` Daniel Stone
  1 sibling, 0 replies; 14+ messages in thread
From: Daniel Stone @ 2025-04-15 11:07 UTC (permalink / raw)
  To: Adrián Larumbe
  Cc: To : Boris Brezillon, Steven Price, Liviu Dudau,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Sumit Semwal, Christian König, kernel,
	dri-devel, linux-kernel, linux-media, linaro-mm-sig

Hi,

On Fri, 11 Apr 2025 at 16:05, Adrián Larumbe
<adrian.larumbe@collabora.com> wrote:
> +#define PANTHOR_BO_LABEL_MAXLEN        PAGE_SIZE

PAGE_SIZE can change between kernel builds with a config setting.

If the thinking here is '4KiB is big enough' (which I agree with),
then just define it to 4096.

Cheers,
Daniel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 1/4] drm/panthor: Introduce BO labeling
  2025-04-14 19:43     ` Adrián Larumbe
@ 2025-04-16  9:14       ` Steven Price
  0 siblings, 0 replies; 14+ messages in thread
From: Steven Price @ 2025-04-16  9:14 UTC (permalink / raw)
  To: Adrián Larumbe
  Cc: Boris Brezillon, Liviu Dudau, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Sumit Semwal,
	Christian König, kernel, dri-devel, linux-kernel,
	linux-media, linaro-mm-sig

On 14/04/2025 20:43, Adrián Larumbe wrote:
> Hi Steven,
> 
> On 14.04.2025 10:50, Steven Price wrote:
>> Hi Adrián,
>>
>> On 11/04/2025 16:03, Adrián Larumbe wrote:
>>> Add a new character string Panthor BO field, and a function that allows
>>> setting it from within the driver.
>>>
>>> Driver takes care of freeing the string when it's replaced or no longer
>>> needed at object destruction time, but allocating it is the responsibility
>>> of callers.
>>>
>>> Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
>>> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
>>> ---
>>>  drivers/gpu/drm/panthor/panthor_gem.c | 39 +++++++++++++++++++++++++++
>>>  drivers/gpu/drm/panthor/panthor_gem.h | 17 ++++++++++++
>>>  2 files changed, 56 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
>>> index 8244a4e6c2a2..af0ac17f357f 100644
>>> --- a/drivers/gpu/drm/panthor/panthor_gem.c
>>> +++ b/drivers/gpu/drm/panthor/panthor_gem.c
>>> @@ -2,6 +2,7 @@
>>>  /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
>>>  /* Copyright 2023 Collabora ltd. */
>>>
>>> +#include <linux/cleanup.h>
>>>  #include <linux/dma-buf.h>
>>>  #include <linux/dma-mapping.h>
>>>  #include <linux/err.h>
>>> @@ -18,6 +19,14 @@ static void panthor_gem_free_object(struct drm_gem_object *obj)
>>>  	struct panthor_gem_object *bo = to_panthor_bo(obj);
>>>  	struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem;
>>>
>>> +	/*
>>> +	 * Label might have been allocated with kstrdup_const(),
>>> +	 * we need to take that into account when freeing the memory
>>> +	 */
>>> +	kfree_const(bo->label.str);
>>> +
>>> +	mutex_destroy(&bo->label.lock);
>>> +
>>>  	drm_gem_free_mmap_offset(&bo->base.base);
>>>  	mutex_destroy(&bo->gpuva_list_lock);
>>>  	drm_gem_shmem_free(&bo->base);
>>> @@ -196,6 +205,7 @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t
>>>  	obj->base.map_wc = !ptdev->coherent;
>>>  	mutex_init(&obj->gpuva_list_lock);
>>>  	drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock);
>>> +	mutex_init(&obj->label.lock);
>>>
>>>  	return &obj->base.base;
>>>  }
>>> @@ -247,3 +257,32 @@ panthor_gem_create_with_handle(struct drm_file *file,
>>>
>>>  	return ret;
>>>  }
>>> +
>>> +void
>>> +panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label)
>>> +{
>>> +	struct panthor_gem_object *bo = to_panthor_bo(obj);
>>> +	const char *old_label;
>>> +
>>> +	scoped_guard(mutex, &bo->label.lock) {
>>> +		old_label = bo->label.str;
>>> +		bo->label.str = label;
>>> +	}
>>> +
>>> +	kfree(old_label);
>>
>> Shouldn't this be kfree_const()? I suspect as things stand we can't
>> trigger this bug but it's inconsistent.
> 
> This could only be called either from the set_label() ioctl, in which case
> old_label could be NULL or a pointer to a string obtained from strdup(); or from
> panthor_gem_kernel_bo_set_label(). In the latter case, it could only ever be
> NULL, since we don't reassign kernel BO labels, so it'd be safe too.

Yeah I thought it probably doesn't cause problems now, but it's a foot
gun for the future.

> However I do agree that it's not consistent, and then in the future perhaps
> relabelling kernel BO's might be justified, so I'll change it to kfree_const().

Thanks!

>>> +}
>>> +
>>> +void
>>> +panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label)
>>> +{
>>> +	const char *str;
>>> +
>>> +	str = kstrdup_const(label, GFP_KERNEL);
>>> +	if (!str) {
>>
>> In the next patch you permit user space to clear the label
>> (args->size==0) which means label==NULL and AFAICT kstrdup_const() will
>> return NULL in this case triggering this warning.
> 
> Kernel and UM-exposed BO's should never experience cross-labelling, so in theory
> this scenario ought to be impossible. The only way panthor_gem_kernel_bo_set_label()
> might take NULL in the 'label' argument is that someone called panthor_kernel_bo_create()
> with NULL for its name 'argument'.

You're absolutely correct - I somehow got confused between the kernel
and user paths. It's the user path above which needs to handle NULL (and
does).

> I think as a defensive check, I could do something as follows
> 
> void
> panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label)
> {
> 	const char *str;
> 
> 	/* We should never attempt labelling a UM-exposed GEM object */
> 	if (drm_WARN_ON(bo->obj->dev, &bo->obj->handle_count > 0))
> 		return;
> 
> 	if (!label)
> 		return;
> 
>        [...]
> }

I'm happy for you to do nothing here - that was my mistake getting the
two functions muddled. Sorry for the noise. I'm equally happy for the
defensive checks above.

Steve

>> Thanks,
>> Steve
>>
>>> +		/* Failing to allocate memory for a label isn't a fatal condition */
>>> +		drm_warn(bo->obj->dev, "Not enough memory to allocate BO label");
>>> +		return;
>>> +	}
>>> +
>>> +	panthor_gem_bo_set_label(bo->obj, str);
>>> +}
>>> diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
>>> index 1a363bb814f4..af0d77338860 100644
>>> --- a/drivers/gpu/drm/panthor/panthor_gem.h
>>> +++ b/drivers/gpu/drm/panthor/panthor_gem.h
>>> @@ -46,6 +46,20 @@ struct panthor_gem_object {
>>>
>>>  	/** @flags: Combination of drm_panthor_bo_flags flags. */
>>>  	u32 flags;
>>> +
>>> +	/**
>>> +	 * @label: BO tagging fields. The label can be assigned within the
>>> +	 * driver itself or through a specific IOCTL.
>>> +	 */
>>> +	struct {
>>> +		/**
>>> +		 * @label.str: Pointer to NULL-terminated string,
>>> +		 */
>>> +		const char *str;
>>> +
>>> +		/** @lock.str: Protects access to the @label.str field. */
>>> +		struct mutex lock;
>>> +	} label;
>>>  };
>>>
>>>  /**
>>> @@ -91,6 +105,9 @@ panthor_gem_create_with_handle(struct drm_file *file,
>>>  			       struct panthor_vm *exclusive_vm,
>>>  			       u64 *size, u32 flags, uint32_t *handle);
>>>
>>> +void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label);
>>> +void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label);
>>> +
>>>  static inline u64
>>>  panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo)
>>>  {
> 
> Adrian Larumbe


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels
  2025-04-14 20:41     ` Adrián Larumbe
@ 2025-04-16  9:22       ` Steven Price
  0 siblings, 0 replies; 14+ messages in thread
From: Steven Price @ 2025-04-16  9:22 UTC (permalink / raw)
  To: Adrián Larumbe
  Cc: Boris Brezillon, Liviu Dudau, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Sumit Semwal,
	Christian König, kernel, dri-devel, linux-kernel,
	linux-media, linaro-mm-sig

On 14/04/2025 21:41, Adrián Larumbe wrote:
> On 14.04.2025 11:01, Steven Price wrote:
>> On 11/04/2025 16:03, Adrián Larumbe wrote:
>>> Allow UM to label a BO for which it possesses a DRM handle.
>>>
>>> Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
>>> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
>>> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
>>
>> Reviewed-by: Steven Price <steven.price@arm.com>
>>
>> Although very minor NITs below which you can consider.
>>
>>> ---
>>>  drivers/gpu/drm/panthor/panthor_drv.c | 42 ++++++++++++++++++++++++++-
>>>  drivers/gpu/drm/panthor/panthor_gem.h |  2 ++
>>>  include/uapi/drm/panthor_drm.h        | 23 +++++++++++++++
>>>  3 files changed, 66 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
>>> index 06fe46e32073..983b24f1236c 100644
>>> --- a/drivers/gpu/drm/panthor/panthor_drv.c
>>> +++ b/drivers/gpu/drm/panthor/panthor_drv.c
>>> @@ -1331,6 +1331,44 @@ static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data,
>>>  	return 0;
>>>  }
>>>
>>> +static int panthor_ioctl_bo_set_label(struct drm_device *ddev, void *data,
>>> +				  struct drm_file *file)
>>> +{
>>> +	struct drm_panthor_bo_set_label *args = data;
>>> +	struct drm_gem_object *obj;
>>> +	const char *label;
>>> +	int ret = 0;
>>> +
>>> +	obj = drm_gem_object_lookup(file, args->handle);
>>> +	if (!obj)
>>> +		return -ENOENT;
>>> +
>>> +	if (args->size && args->label) {
>>> +		if (args->size > PANTHOR_BO_LABEL_MAXLEN) {
>>> +			ret = -E2BIG;
>>> +			goto err_label;
>>> +		}
>>> +
>>> +		label = strndup_user(u64_to_user_ptr(args->label), args->size);
>>> +		if (IS_ERR(label)) {
>>> +			ret = PTR_ERR(label);
>>> +			goto err_label;
>>> +		}
>>> +	} else if (args->size && !args->label) {
>>> +		ret = -EINVAL;
>>> +		goto err_label;
>>> +	} else {
>>> +		label = NULL;
>>> +	}
>>> +
>>> +	panthor_gem_bo_set_label(obj, label);
>>> +
>>> +err_label:
>>> +	drm_gem_object_put(obj);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>>  static int
>>>  panthor_open(struct drm_device *ddev, struct drm_file *file)
>>>  {
>>> @@ -1400,6 +1438,7 @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = {
>>>  	PANTHOR_IOCTL(TILER_HEAP_CREATE, tiler_heap_create, DRM_RENDER_ALLOW),
>>>  	PANTHOR_IOCTL(TILER_HEAP_DESTROY, tiler_heap_destroy, DRM_RENDER_ALLOW),
>>>  	PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW),
>>> +	PANTHOR_IOCTL(BO_SET_LABEL, bo_set_label, DRM_RENDER_ALLOW),
>>>  };
>>>
>>>  static int panthor_mmap(struct file *filp, struct vm_area_struct *vma)
>>> @@ -1509,6 +1548,7 @@ static void panthor_debugfs_init(struct drm_minor *minor)
>>>   * - 1.2 - adds DEV_QUERY_GROUP_PRIORITIES_INFO query
>>>   *       - adds PANTHOR_GROUP_PRIORITY_REALTIME priority
>>>   * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag
>>> + * - 1.4 - adds DRM_IOCTL_PANTHOR_BO_SET_LABEL ioctl
>>>   */
>>>  static const struct drm_driver panthor_drm_driver = {
>>>  	.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ |
>>> @@ -1522,7 +1562,7 @@ static const struct drm_driver panthor_drm_driver = {
>>>  	.name = "panthor",
>>>  	.desc = "Panthor DRM driver",
>>>  	.major = 1,
>>> -	.minor = 3,
>>> +	.minor = 4,
>>>
>>>  	.gem_create_object = panthor_gem_create_object,
>>>  	.gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
>>> diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
>>> index af0d77338860..beba066b4974 100644
>>> --- a/drivers/gpu/drm/panthor/panthor_gem.h
>>> +++ b/drivers/gpu/drm/panthor/panthor_gem.h
>>> @@ -13,6 +13,8 @@
>>>
>>>  struct panthor_vm;
>>>
>>> +#define PANTHOR_BO_LABEL_MAXLEN	PAGE_SIZE
>>> +
>>>  /**
>>>   * struct panthor_gem_object - Driver specific GEM object.
>>>   */
>>> diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
>>> index 97e2c4510e69..12b1994499a9 100644
>>> --- a/include/uapi/drm/panthor_drm.h
>>> +++ b/include/uapi/drm/panthor_drm.h
>>> @@ -127,6 +127,9 @@ enum drm_panthor_ioctl_id {
>>>
>>>  	/** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */
>>>  	DRM_PANTHOR_TILER_HEAP_DESTROY,
>>> +
>>> +	/** @DRM_PANTHOR_BO_SET_LABEL: Label a BO. */
>>> +	DRM_PANTHOR_BO_SET_LABEL,
>>>  };
>>>
>>>  /**
>>> @@ -977,6 +980,24 @@ struct drm_panthor_tiler_heap_destroy {
>>>  	__u32 pad;
>>>  };
>>>
>>> +/**
>>> + * struct drm_panthor_bo_set_label - Arguments passed to DRM_IOCTL_PANTHOR_BO_SET_LABEL
>>> + */
>>> +struct drm_panthor_bo_set_label {
>>> +	/** @handle: Handle of the buffer object to label. */
>>> +	__u32 handle;
>>> +
>>> +	/**
>>> +	 * @size: Length of the label, including the NULL terminator.
>>> +	 *
>>> +	 * Cannot be greater than the OS page size.
>>> +	 */
>>> +	__u32 size;
>>> +
>>> +	/** @label: User pointer to a NULL-terminated string */
>>> +	__u64 label;
>>> +};
>>
>> First very minor NIT:
>>  * NULL is a pointer, i.e. (void*)0
>>  * NUL is the ASCII code point '\0'.
>> So it's a NUL-terminated string.
> 
> Fixed
> 
>> Second NIT: We don't actually need 'size' - since the string is
>> NUL-terminated we can just strndup_user(__user_pointer__, PAGE_SIZE).
>> As things stand we validate that strlen(label) < size <= PAGE_SIZE -
>> which is a little odd (user space might as well just pass PAGE_SIZE
>> rather than calculate the actual length).
> 
> The snag I see in this approach is that the only way to make sure
> strlen(label) + 1 <= PAGE_SIZE would be doing something like
> 
> label = strndup_user(u64_to_user_ptr(args->label), args->size);
> if (strlen(label) + 1 <= PAGE_SIZE) {
>    kfree(label)
>    return -E2BIG;
> }

You can just do

  strndup_user(u64_to_user_ptr(args->label), PAGE_SIZE)

If you look at the kernel's implementation it handles an overly long
string by returning an error:

> 	length = strnlen_user(s, n);
> 
> 	if (!length)
> 		return ERR_PTR(-EFAULT);
> 
> 	if (length > n)
> 		return ERR_PTR(-EINVAL);
> 
> 	p = memdup_user(s, length);

So there's no need to call strlen() on the result.

> In the meantime, we've duplicated the string and traversed a whole page
> of bytes, all to be discarded at once.
> 
> In this case, I think it's alright to expect some cooperation from UM
> in supplying the actual size, although I'm really not an expert in
> designing elegant uAPIs, so if you think this looks very odd I'd be
> glad to replace it with.
> 
> Actually, as I was writing this, I realised that strndup_user() calls
> strnlen_user(), which is publicly available for other drivers, so
> I might check the length first, and if it falls within bounds, do
> the actual user stringdup.

Again, no need (and strnlen_user() has a comment basically saying "don't
call this"). strndup_user() has all the magic we need here.

As I say this is just a 'nit' - so no big deal. But I don't really see
the point of the size in the uAPI.

Take a look at dma_buf_set_name() for an example which sets the name on
a dma_buf (and doesn't take a size argument) - although that wasn't an
example of good uAPI design as the type in the ioctl was botched ;(

Thanks,
Steve

> I shall also mention the size bound on the uAPI for the 'label' pointer.
> 
>> Thanks,
>> Steve
>>
>> +
>>  /**
>>   * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number
>>   * @__access: Access type. Must be R, W or RW.
>> @@ -1019,6 +1040,8 @@ enum {
>>  		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create),
>>  	DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY =
>>  		DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy),
>> +	DRM_IOCTL_PANTHOR_BO_SET_LABEL =
>> +		DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label),
>>  };
>>
>>  #if defined(__cplusplus)
> 
> 
> Adrian Larumbe


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-04-16  9:22 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-11 15:03 [PATCH v7 0/4] Panthor BO tagging and GEMS debug display Adrián Larumbe
2025-04-11 15:03 ` [PATCH v7 1/4] drm/panthor: Introduce BO labeling Adrián Larumbe
2025-04-14  9:50   ` Steven Price
2025-04-14 19:43     ` Adrián Larumbe
2025-04-16  9:14       ` Steven Price
2025-04-11 15:03 ` [PATCH v7 2/4] drm/panthor: Add driver IOCTL for setting BO labels Adrián Larumbe
2025-04-14 10:01   ` Steven Price
2025-04-14 20:41     ` Adrián Larumbe
2025-04-16  9:22       ` Steven Price
2025-04-15 11:07   ` Daniel Stone
2025-04-11 15:03 ` [PATCH v7 3/4] drm/panthor: Label all kernel BO's Adrián Larumbe
2025-04-14 10:01   ` Steven Price
2025-04-14 13:38   ` kernel test robot
2025-04-11 15:03 ` [PATCH v7 4/4] drm/panthor: show device-wide list of DRM GEM objects over DebugFS Adrián Larumbe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox