* [PATCH v2 0/3] Panfrost BO tagging and GEMS debug display
@ 2025-05-07 16:07 Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 1/3] drm/panfrost: Add BO labelling to Panfrost Adrián Larumbe
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Adrián Larumbe @ 2025-05-07 16:07 UTC (permalink / raw)
To: linux-kernel; +Cc: dri-devel, Boris Brezillon, kernel, Adrián Larumbe
This patch series is a Panfrost port of the already merged patches
previously discussed at [1].
The differences are minimal. However, Panfrost doesn't have Kernel-only BO's, so all the
functionality that dealt with them has been removed.
The under-discussion Mesa MR that would allow one to test these changes can be found at [2].
The way BO flags is printed is also slightly different.
Discussion of previous version in the series can be found at [3]
Changelog:
v2:
- Introduced u64_to_user_ptr() for casting user pointers
- Refined documentation for uAPI bo labelling struct fields
- Moved panfrost device debugfs struct fields into a single debugfs struct
- Add BO to debugfs GEMs list right before creating its handle to avoid unnecessary initialised field.
[1] https://lore.kernel.org/dri-devel/20250418022710.74749-1-adrian.larumbe@collabora.com/
[2] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34224
[3] https://lore.kernel.org/dri-devel/20250424022138.709303-1-adrian.larumbe@collabora.com/T/#t
Adrián Larumbe (3):
drm/panfrost: Add BO labelling to Panfrost
drm/panfrost: Add driver IOCTL for setting BO labels
drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
drivers/gpu/drm/panfrost/panfrost_device.c | 5 +
drivers/gpu/drm/panfrost/panfrost_device.h | 15 ++
drivers/gpu/drm/panfrost/panfrost_drv.c | 79 ++++++++++-
drivers/gpu/drm/panfrost/panfrost_gem.c | 154 +++++++++++++++++++++
drivers/gpu/drm/panfrost/panfrost_gem.h | 65 +++++++++
include/uapi/drm/panfrost_drm.h | 21 +++
6 files changed, 338 insertions(+), 1 deletion(-)
base-commit: 9ff4fdf4f44b69237c0afc1d3a8dac916ce66f3e
--
2.48.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/3] drm/panfrost: Add BO labelling to Panfrost
2025-05-07 16:07 [PATCH v2 0/3] Panfrost BO tagging and GEMS debug display Adrián Larumbe
@ 2025-05-07 16:07 ` Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 2/3] drm/panfrost: Add driver IOCTL for setting BO labels Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS Adrián Larumbe
2 siblings, 0 replies; 9+ messages in thread
From: Adrián Larumbe @ 2025-05-07 16:07 UTC (permalink / raw)
To: linux-kernel
Cc: dri-devel, Boris Brezillon, kernel, Adrián Larumbe,
Steven Price, Rob Herring, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
Unlike in Panthor, from where this change is based on, there is no need
to support tagging of BO's other than UM-exposed ones, so all strings
can be freed with kfree().
This commit is done in preparation of a following one that will allow
UM to set BO labels through a new ioctl().
Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
---
drivers/gpu/drm/panfrost/panfrost_gem.c | 19 +++++++++++++++++++
drivers/gpu/drm/panfrost/panfrost_gem.h | 16 ++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 963f04ba2de6..a7a29974d8b1 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
+#include <linux/cleanup.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/dma-buf.h>
@@ -35,6 +36,9 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
*/
WARN_ON_ONCE(!list_empty(&bo->mappings.list));
+ kfree(bo->label.str);
+ mutex_destroy(&bo->label.lock);
+
if (bo->sgts) {
int i;
int n_sgt = bo->base.base.size / SZ_2M;
@@ -260,6 +264,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
mutex_init(&obj->mappings.lock);
obj->base.base.funcs = &panfrost_gem_funcs;
obj->base.map_wc = !pfdev->coherent;
+ mutex_init(&obj->label.lock);
return &obj->base.base;
}
@@ -302,3 +307,17 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev,
return obj;
}
+
+void
+panfrost_gem_set_label(struct drm_gem_object *obj, const char *label)
+{
+ struct panfrost_gem_object *bo = to_panfrost_bo(obj);
+ const char *old_label;
+
+ scoped_guard(mutex, &bo->label.lock) {
+ old_label = bo->label.str;
+ bo->label.str = label;
+ }
+
+ kfree(old_label);
+}
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
index 7516b7ecf7fe..c0be2934f229 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -41,6 +41,20 @@ struct panfrost_gem_object {
*/
size_t heap_rss_size;
+ /**
+ * @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;
+
bool noexec :1;
bool is_heap :1;
};
@@ -89,4 +103,6 @@ void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo);
int panfrost_gem_shrinker_init(struct drm_device *dev);
void panfrost_gem_shrinker_cleanup(struct drm_device *dev);
+void panfrost_gem_set_label(struct drm_gem_object *obj, const char *label);
+
#endif /* __PANFROST_GEM_H__ */
base-commit: 9ff4fdf4f44b69237c0afc1d3a8dac916ce66f3e
--
2.48.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/3] drm/panfrost: Add driver IOCTL for setting BO labels
2025-05-07 16:07 [PATCH v2 0/3] Panfrost BO tagging and GEMS debug display Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 1/3] drm/panfrost: Add BO labelling to Panfrost Adrián Larumbe
@ 2025-05-07 16:07 ` Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS Adrián Larumbe
2 siblings, 0 replies; 9+ messages in thread
From: Adrián Larumbe @ 2025-05-07 16:07 UTC (permalink / raw)
To: linux-kernel
Cc: dri-devel, Boris Brezillon, kernel, Adrián Larumbe,
Steven Price, Rob Herring, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter
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: Steven Price <steven.price@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
---
drivers/gpu/drm/panfrost/panfrost_drv.c | 44 ++++++++++++++++++++++++-
drivers/gpu/drm/panfrost/panfrost_gem.h | 2 ++
include/uapi/drm/panfrost_drm.h | 21 ++++++++++++
3 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index f1ec3b02f15a..179fbaa1cd0c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -495,6 +495,46 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
return ret;
}
+static int panfrost_ioctl_set_label_bo(struct drm_device *ddev, void *data,
+ struct drm_file *file)
+{
+ struct drm_panfrost_set_label_bo *args = data;
+ struct drm_gem_object *obj;
+ const char *label = NULL;
+ int ret = 0;
+
+ if (args->pad)
+ return -EINVAL;
+
+ obj = drm_gem_object_lookup(file, args->handle);
+ if (!obj)
+ return -ENOENT;
+
+ if (args->label) {
+ label = strndup_user(u64_to_user_ptr(args->label),
+ PANFROST_BO_LABEL_MAXLEN);
+ if (IS_ERR(label)) {
+ ret = PTR_ERR(label);
+ if (ret == -EINVAL)
+ ret = -E2BIG;
+ goto err_put_obj;
+ }
+ }
+
+ /*
+ * We treat passing a label of length 0 and passing a NULL label
+ * differently, because even though they might seem conceptually
+ * similar, future uses of the BO label might expect a different
+ * behaviour in each case.
+ */
+ panfrost_gem_set_label(obj, label);
+
+err_put_obj:
+ drm_gem_object_put(obj);
+
+ return ret;
+}
+
int panfrost_unstable_ioctl_check(void)
{
if (!unstable_ioctls)
@@ -561,6 +601,7 @@ static const struct drm_ioctl_desc panfrost_drm_driver_ioctls[] = {
PANFROST_IOCTL(PERFCNT_ENABLE, perfcnt_enable, DRM_RENDER_ALLOW),
PANFROST_IOCTL(PERFCNT_DUMP, perfcnt_dump, DRM_RENDER_ALLOW),
PANFROST_IOCTL(MADVISE, madvise, DRM_RENDER_ALLOW),
+ PANFROST_IOCTL(SET_LABEL_BO, set_label_bo, DRM_RENDER_ALLOW),
};
static void panfrost_gpu_show_fdinfo(struct panfrost_device *pfdev,
@@ -625,6 +666,7 @@ static const struct file_operations panfrost_drm_driver_fops = {
* - 1.2 - adds AFBC_FEATURES query
* - 1.3 - adds JD_REQ_CYCLE_COUNT job requirement for SUBMIT
* - adds SYSTEM_TIMESTAMP and SYSTEM_TIMESTAMP_FREQUENCY queries
+ * - 1.4 - adds SET_LABEL_BO
*/
static const struct drm_driver panfrost_drm_driver = {
.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ,
@@ -637,7 +679,7 @@ static const struct drm_driver panfrost_drm_driver = {
.name = "panfrost",
.desc = "panfrost DRM",
.major = 1,
- .minor = 3,
+ .minor = 4,
.gem_create_object = panfrost_gem_create_object,
.gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table,
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
index c0be2934f229..842e025b9bdc 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -9,6 +9,8 @@
struct panfrost_mmu;
+#define PANFROST_BO_LABEL_MAXLEN 4096
+
struct panfrost_gem_object {
struct drm_gem_shmem_object base;
struct sg_table *sgts;
diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h
index 568724be6628..ed67510395bd 100644
--- a/include/uapi/drm/panfrost_drm.h
+++ b/include/uapi/drm/panfrost_drm.h
@@ -21,6 +21,7 @@ extern "C" {
#define DRM_PANFROST_PERFCNT_ENABLE 0x06
#define DRM_PANFROST_PERFCNT_DUMP 0x07
#define DRM_PANFROST_MADVISE 0x08
+#define DRM_PANFROST_SET_LABEL_BO 0x09
#define DRM_IOCTL_PANFROST_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_SUBMIT, struct drm_panfrost_submit)
#define DRM_IOCTL_PANFROST_WAIT_BO DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_WAIT_BO, struct drm_panfrost_wait_bo)
@@ -29,6 +30,7 @@ extern "C" {
#define DRM_IOCTL_PANFROST_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_GET_PARAM, struct drm_panfrost_get_param)
#define DRM_IOCTL_PANFROST_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_GET_BO_OFFSET, struct drm_panfrost_get_bo_offset)
#define DRM_IOCTL_PANFROST_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_MADVISE, struct drm_panfrost_madvise)
+#define DRM_IOCTL_PANFROST_SET_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_SET_LABEL_BO, struct drm_panfrost_set_label_bo)
/*
* Unstable ioctl(s): only exposed when the unsafe unstable_ioctls module
@@ -227,6 +229,25 @@ struct drm_panfrost_madvise {
__u32 retained; /* out, whether backing store still exists */
};
+/**
+ * struct drm_panfrost_set_label_bo - ioctl argument for labelling Panfrost BOs.
+ */
+struct drm_panfrost_set_label_bo {
+ /** @handle: Handle of the buffer object to label. */
+ __u32 handle;
+
+ /** @pad: MBZ. */
+ __u32 pad;
+
+ /**
+ * @label: User pointer to a NUL-terminated string
+ *
+ * Length cannot be greater than 4096.
+ * NULL is permitted and means clear the label.
+ */
+ __u64 label;
+};
+
/* Definitions for coredump decoding in user space */
#define PANFROSTDUMP_MAJOR 1
#define PANFROSTDUMP_MINOR 0
--
2.48.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
2025-05-07 16:07 [PATCH v2 0/3] Panfrost BO tagging and GEMS debug display Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 1/3] drm/panfrost: Add BO labelling to Panfrost Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 2/3] drm/panfrost: Add driver IOCTL for setting BO labels Adrián Larumbe
@ 2025-05-07 16:07 ` Adrián Larumbe
2025-05-08 10:42 ` Steven Price
2 siblings, 1 reply; 9+ messages in thread
From: Adrián Larumbe @ 2025-05-07 16:07 UTC (permalink / raw)
To: linux-kernel
Cc: dri-devel, Boris Brezillon, kernel, Adrián Larumbe,
Rob Herring, Steven Price, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sumit Semwal,
Christian König, linux-media, linaro-mm-sig
This change is essentially a Panfrost port of commit a3707f53eb3f
("drm/panthor: show device-wide list of DRM GEM objects over DebugFS").
The DebugFS file is almost the same as in Panthor, minus the GEM object
usage flags, since Panfrost has no kernel-only BO's.
Two additional GEM state flags which are displayed but aren't relevant
to Panthor are 'Purged' and 'Purgeable', since Panfrost implements an
explicit shrinker and a madvise ioctl to flag objects as reclaimable.
Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
---
drivers/gpu/drm/panfrost/panfrost_device.c | 5 +
drivers/gpu/drm/panfrost/panfrost_device.h | 15 +++
drivers/gpu/drm/panfrost/panfrost_drv.c | 35 ++++++
drivers/gpu/drm/panfrost/panfrost_gem.c | 135 +++++++++++++++++++++
drivers/gpu/drm/panfrost/panfrost_gem.h | 47 +++++++
5 files changed, 237 insertions(+)
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
index 5d35076b2e6d..04bec27449cb 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -209,6 +209,11 @@ int panfrost_device_init(struct panfrost_device *pfdev)
spin_lock_init(&pfdev->cycle_counter.lock);
+#ifdef CONFIG_DEBUG_FS
+ mutex_init(&pfdev->debugfs.gems_lock);
+ INIT_LIST_HEAD(&pfdev->debugfs.gems_list);
+#endif
+
err = panfrost_pm_domain_init(pfdev);
if (err)
return err;
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
index dcff70f905cd..077525a3ad68 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -111,6 +111,17 @@ struct panfrost_compatible {
u8 gpu_quirks;
};
+/**
+ * struct panfrost_device_debugfs - Device-wide DebugFS tracking structures
+ */
+struct panfrost_device_debugfs {
+ /** @gems_list: Device-wide list of GEM objects owned by at least one file. */
+ struct list_head gems_list;
+
+ /** @gems_lock: Serializes access to the device-wide list of GEM objects. */
+ struct mutex gems_lock;
+};
+
struct panfrost_device {
struct device *dev;
struct drm_device *ddev;
@@ -164,6 +175,10 @@ struct panfrost_device {
atomic_t use_count;
spinlock_t lock;
} cycle_counter;
+
+#ifdef CONFIG_DEBUG_FS
+ struct panfrost_device_debugfs debugfs;
+#endif
};
struct panfrost_mmu {
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 179fbaa1cd0c..f576cb215898 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <drm/panfrost_drm.h>
+#include <drm/drm_debugfs.h>
#include <drm/drm_drv.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_syncobj.h>
@@ -659,6 +660,37 @@ static const struct file_operations panfrost_drm_driver_fops = {
.show_fdinfo = drm_show_fdinfo,
};
+#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 panfrost_device *pfdev = dev->dev_private;
+
+ panfrost_gem_debugfs_print_bos(pfdev, 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 panfrost_debugfs_init(struct drm_minor *minor)
+{
+ panthor_gems_debugfs_init(minor);
+}
+#endif
+
/*
* Panfrost driver version:
* - 1.0 - initial interface
@@ -683,6 +715,9 @@ static const struct drm_driver panfrost_drm_driver = {
.gem_create_object = panfrost_gem_create_object,
.gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table,
+#ifdef CONFIG_DEBUG_FS
+ .debugfs_init = panfrost_debugfs_init,
+#endif
};
static int panfrost_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index a7a29974d8b1..fe2cdbe8baf0 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -12,6 +12,36 @@
#include "panfrost_gem.h"
#include "panfrost_mmu.h"
+#ifdef CONFIG_DEBUG_FS
+static void panfrost_gem_debugfs_bo_add(struct panfrost_device *ptdev,
+ struct panfrost_gem_object *bo)
+{
+ bo->debugfs.creator.tgid = current->group_leader->pid;
+ get_task_comm(bo->debugfs.creator.process_name, current->group_leader);
+
+ mutex_lock(&ptdev->debugfs.gems_lock);
+ list_add_tail(&bo->debugfs.node, &ptdev->debugfs.gems_list);
+ mutex_unlock(&ptdev->debugfs.gems_lock);
+}
+
+static void panfrost_gem_debugfs_bo_rm(struct panfrost_gem_object *bo)
+{
+ struct panfrost_device *ptdev = bo->base.base.dev->dev_private;
+
+ if (list_empty(&bo->debugfs.node))
+ return;
+
+ mutex_lock(&ptdev->debugfs.gems_lock);
+ list_del_init(&bo->debugfs.node);
+ mutex_unlock(&ptdev->debugfs.gems_lock);
+}
+#else
+static void panfrost_gem_debugfs_bo_add(struct panfrost_device *ptdev,
+ struct panfrost_gem_object *bo)
+{}
+static void panfrost_gem_debugfs_bo_rm(struct panfrost_gem_object *bo) {}
+#endif
+
/* Called DRM core on the last userspace/kernel unreference of the
* BO.
*/
@@ -36,6 +66,7 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
*/
WARN_ON_ONCE(!list_empty(&bo->mappings.list));
+ panfrost_gem_debugfs_bo_rm(bo);
kfree(bo->label.str);
mutex_destroy(&bo->label.lock);
@@ -272,6 +303,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
struct panfrost_gem_object *
panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
{
+ struct panfrost_device *pfdev = dev->dev_private;
struct drm_gem_shmem_object *shmem;
struct panfrost_gem_object *bo;
@@ -287,6 +319,8 @@ panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
bo->is_heap = !!(flags & PANFROST_BO_HEAP);
+ panfrost_gem_debugfs_bo_add(pfdev, bo);
+
return bo;
}
@@ -321,3 +355,104 @@ panfrost_gem_set_label(struct drm_gem_object *obj, const char *label)
kfree(old_label);
}
+
+#ifdef CONFIG_DEBUG_FS
+struct gem_size_totals {
+ size_t size;
+ size_t resident;
+ size_t reclaimable;
+};
+
+struct flag_def {
+ u32 flag;
+ const char *name;
+};
+
+static void panfrost_gem_debugfs_print_flag_names(struct seq_file *m)
+{
+ int len;
+ int i;
+
+ static const struct flag_def gem_state_flags_names[] = {
+ {PANFROST_DEBUGFS_GEM_STATE_FLAG_IMPORTED, "imported"},
+ {PANFROST_DEBUGFS_GEM_STATE_FLAG_EXPORTED, "exported"},
+ {PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGED, "purged"},
+ {PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGEABLE, "purgeable"},
+ };
+
+ seq_puts(m, "GEM state flags: ");
+ for (i = 0, len = ARRAY_SIZE(gem_state_flags_names); i < len; i++) {
+ seq_printf(m, "%s (0x%x)%s", gem_state_flags_names[i].name,
+ gem_state_flags_names[i].flag, (i < len - 1) ? ", " : "\n\n");
+ }
+}
+
+static void panfrost_gem_debugfs_bo_print(struct panfrost_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;
+ u32 gem_state_flags = 0;
+
+ /* Skip BOs being destroyed. */
+ if (!refcount)
+ return;
+
+ resident_size = bo->base.pages ? 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%-16zd0x%-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)
+ gem_state_flags |= PANFROST_DEBUGFS_GEM_STATE_FLAG_IMPORTED;
+ if (bo->base.base.dma_buf)
+ gem_state_flags |= PANFROST_DEBUGFS_GEM_STATE_FLAG_EXPORTED;
+
+ if (bo->base.madv < 0)
+ gem_state_flags |= PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGED;
+ else if (bo->base.madv > 0)
+ gem_state_flags |= PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGEABLE;
+
+ seq_printf(m, "0x%-10x", gem_state_flags);
+
+ scoped_guard(mutex, &bo->label.lock) {
+ seq_printf(m, "%s\n", bo->label.str ? : "");
+ }
+
+ totals->size += bo->base.base.size;
+ totals->resident += resident_size;
+ if (bo->base.madv > 0)
+ totals->reclaimable += resident_size;
+}
+
+void panfrost_gem_debugfs_print_bos(struct panfrost_device *ptdev,
+ struct seq_file *m)
+{
+ struct gem_size_totals totals = {0};
+ struct panfrost_gem_object *bo;
+
+ panfrost_gem_debugfs_print_flag_names(m);
+
+ seq_puts(m, "created-by global-name refcount size resident-size file-offset state label\n");
+ seq_puts(m, "-----------------------------------------------------------------------------------------------------------------------------------\n");
+
+ scoped_guard(mutex, &ptdev->debugfs.gems_lock) {
+ list_for_each_entry(bo, &ptdev->debugfs.gems_list, debugfs.node) {
+ panfrost_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/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
index 842e025b9bdc..ce8ca7be2d66 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -8,9 +8,47 @@
#include <drm/drm_mm.h>
struct panfrost_mmu;
+struct panfrost_device;
#define PANFROST_BO_LABEL_MAXLEN 4096
+enum panfrost_debugfs_gem_state_flags {
+ /** @PANFROST_DEBUGFS_GEM_STATE_FLAG_IMPORTED: GEM BO is PRIME imported. */
+ PANFROST_DEBUGFS_GEM_STATE_FLAG_IMPORTED = BIT(0),
+
+ /** @PANFROST_DEBUGFS_GEM_STATE_FLAG_EXPORTED: GEM BO is PRIME exported. */
+ PANFROST_DEBUGFS_GEM_STATE_FLAG_EXPORTED = BIT(1),
+
+ /** @PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGED: GEM BO was reclaimed by the shrinker. */
+ PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGED = BIT(2),
+
+ /**
+ * @PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGEABLE: GEM BO pages were marked as no longer
+ * needed by UM and can be reclaimed by the shrinker.
+ */
+ PANFROST_DEBUGFS_GEM_STATE_FLAG_PURGEABLE = BIT(3),
+};
+
+/**
+ * struct panfrost_gem_debugfs - GEM object's DebugFS list information
+ */
+struct panfrost_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;
+};
+
struct panfrost_gem_object {
struct drm_gem_shmem_object base;
struct sg_table *sgts;
@@ -59,6 +97,10 @@ struct panfrost_gem_object {
bool noexec :1;
bool is_heap :1;
+
+#ifdef CONFIG_DEBUG_FS
+ struct panfrost_gem_debugfs debugfs;
+#endif
};
struct panfrost_gem_mapping {
@@ -107,4 +149,9 @@ void panfrost_gem_shrinker_cleanup(struct drm_device *dev);
void panfrost_gem_set_label(struct drm_gem_object *obj, const char *label);
+#ifdef CONFIG_DEBUG_FS
+void panfrost_gem_debugfs_print_bos(struct panfrost_device *pfdev,
+ struct seq_file *m);
+#endif
+
#endif /* __PANFROST_GEM_H__ */
--
2.48.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
2025-05-07 16:07 ` [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS Adrián Larumbe
@ 2025-05-08 10:42 ` Steven Price
2025-05-15 18:04 ` Daniel Stone
2025-05-20 11:30 ` Adrián Larumbe
0 siblings, 2 replies; 9+ messages in thread
From: Steven Price @ 2025-05-08 10:42 UTC (permalink / raw)
To: Adrián Larumbe, linux-kernel
Cc: dri-devel, Boris Brezillon, kernel, Rob Herring,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sumit Semwal, Christian König, linux-media,
linaro-mm-sig
On 07/05/2025 17:07, Adrián Larumbe wrote:
> This change is essentially a Panfrost port of commit a3707f53eb3f
> ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS").
>
> The DebugFS file is almost the same as in Panthor, minus the GEM object
> usage flags, since Panfrost has no kernel-only BO's.
>
> Two additional GEM state flags which are displayed but aren't relevant
> to Panthor are 'Purged' and 'Purgeable', since Panfrost implements an
> explicit shrinker and a madvise ioctl to flag objects as reclaimable.
>
> Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
Minor point, but you've used "ptdev" rather than "pfdev" several times
in this patch - it would be good to avoid this.
I'm also seeing a splat when running this, see below. I haven't got my
head around how this is happening, but I see it when glmark quits at the
end of the test.
Steve
[ 399.505066] Unable to handle kernel NULL pointer dereference at virtual address 00000004 when write
[ 399.515519] [00000004] *pgd=00000000
[ 399.519541] Internal error: Oops: 805 [#1] SMP ARM
[ 399.524896] Modules linked in: panfrost gpu_sched drm_shmem_helper
[ 399.531817] CPU: 1 UID: 1000 PID: 316 Comm: glmark2-es2-drm Not tainted 6.15.0-rc5-00731-g9cc5b4d7da27 #1 NONE
[ 399.543098] Hardware name: Rockchip (Device Tree)
[ 399.548350] PC is at panfrost_gem_free_object+0x8c/0x160 [panfrost]
[ 399.555371] LR is at trace_contention_end+0x4c/0xfc
[ 399.560822] pc : [<bf01a384>] lr : [<c03d0170>] psr: 60010013
[ 399.567823] sp : f22b1df8 ip : c2163e00 fp : c4b15800
[ 399.573658] r10: 00000009 r9 : c5f94c40 r8 : c4b15850
[ 399.579492] r7 : c4b15884 r6 : c7813614 r5 : c5f94f30 r4 : c7813400
[ 399.586784] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : c5f94f30
[ 399.594075] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
[ 399.602048] Control: 10c5387d Table: 06c6c06a DAC: 00000051
[ 399.608465] Register r0 information: slab kmalloc-1k start c5f94c00 pointer offset 816 size 1024
[ 399.618296] Register r1 information: NULL pointer
[ 399.623551] Register r2 information: NULL pointer
[ 399.628804] Register r3 information: NULL pointer
[ 399.634057] Register r4 information: slab kmalloc-1k start c7813400 pointer offset 0 size 1024
[ 399.643690] Register r5 information: slab kmalloc-1k start c5f94c00 pointer offset 816 size 1024
[ 399.653517] Register r6 information: slab kmalloc-1k start c7813400 pointer offset 532 size 1024
[ 399.663344] Register r7 information: slab kmalloc-1k start c4b15800 pointer offset 132 size 1024
[ 399.673171] Register r8 information: slab kmalloc-1k start c4b15800 pointer offset 80 size 1024
[ 399.682901] Register r9 information: slab kmalloc-1k start c5f94c00 pointer offset 64 size 1024
[ 399.692631] Register r10 information: non-paged memory
[ 399.698370] Register r11 information: slab kmalloc-1k start c4b15800 pointer offset 0 size 1024
[ 399.708101] Register r12 information: non-slab/vmalloc memory
[ 399.714521] Process glmark2-es2-drm (pid: 316, stack limit = 0x178bc4ea)
[ 399.722009] Stack: (0xf22b1df8 to 0xf22b2000)
[ 399.726874] 1de0: 00000000 c4b15884
[ 399.736012] 1e00: c7813400 c4b15800 00000007 c4b15884 c4b15850 c6815000 00000009 c0bb3824
[ 399.745150] 1e20: 00000000 40086409 c7860800 c15fd008 00000008 c0bb588c c6815630 0000013c
[ 399.754288] 1e40: 0000e280 00000000 c1b35650 b235e000 f22b1f5c 00000008 f22b1e74 bec37550
[ 399.763426] 1e60: c6815630 c694ea00 c0bb47cc 00000051 00000000 00000007 00000000 00000000
[ 399.772564] 1e80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 399.781701] 1ea0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 399.790839] 1ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 399.799977] 1ee0: 00000000 00000000 00000000 00000000 00000000 356cc46f 00000000 40086409
[ 399.809115] 1f00: c694ea00 c03000c0 bec37550 c694ea00 c6815000 00000006 c4bf9b70 c058d694
[ 399.818253] 1f20: b2b47000 f22b1f50 00000001 c03002f0 00000000 c5f60900 00000000 b235e000
[ 399.827391] 1f40: 007e9000 c053d874 f22b1f50 00000001 f22b1f50 f22b1f50 004e0b14 c5f60940
[ 399.836528] 1f60: b235e000 b2b46fff c4abec0c b09e3000 b2bcffff 00000000 00000000 356cc46f
[ 399.845666] 1f80: 00000003 004e6b40 bec37550 40086409 00000036 c03002f0 c6815000 00000036
[ 399.854805] 1fa0: 01cb32a0 c03000c0 004e6b40 bec37550 00000006 40086409 bec37550 00000007
[ 399.863943] 1fc0: 004e6b40 bec37550 40086409 00000036 00000000 00000000 01cb2da0 01cb32a0
[ 399.873080] 1fe0: b6e4b08c bec37534 b6e3442f b6bb8f98 60010030 00000006 00000000 00000000
[ 399.882216] Call trace:
[ 399.882222] panfrost_gem_free_object [panfrost] from drm_gem_handle_delete+0x84/0xb0
[ 399.893813] drm_gem_handle_delete from drm_ioctl+0x2b8/0x4f4
[ 399.900237] drm_ioctl from sys_ioctl+0x428/0xe30
[ 399.905496] sys_ioctl from ret_fast_syscall+0x0/0x1c
[ 399.911141] Exception stack(0xf22b1fa8 to 0xf22b1ff0)
[ 399.916783] 1fa0: 004e6b40 bec37550 00000006 40086409 bec37550 00000007
[ 399.925922] 1fc0: 004e6b40 bec37550 40086409 00000036 00000000 00000000 01cb2da0 01cb32a0
[ 399.935058] 1fe0: b6e4b08c bec37534 b6e3442f b6bb8f98
[ 399.940702] Code: eb0018fa e5943218 e5942214 e1a00005 (e5823004)
[ 399.947532] ---[ end trace 0000000000000000 ]---
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
2025-05-08 10:42 ` Steven Price
@ 2025-05-15 18:04 ` Daniel Stone
2025-05-19 16:02 ` Steven Price
2025-05-20 11:30 ` Adrián Larumbe
1 sibling, 1 reply; 9+ messages in thread
From: Daniel Stone @ 2025-05-15 18:04 UTC (permalink / raw)
To: Adrián Larumbe, Linux Kernel Mailing List, dri-devel,
Boris Brezillon, kernel, Rob Herring, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Sumit Semwal, Christian König, Linux Media Mailing List,
moderated list:DMA BUFFER SHARING FRAMEWORK
Hi Steven,
On Thu, 8 May 2025 at 11:42, Steven Price <steven.price@arm.com> wrote:
> I'm also seeing a splat when running this, see below. I haven't got my
> head around how this is happening, but I see it when glmark quits at the
> end of the test.
>
> [ 399.505066] Unable to handle kernel NULL pointer dereference at virtual address 00000004 when write
> [...]
> [ 399.882216] Call trace:
> [ 399.882222] panfrost_gem_free_object [panfrost] from drm_gem_handle_delete+0x84/0xb0
> [ 399.893813] drm_gem_handle_delete from drm_ioctl+0x2b8/0x4f4
> [ 399.900237] drm_ioctl from sys_ioctl+0x428/0xe30
> [ 399.905496] sys_ioctl from ret_fast_syscall+0x0/0x1c
Soooo. Let's assume it has to actually occur in
panfrost_gem_debugfs_bo_rm(), since that's all that's changed here.
I don't think pfdev can be NULL here, because we've already
dereferenced ptdev and written to a structure member earlier in
panfrost_gem_free_object(). I don't think it can be the debugfs mutex,
because a) that's initialised with the device, and b) wouldn't be
offset 0x4.
I'm looking then at list_del_init(&bo->debugfs.node), which would
effectively execute bo->debugfs.node->next->prev =
bo->debugfs.node->prev. So if bo->debugfs.node->next was NULL, that
would explain a write to 0x4 on 32-bit systems.
What I _can't_ see is how that would be. Even a double-free calls
list_del_init() so we're all good. If the shmem alloc failed then this
would splat because panfrost_gem_debugfs_bo_add() happens too late,
and we end up with an uninitialised list head - so that's one to fix.
But I assume that isn't what happens here. I wonder if it's the import
path, and the panfrost_gem_debugfs_bo_add() call instead needs to be
in the panfrost_gem_create_object() callback rather than only
panfrost_gem_create() which is called through the ioctl?
Cheers,
Daniel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
2025-05-15 18:04 ` Daniel Stone
@ 2025-05-19 16:02 ` Steven Price
2025-05-20 12:53 ` Adrián Larumbe
0 siblings, 1 reply; 9+ messages in thread
From: Steven Price @ 2025-05-19 16:02 UTC (permalink / raw)
To: Daniel Stone, Adrián Larumbe, Linux Kernel Mailing List,
dri-devel, Boris Brezillon, kernel, Rob Herring,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sumit Semwal, Christian König,
Linux Media Mailing List,
moderated list:DMA BUFFER SHARING FRAMEWORK
On 15/05/2025 19:04, Daniel Stone wrote:
> Hi Steven,
>
> On Thu, 8 May 2025 at 11:42, Steven Price <steven.price@arm.com> wrote:
>> I'm also seeing a splat when running this, see below. I haven't got my
>> head around how this is happening, but I see it when glmark quits at the
>> end of the test.
>>
>> [ 399.505066] Unable to handle kernel NULL pointer dereference at virtual address 00000004 when write
>> [...]
>> [ 399.882216] Call trace:
>> [ 399.882222] panfrost_gem_free_object [panfrost] from drm_gem_handle_delete+0x84/0xb0
>> [ 399.893813] drm_gem_handle_delete from drm_ioctl+0x2b8/0x4f4
>> [ 399.900237] drm_ioctl from sys_ioctl+0x428/0xe30
>> [ 399.905496] sys_ioctl from ret_fast_syscall+0x0/0x1c
>
> Soooo. Let's assume it has to actually occur in
> panfrost_gem_debugfs_bo_rm(), since that's all that's changed here.
>
> I don't think pfdev can be NULL here, because we've already
> dereferenced ptdev and written to a structure member earlier in
> panfrost_gem_free_object(). I don't think it can be the debugfs mutex,
> because a) that's initialised with the device, and b) wouldn't be
> offset 0x4.
>
> I'm looking then at list_del_init(&bo->debugfs.node), which would
> effectively execute bo->debugfs.node->next->prev =
> bo->debugfs.node->prev. So if bo->debugfs.node->next was NULL, that
> would explain a write to 0x4 on 32-bit systems.
So I finally got some time to do some debugging on this. And you are
absolutely correct on where the fault is triggered.
The cause of it is that panfrost_gem_debugfs_bo_add() is called from
panfrost_gem_create(), but that isn't the only place that Panfrost GEM
objects are created - it turns out panfrost_perfcnt_enable_locked() also
calls drm_gem_shmem_create(). And in that case the list next/prev
pointers are left set to NULL, causing things to blow up when the GEM
object is freed.
The below patch gets things working, or alternatively just init the list
in panfrost_gem_create_object() if we don't want to include the perfcnt
buffer in the list.
Steve
---8<--
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index fe2cdbe8baf0..51da13cd81f0 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -297,13 +297,14 @@ struct drm_gem_object
*panfrost_gem_create_object(struct drm_device *dev, size_t
obj->base.map_wc = !pfdev->coherent;
mutex_init(&obj->label.lock);
+ panfrost_gem_debugfs_bo_add(pfdev, obj);
+
return &obj->base.base;
}
struct panfrost_gem_object *
panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
{
- struct panfrost_device *pfdev = dev->dev_private;
struct drm_gem_shmem_object *shmem;
struct panfrost_gem_object *bo;
@@ -319,8 +320,6 @@ panfrost_gem_create(struct drm_device *dev, size_t
size, u32 flags)
bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
bo->is_heap = !!(flags & PANFROST_BO_HEAP);
- panfrost_gem_debugfs_bo_add(pfdev, bo);
-
return bo;
}
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
2025-05-08 10:42 ` Steven Price
2025-05-15 18:04 ` Daniel Stone
@ 2025-05-20 11:30 ` Adrián Larumbe
1 sibling, 0 replies; 9+ messages in thread
From: Adrián Larumbe @ 2025-05-20 11:30 UTC (permalink / raw)
To: Steven Price
Cc: linux-kernel, dri-devel, Boris Brezillon, kernel, Rob Herring,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Sumit Semwal, Christian König, linux-media,
linaro-mm-sig
Hi Steven,
On 08.05.2025 11:42, Steven Price wrote:
> On 07/05/2025 17:07, Adrián Larumbe wrote:
> > This change is essentially a Panfrost port of commit a3707f53eb3f
> > ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS").
> >
> > The DebugFS file is almost the same as in Panthor, minus the GEM object
> > usage flags, since Panfrost has no kernel-only BO's.
> >
> > Two additional GEM state flags which are displayed but aren't relevant
> > to Panthor are 'Purged' and 'Purgeable', since Panfrost implements an
> > explicit shrinker and a madvise ioctl to flag objects as reclaimable.
> >
> > Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com>
>
> Minor point, but you've used "ptdev" rather than "pfdev" several times
> in this patch - it would be good to avoid this.
I've noticed I also forgot to fix the spelling when porting some devfreq fix code from Panthor some time ago.
I'll send a new patch within the same series to fix thosoe too.
> I'm also seeing a splat when running this, see below. I haven't got my
> head around how this is happening, but I see it when glmark quits at the
> end of the test.
>
> Steve
>
> [ 399.505066] Unable to handle kernel NULL pointer dereference at virtual address 00000004 when write
> [ 399.515519] [00000004] *pgd=00000000
> [ 399.519541] Internal error: Oops: 805 [#1] SMP ARM
> [ 399.524896] Modules linked in: panfrost gpu_sched drm_shmem_helper
> [ 399.531817] CPU: 1 UID: 1000 PID: 316 Comm: glmark2-es2-drm Not tainted 6.15.0-rc5-00731-g9cc5b4d7da27 #1 NONE
> [ 399.543098] Hardware name: Rockchip (Device Tree)
> [ 399.548350] PC is at panfrost_gem_free_object+0x8c/0x160 [panfrost]
> [ 399.555371] LR is at trace_contention_end+0x4c/0xfc
> [ 399.560822] pc : [<bf01a384>] lr : [<c03d0170>] psr: 60010013
> [ 399.567823] sp : f22b1df8 ip : c2163e00 fp : c4b15800
> [ 399.573658] r10: 00000009 r9 : c5f94c40 r8 : c4b15850
> [ 399.579492] r7 : c4b15884 r6 : c7813614 r5 : c5f94f30 r4 : c7813400
> [ 399.586784] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : c5f94f30
> [ 399.594075] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
> [ 399.602048] Control: 10c5387d Table: 06c6c06a DAC: 00000051
> [ 399.608465] Register r0 information: slab kmalloc-1k start c5f94c00 pointer offset 816 size 1024
> [ 399.618296] Register r1 information: NULL pointer
> [ 399.623551] Register r2 information: NULL pointer
> [ 399.628804] Register r3 information: NULL pointer
> [ 399.634057] Register r4 information: slab kmalloc-1k start c7813400 pointer offset 0 size 1024
> [ 399.643690] Register r5 information: slab kmalloc-1k start c5f94c00 pointer offset 816 size 1024
> [ 399.653517] Register r6 information: slab kmalloc-1k start c7813400 pointer offset 532 size 1024
> [ 399.663344] Register r7 information: slab kmalloc-1k start c4b15800 pointer offset 132 size 1024
> [ 399.673171] Register r8 information: slab kmalloc-1k start c4b15800 pointer offset 80 size 1024
> [ 399.682901] Register r9 information: slab kmalloc-1k start c5f94c00 pointer offset 64 size 1024
> [ 399.692631] Register r10 information: non-paged memory
> [ 399.698370] Register r11 information: slab kmalloc-1k start c4b15800 pointer offset 0 size 1024
> [ 399.708101] Register r12 information: non-slab/vmalloc memory
> [ 399.714521] Process glmark2-es2-drm (pid: 316, stack limit = 0x178bc4ea)
> [ 399.722009] Stack: (0xf22b1df8 to 0xf22b2000)
> [ 399.726874] 1de0: 00000000 c4b15884
> [ 399.736012] 1e00: c7813400 c4b15800 00000007 c4b15884 c4b15850 c6815000 00000009 c0bb3824
> [ 399.745150] 1e20: 00000000 40086409 c7860800 c15fd008 00000008 c0bb588c c6815630 0000013c
> [ 399.754288] 1e40: 0000e280 00000000 c1b35650 b235e000 f22b1f5c 00000008 f22b1e74 bec37550
> [ 399.763426] 1e60: c6815630 c694ea00 c0bb47cc 00000051 00000000 00000007 00000000 00000000
> [ 399.772564] 1e80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 399.781701] 1ea0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 399.790839] 1ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 399.799977] 1ee0: 00000000 00000000 00000000 00000000 00000000 356cc46f 00000000 40086409
> [ 399.809115] 1f00: c694ea00 c03000c0 bec37550 c694ea00 c6815000 00000006 c4bf9b70 c058d694
> [ 399.818253] 1f20: b2b47000 f22b1f50 00000001 c03002f0 00000000 c5f60900 00000000 b235e000
> [ 399.827391] 1f40: 007e9000 c053d874 f22b1f50 00000001 f22b1f50 f22b1f50 004e0b14 c5f60940
> [ 399.836528] 1f60: b235e000 b2b46fff c4abec0c b09e3000 b2bcffff 00000000 00000000 356cc46f
> [ 399.845666] 1f80: 00000003 004e6b40 bec37550 40086409 00000036 c03002f0 c6815000 00000036
> [ 399.854805] 1fa0: 01cb32a0 c03000c0 004e6b40 bec37550 00000006 40086409 bec37550 00000007
> [ 399.863943] 1fc0: 004e6b40 bec37550 40086409 00000036 00000000 00000000 01cb2da0 01cb32a0
> [ 399.873080] 1fe0: b6e4b08c bec37534 b6e3442f b6bb8f98 60010030 00000006 00000000 00000000
> [ 399.882216] Call trace:
> [ 399.882222] panfrost_gem_free_object [panfrost] from drm_gem_handle_delete+0x84/0xb0
> [ 399.893813] drm_gem_handle_delete from drm_ioctl+0x2b8/0x4f4
> [ 399.900237] drm_ioctl from sys_ioctl+0x428/0xe30
> [ 399.905496] sys_ioctl from ret_fast_syscall+0x0/0x1c
> [ 399.911141] Exception stack(0xf22b1fa8 to 0xf22b1ff0)
> [ 399.916783] 1fa0: 004e6b40 bec37550 00000006 40086409 bec37550 00000007
> [ 399.925922] 1fc0: 004e6b40 bec37550 40086409 00000036 00000000 00000000 01cb2da0 01cb32a0
> [ 399.935058] 1fe0: b6e4b08c bec37534 b6e3442f b6bb8f98
> [ 399.940702] Code: eb0018fa e5943218 e5942214 e1a00005 (e5823004)
> [ 399.947532] ---[ end trace 0000000000000000 ]---
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
2025-05-19 16:02 ` Steven Price
@ 2025-05-20 12:53 ` Adrián Larumbe
0 siblings, 0 replies; 9+ messages in thread
From: Adrián Larumbe @ 2025-05-20 12:53 UTC (permalink / raw)
To: Steven Price
Cc: Daniel Stone, Linux Kernel Mailing List, dri-devel,
Boris Brezillon, kernel, Rob Herring, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Sumit Semwal, Christian König, Linux Media Mailing List,
moderated list:DMA BUFFER SHARING FRAMEWORK
Hi Steven,
Thanks for the fix, I've tested it and it fixes the outstanding issue.
However, including the perfcnt sample buffer in the DebugFS GEMs file raises the question of what
to do with its labelling, because it isn't exposed to UM through a handle, so my previous assumption
about not needing to handle static labels when tagging BO's within the driver no longer holds.
This might require some quick rewrite so that the sample BO can be displayed with a fitting name.
On 19.05.2025 17:02, Steven Price wrote:
> On 15/05/2025 19:04, Daniel Stone wrote:
> > Hi Steven,
> >
> > On Thu, 8 May 2025 at 11:42, Steven Price <steven.price@arm.com> wrote:
> >> I'm also seeing a splat when running this, see below. I haven't got my
> >> head around how this is happening, but I see it when glmark quits at the
> >> end of the test.
> >>
> >> [ 399.505066] Unable to handle kernel NULL pointer dereference at virtual address 00000004 when write
> >> [...]
> >> [ 399.882216] Call trace:
> >> [ 399.882222] panfrost_gem_free_object [panfrost] from drm_gem_handle_delete+0x84/0xb0
> >> [ 399.893813] drm_gem_handle_delete from drm_ioctl+0x2b8/0x4f4
> >> [ 399.900237] drm_ioctl from sys_ioctl+0x428/0xe30
> >> [ 399.905496] sys_ioctl from ret_fast_syscall+0x0/0x1c
> >
> > Soooo. Let's assume it has to actually occur in
> > panfrost_gem_debugfs_bo_rm(), since that's all that's changed here.
> >
> > I don't think pfdev can be NULL here, because we've already
> > dereferenced ptdev and written to a structure member earlier in
> > panfrost_gem_free_object(). I don't think it can be the debugfs mutex,
> > because a) that's initialised with the device, and b) wouldn't be
> > offset 0x4.
> >
> > I'm looking then at list_del_init(&bo->debugfs.node), which would
> > effectively execute bo->debugfs.node->next->prev =
> > bo->debugfs.node->prev. So if bo->debugfs.node->next was NULL, that
> > would explain a write to 0x4 on 32-bit systems.
>
> So I finally got some time to do some debugging on this. And you are
> absolutely correct on where the fault is triggered.
>
> The cause of it is that panfrost_gem_debugfs_bo_add() is called from
> panfrost_gem_create(), but that isn't the only place that Panfrost GEM
> objects are created - it turns out panfrost_perfcnt_enable_locked() also
> calls drm_gem_shmem_create(). And in that case the list next/prev
> pointers are left set to NULL, causing things to blow up when the GEM
> object is freed.
>
> The below patch gets things working, or alternatively just init the list
> in panfrost_gem_create_object() if we don't want to include the perfcnt
> buffer in the list.
> Steve
>
> ---8<--
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c
> b/drivers/gpu/drm/panfrost/panfrost_gem.c
> index fe2cdbe8baf0..51da13cd81f0 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gem.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
> @@ -297,13 +297,14 @@ struct drm_gem_object
> *panfrost_gem_create_object(struct drm_device *dev, size_t
> obj->base.map_wc = !pfdev->coherent;
> mutex_init(&obj->label.lock);
>
> + panfrost_gem_debugfs_bo_add(pfdev, obj);
> +
> return &obj->base.base;
> }
>
> struct panfrost_gem_object *
> panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
> {
> - struct panfrost_device *pfdev = dev->dev_private;
> struct drm_gem_shmem_object *shmem;
> struct panfrost_gem_object *bo;
>
> @@ -319,8 +320,6 @@ panfrost_gem_create(struct drm_device *dev, size_t
> size, u32 flags)
> bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
> bo->is_heap = !!(flags & PANFROST_BO_HEAP);
>
> - panfrost_gem_debugfs_bo_add(pfdev, bo);
> -
> return bo;
> }
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-05-20 12:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-07 16:07 [PATCH v2 0/3] Panfrost BO tagging and GEMS debug display Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 1/3] drm/panfrost: Add BO labelling to Panfrost Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 2/3] drm/panfrost: Add driver IOCTL for setting BO labels Adrián Larumbe
2025-05-07 16:07 ` [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS Adrián Larumbe
2025-05-08 10:42 ` Steven Price
2025-05-15 18:04 ` Daniel Stone
2025-05-19 16:02 ` Steven Price
2025-05-20 12:53 ` Adrián Larumbe
2025-05-20 11:30 ` 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;
as well as URLs for NNTP newsgroup(s).