... | ... | ||
---|---|---|---|
4 | through a new IOCTL. | 4 | through a new IOCTL. |
5 | 5 | ||
6 | The new debugfs file shows a list of driver DRM GEM objects in tabular mode. | 6 | The new debugfs file shows a list of driver DRM GEM objects in tabular mode. |
7 | To visualise it, cat sudo cat /sys/kernel/debug/dri/*.gpu/gems. | 7 | To visualise it, cat sudo cat /sys/kernel/debug/dri/*.gpu/gems. |
8 | To test this functionality from UM, please refer to this Mesa patch series: | 8 | To test this functionality from UM, please refer to this Mesa patch series: |
9 | https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34224 | ||
9 | 10 | ||
10 | https://gitlab.collabora.com/alarumbe/mesa/-/commits/bo-tagging-panthor-gl | 11 | Discussion of previous revision of this patch series can be found at: |
12 | https://lore.kernel.org/dri-devel/20250327140845.105962-1-adrian.larumbe@collabora.com/ | ||
13 | |||
14 | Changelog: | ||
15 | |||
16 | v4: | ||
17 | - Labelled all kernel BO's, not just heap chunks. | ||
18 | - Refactored DebugGFs GEMs list handling functions | ||
19 | - Added debugfs GEMS node mask to tell different kinds of BO's | ||
11 | 20 | ||
12 | Adrián Larumbe (4): | 21 | Adrián Larumbe (4): |
13 | drm/panthor: Introduce BO labeling | 22 | drm/panthor: Introduce BO labeling |
14 | drm/panthor: Add driver IOCTL for setting BO labels | 23 | drm/panthor: Add driver IOCTL for setting BO labels |
24 | drm/panthor: Label all kernel BO's | ||
15 | drm/panthor: show device-wide list of DRM GEM objects over DebugFS | 25 | drm/panthor: show device-wide list of DRM GEM objects over DebugFS |
16 | drm/panthor: Display heap chunk entries in DebugFS GEMS file | ||
17 | 26 | ||
18 | drivers/gpu/drm/panthor/panthor_device.c | 5 + | 27 | drivers/gpu/drm/panthor/panthor_device.c | 5 + |
19 | drivers/gpu/drm/panthor/panthor_device.h | 8 ++ | 28 | drivers/gpu/drm/panthor/panthor_device.h | 11 ++ |
20 | drivers/gpu/drm/panthor/panthor_drv.c | 57 +++++++++++ | 29 | drivers/gpu/drm/panthor/panthor_drv.c | 66 ++++++++ |
21 | drivers/gpu/drm/panthor/panthor_gem.c | 119 +++++++++++++++++++++++ | 30 | drivers/gpu/drm/panthor/panthor_fw.c | 8 +- |
22 | drivers/gpu/drm/panthor/panthor_gem.h | 34 +++++++ | 31 | drivers/gpu/drm/panthor/panthor_gem.c | 190 ++++++++++++++++++++++- |
23 | drivers/gpu/drm/panthor/panthor_heap.c | 15 +++ | 32 | drivers/gpu/drm/panthor/panthor_gem.h | 56 ++++++- |
24 | include/uapi/drm/panthor_drm.h | 14 +++ | 33 | drivers/gpu/drm/panthor/panthor_heap.c | 6 +- |
25 | 7 files changed, 252 insertions(+) | 34 | drivers/gpu/drm/panthor/panthor_sched.c | 9 +- |
35 | include/uapi/drm/panthor_drm.h | 19 +++ | ||
36 | 9 files changed, 360 insertions(+), 10 deletions(-) | ||
26 | 37 | ||
27 | -- | 38 | -- |
28 | 2.48.1 | 39 | 2.48.1 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
5 | needed at object destruction time, but allocating it is the responsibility | 5 | needed at object destruction time, but allocating it is the responsibility |
6 | of callers. | 6 | of callers. |
7 | 7 | ||
8 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> | 8 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> |
9 | --- | 9 | --- |
10 | drivers/gpu/drm/panthor/panthor_gem.c | 18 ++++++++++++++++++ | 10 | drivers/gpu/drm/panthor/panthor_gem.c | 38 +++++++++++++++++++++++++++ |
11 | drivers/gpu/drm/panthor/panthor_gem.h | 12 ++++++++++++ | 11 | drivers/gpu/drm/panthor/panthor_gem.h | 17 ++++++++++++ |
12 | 2 files changed, 30 insertions(+) | 12 | 2 files changed, 55 insertions(+) |
13 | 13 | ||
14 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c | 14 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c |
15 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/drivers/gpu/drm/panthor/panthor_gem.c | 16 | --- a/drivers/gpu/drm/panthor/panthor_gem.c |
17 | +++ b/drivers/gpu/drm/panthor/panthor_gem.c | 17 | +++ b/drivers/gpu/drm/panthor/panthor_gem.c |
18 | @@ -XXX,XX +XXX,XX @@ static void panthor_gem_free_object(struct drm_gem_object *obj) | 18 | @@ -XXX,XX +XXX,XX @@ static void panthor_gem_free_object(struct drm_gem_object *obj) |
19 | struct panthor_gem_object *bo = to_panthor_bo(obj); | 19 | struct panthor_gem_object *bo = to_panthor_bo(obj); |
20 | struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem; | 20 | struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem; |
21 | 21 | ||
22 | + kfree(bo->label); | 22 | + /* |
23 | + mutex_destroy(&bo->label_lock); | 23 | + * Label might have been allocated with kstrdup_const(), |
24 | + * we need to take that into account when freeing the memory | ||
25 | + */ | ||
26 | + kfree_const(bo->label.str); | ||
27 | + | ||
28 | + mutex_destroy(&bo->label.lock); | ||
24 | + | 29 | + |
25 | drm_gem_free_mmap_offset(&bo->base.base); | 30 | drm_gem_free_mmap_offset(&bo->base.base); |
26 | mutex_destroy(&bo->gpuva_list_lock); | 31 | mutex_destroy(&bo->gpuva_list_lock); |
27 | drm_gem_shmem_free(&bo->base); | 32 | drm_gem_shmem_free(&bo->base); |
28 | @@ -XXX,XX +XXX,XX @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t | 33 | @@ -XXX,XX +XXX,XX @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t |
29 | obj->base.map_wc = !ptdev->coherent; | 34 | obj->base.map_wc = !ptdev->coherent; |
30 | mutex_init(&obj->gpuva_list_lock); | 35 | mutex_init(&obj->gpuva_list_lock); |
31 | drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock); | 36 | drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock); |
32 | + mutex_init(&obj->label_lock); | 37 | + mutex_init(&obj->label.lock); |
33 | 38 | ||
34 | return &obj->base.base; | 39 | return &obj->base.base; |
35 | } | 40 | } |
36 | @@ -XXX,XX +XXX,XX @@ panthor_gem_create_with_handle(struct drm_file *file, | 41 | @@ -XXX,XX +XXX,XX @@ panthor_gem_create_with_handle(struct drm_file *file, |
37 | 42 | ||
38 | return ret; | 43 | return ret; |
39 | } | 44 | } |
40 | + | 45 | + |
41 | +void | 46 | +void |
42 | +panthor_gem_label_bo(struct drm_gem_object *obj, const char *label) | 47 | +panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label) |
43 | +{ | 48 | +{ |
44 | + struct panthor_gem_object *bo = to_panthor_bo(obj); | 49 | + struct panthor_gem_object *bo = to_panthor_bo(obj); |
45 | + const char *old_label; | 50 | + const char *old_label; |
46 | + | 51 | + |
47 | + mutex_lock(&bo->label_lock); | 52 | + mutex_lock(&bo->label.lock); |
48 | + old_label = bo->label; | 53 | + old_label = bo->label.str; |
49 | + bo->label = label; | 54 | + bo->label.str = label; |
50 | + mutex_unlock(&bo->label_lock); | 55 | + mutex_unlock(&bo->label.lock); |
51 | + | 56 | + |
52 | + kfree(old_label); | 57 | + kfree(old_label); |
58 | +} | ||
59 | + | ||
60 | +void | ||
61 | +panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label) | ||
62 | +{ | ||
63 | + const char *str; | ||
64 | + | ||
65 | + str = kstrdup_const(label, GFP_KERNEL); | ||
66 | + if (!str) { | ||
67 | + /* Failing to allocate memory for a label isn't a fatal condition */ | ||
68 | + drm_warn(bo->obj->dev, "Not enough memory to allocate BO label"); | ||
69 | + return; | ||
70 | + } | ||
71 | + | ||
72 | + panthor_gem_bo_set_label(bo->obj, kstrdup_const(str, GFP_KERNEL)); | ||
53 | +} | 73 | +} |
54 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h | 74 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h |
55 | index XXXXXXX..XXXXXXX 100644 | 75 | index XXXXXXX..XXXXXXX 100644 |
56 | --- a/drivers/gpu/drm/panthor/panthor_gem.h | 76 | --- a/drivers/gpu/drm/panthor/panthor_gem.h |
57 | +++ b/drivers/gpu/drm/panthor/panthor_gem.h | 77 | +++ b/drivers/gpu/drm/panthor/panthor_gem.h |
58 | @@ -XXX,XX +XXX,XX @@ struct panthor_gem_object { | 78 | @@ -XXX,XX +XXX,XX @@ struct panthor_gem_object { |
59 | 79 | ||
60 | /** @flags: Combination of drm_panthor_bo_flags flags. */ | 80 | /** @flags: Combination of drm_panthor_bo_flags flags. */ |
61 | u32 flags; | 81 | u32 flags; |
62 | + | 82 | + |
63 | + /** | 83 | + /** |
64 | + * @label: Pointer to NULL-terminated string, can be assigned within the | 84 | + * @label: BO tagging fields. The label can be assigned within the |
65 | + * driver itself or through a specific IOCTL. | 85 | + * driver itself or through a specific IOCTL. |
66 | + */ | 86 | + */ |
67 | + const char *label; | 87 | + struct { |
88 | + /** | ||
89 | + * @label.str: Pointer to NULL-terminated string, | ||
90 | + */ | ||
91 | + const char *str; | ||
68 | + | 92 | + |
69 | + /** @label_lock: Lock that protects access to the @label field. */ | 93 | + /** @lock.str: Protects access to the @label.str field. */ |
70 | + struct mutex label_lock; | 94 | + struct mutex lock; |
95 | + } label; | ||
71 | }; | 96 | }; |
72 | 97 | ||
73 | /** | 98 | /** |
74 | @@ -XXX,XX +XXX,XX @@ panthor_gem_create_with_handle(struct drm_file *file, | 99 | @@ -XXX,XX +XXX,XX @@ panthor_gem_create_with_handle(struct drm_file *file, |
75 | struct panthor_vm *exclusive_vm, | 100 | struct panthor_vm *exclusive_vm, |
76 | u64 *size, u32 flags, uint32_t *handle); | 101 | u64 *size, u32 flags, uint32_t *handle); |
77 | 102 | ||
78 | +void | 103 | +void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label); |
79 | +panthor_gem_label_bo(struct drm_gem_object *obj, const char *label); | 104 | +void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label); |
80 | + | 105 | + |
81 | static inline u64 | 106 | static inline u64 |
82 | panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo) | 107 | panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo) |
83 | { | 108 | { |
84 | -- | 109 | -- |
85 | 2.48.1 | 110 | 2.48.1 |
86 | 111 | diff view generated by jsdifflib |
1 | Allow UM to label a BO for which it possesses a DRM handle. | 1 | Allow UM to label a BO for which it possesses a DRM handle. |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> | 3 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> |
4 | --- | 4 | --- |
5 | drivers/gpu/drm/panthor/panthor_drv.c | 31 +++++++++++++++++++++++++++ | 5 | drivers/gpu/drm/panthor/panthor_drv.c | 40 +++++++++++++++++++++++++++ |
6 | include/uapi/drm/panthor_drm.h | 14 ++++++++++++ | 6 | drivers/gpu/drm/panthor/panthor_gem.h | 2 ++ |
7 | 2 files changed, 45 insertions(+) | 7 | include/uapi/drm/panthor_drm.h | 19 +++++++++++++ |
8 | 3 files changed, 61 insertions(+) | ||
8 | 9 | ||
9 | diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c | 10 | diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c |
10 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
11 | --- a/drivers/gpu/drm/panthor/panthor_drv.c | 12 | --- a/drivers/gpu/drm/panthor/panthor_drv.c |
12 | +++ b/drivers/gpu/drm/panthor/panthor_drv.c | 13 | +++ b/drivers/gpu/drm/panthor/panthor_drv.c |
13 | @@ -XXX,XX +XXX,XX @@ static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data, | 14 | @@ -XXX,XX +XXX,XX @@ static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data, |
14 | return 0; | 15 | return 0; |
15 | } | 16 | } |
16 | 17 | ||
17 | +static int panthor_ioctl_label_bo(struct drm_device *ddev, void *data, | 18 | +static int panthor_ioctl_bo_set_label(struct drm_device *ddev, void *data, |
18 | + struct drm_file *file) | 19 | + struct drm_file *file) |
19 | +{ | 20 | +{ |
20 | + struct drm_panthor_label_bo *args = data; | 21 | + struct drm_panthor_bo_set_label *args = data; |
21 | + struct drm_gem_object *obj; | 22 | + struct drm_gem_object *obj; |
22 | + const char *label; | 23 | + const char *label; |
23 | + int ret = 0; | 24 | + int ret = 0; |
24 | + | 25 | + |
25 | + obj = drm_gem_object_lookup(file, args->handle); | 26 | + obj = drm_gem_object_lookup(file, args->handle); |
26 | + if (!obj) | 27 | + if (!obj) |
27 | + return -ENOENT; | 28 | + return -ENOENT; |
28 | + | 29 | + |
29 | + if (args->len && args->label) { | 30 | + if (args->size && args->label) { |
30 | + label = strndup_user(u64_to_user_ptr(args->label), args->len + 1); | 31 | + if (args->size > PANTHOR_BO_LABEL_MAXLEN) { |
32 | + ret = -E2BIG; | ||
33 | + goto err_label; | ||
34 | + } | ||
35 | + | ||
36 | + label = strndup_user(u64_to_user_ptr(args->label), args->size); | ||
31 | + if (IS_ERR(label)) { | 37 | + if (IS_ERR(label)) { |
32 | + ret = PTR_ERR(label); | 38 | + ret = PTR_ERR(label); |
33 | + goto err_label; | 39 | + goto err_label; |
34 | + } | 40 | + } |
35 | + } else | 41 | + } else if (args->size && !args->label) { |
42 | + ret = -EINVAL; | ||
43 | + goto err_label; | ||
44 | + } else { | ||
36 | + label = NULL; | 45 | + label = NULL; |
46 | + } | ||
37 | + | 47 | + |
38 | + panthor_gem_label_bo(obj, label); | 48 | + panthor_gem_bo_set_label(obj, label); |
39 | + | 49 | + |
40 | +err_label: | 50 | +err_label: |
41 | + drm_gem_object_put(obj); | 51 | + drm_gem_object_put(obj); |
42 | + | 52 | + |
43 | + return ret; | 53 | + return ret; |
... | ... | ||
48 | { | 58 | { |
49 | @@ -XXX,XX +XXX,XX @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = { | 59 | @@ -XXX,XX +XXX,XX @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = { |
50 | PANTHOR_IOCTL(TILER_HEAP_CREATE, tiler_heap_create, DRM_RENDER_ALLOW), | 60 | PANTHOR_IOCTL(TILER_HEAP_CREATE, tiler_heap_create, DRM_RENDER_ALLOW), |
51 | PANTHOR_IOCTL(TILER_HEAP_DESTROY, tiler_heap_destroy, DRM_RENDER_ALLOW), | 61 | PANTHOR_IOCTL(TILER_HEAP_DESTROY, tiler_heap_destroy, DRM_RENDER_ALLOW), |
52 | PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW), | 62 | PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW), |
53 | + PANTHOR_IOCTL(LABEL_BO, label_bo, DRM_RENDER_ALLOW), | 63 | + PANTHOR_IOCTL(BO_SET_LABEL, bo_set_label, DRM_RENDER_ALLOW), |
54 | }; | 64 | }; |
55 | 65 | ||
56 | static int panthor_mmap(struct file *filp, struct vm_area_struct *vma) | 66 | static int panthor_mmap(struct file *filp, struct vm_area_struct *vma) |
57 | @@ -XXX,XX +XXX,XX @@ static void panthor_debugfs_init(struct drm_minor *minor) | 67 | @@ -XXX,XX +XXX,XX @@ static void panthor_debugfs_init(struct drm_minor *minor) |
58 | * - 1.2 - adds DEV_QUERY_GROUP_PRIORITIES_INFO query | 68 | * - 1.2 - adds DEV_QUERY_GROUP_PRIORITIES_INFO query |
59 | * - adds PANTHOR_GROUP_PRIORITY_REALTIME priority | 69 | * - adds PANTHOR_GROUP_PRIORITY_REALTIME priority |
60 | * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag | 70 | * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag |
61 | + * - 1.4 - adds DRM_IOCTL_PANTHOR_LABEL_BO ioctl | 71 | + * - 1.4 - adds DRM_IOCTL_PANTHOR_BO_SET_LABEL ioctl |
62 | */ | 72 | */ |
63 | static const struct drm_driver panthor_drm_driver = { | 73 | static const struct drm_driver panthor_drm_driver = { |
64 | .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ | | 74 | .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ | |
75 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h | ||
76 | index XXXXXXX..XXXXXXX 100644 | ||
77 | --- a/drivers/gpu/drm/panthor/panthor_gem.h | ||
78 | +++ b/drivers/gpu/drm/panthor/panthor_gem.h | ||
79 | @@ -XXX,XX +XXX,XX @@ | ||
80 | |||
81 | struct panthor_vm; | ||
82 | |||
83 | +#define PANTHOR_BO_LABEL_MAXLEN PAGE_SIZE | ||
84 | + | ||
85 | /** | ||
86 | * struct panthor_gem_object - Driver specific GEM object. | ||
87 | */ | ||
65 | diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h | 88 | diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h |
66 | index XXXXXXX..XXXXXXX 100644 | 89 | index XXXXXXX..XXXXXXX 100644 |
67 | --- a/include/uapi/drm/panthor_drm.h | 90 | --- a/include/uapi/drm/panthor_drm.h |
68 | +++ b/include/uapi/drm/panthor_drm.h | 91 | +++ b/include/uapi/drm/panthor_drm.h |
69 | @@ -XXX,XX +XXX,XX @@ enum drm_panthor_ioctl_id { | 92 | @@ -XXX,XX +XXX,XX @@ enum drm_panthor_ioctl_id { |
70 | 93 | ||
71 | /** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */ | 94 | /** @DRM_PANTHOR_TILER_HEAP_DESTROY: Destroy a tiler heap. */ |
72 | DRM_PANTHOR_TILER_HEAP_DESTROY, | 95 | DRM_PANTHOR_TILER_HEAP_DESTROY, |
73 | + | 96 | + |
74 | + /** @DRM_PANTHOR_LABEL_BO: Label a BO. */ | 97 | + /** @DRM_PANTHOR_BO_SET_LABEL: Label a BO. */ |
75 | + DRM_PANTHOR_LABEL_BO, | 98 | + DRM_PANTHOR_BO_SET_LABEL, |
76 | }; | 99 | }; |
77 | 100 | ||
78 | /** | 101 | /** |
79 | @@ -XXX,XX +XXX,XX @@ struct drm_panthor_tiler_heap_destroy { | 102 | @@ -XXX,XX +XXX,XX @@ struct drm_panthor_tiler_heap_destroy { |
80 | __u32 pad; | 103 | __u32 pad; |
81 | }; | 104 | }; |
82 | 105 | ||
83 | +/** | 106 | +/** |
84 | + * struct drm_panthor_label_bo - Arguments passed to DRM_IOCTL_PANTHOR_LABEL_BO | 107 | + * struct drm_panthor_bo_set_label - Arguments passed to DRM_IOCTL_PANTHOR_BO_SET_LABEL |
85 | + */ | 108 | + */ |
86 | +struct drm_panthor_label_bo { | 109 | +struct drm_panthor_bo_set_label { |
110 | + /** @handle: Handle of the buffer object to label. */ | ||
87 | + __u32 handle; | 111 | + __u32 handle; |
88 | + __u32 len; | 112 | + |
113 | + /** @size: Length of the label, including the NULL terminator. */ | ||
114 | + __u32 size; | ||
115 | + | ||
116 | + /** @label: User pointer to a NULL-terminated string */ | ||
89 | + __u64 label; | 117 | + __u64 label; |
90 | +}; | 118 | +}; |
91 | + | 119 | + |
92 | /** | 120 | /** |
93 | * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number | 121 | * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number |
94 | * @__access: Access type. Must be R, W or RW. | 122 | * @__access: Access type. Must be R, W or RW. |
95 | @@ -XXX,XX +XXX,XX @@ enum { | 123 | @@ -XXX,XX +XXX,XX @@ enum { |
96 | DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create), | 124 | DRM_IOCTL_PANTHOR(WR, TILER_HEAP_CREATE, tiler_heap_create), |
97 | DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY = | 125 | DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY = |
98 | DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy), | 126 | DRM_IOCTL_PANTHOR(WR, TILER_HEAP_DESTROY, tiler_heap_destroy), |
99 | + DRM_IOCTL_PANTHOR_LABEL_BO = | 127 | + DRM_IOCTL_PANTHOR_BO_SET_LABEL = |
100 | + DRM_IOCTL_PANTHOR(WR, LABEL_BO, label_bo), | 128 | + DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label), |
101 | }; | 129 | }; |
102 | 130 | ||
103 | #if defined(__cplusplus) | 131 | #if defined(__cplusplus) |
104 | -- | 132 | -- |
105 | 2.48.1 | 133 | 2.48.1 |
106 | 134 | diff view generated by jsdifflib |
1 | Expand the driver's DebugFS GEMS file to display entries for the heap | 1 | Kernel BO's aren't exposed to UM, so labelling them is the responsibility |
---|---|---|---|
2 | chunks' GEM objects, both those allocated at heap creation time through an | 2 | of the driver itself. This kind of tagging will prove useful in further |
3 | ioctl(), or in response to a tiler OOM event. | 3 | commits when want to expose these objects through DebugFS. |
4 | |||
5 | Expand panthor_kernel_bo_create() interface to take a NULL-terminated | ||
6 | string. No bounds checking is done because all label strings are given | ||
7 | as statically-allocated literals, but if a more complex kernel BO naming | ||
8 | scheme with explicit memory allocation and formatting was desired in the | ||
9 | future, this would have to change. | ||
4 | 10 | ||
5 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> | 11 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> |
6 | --- | 12 | --- |
7 | drivers/gpu/drm/panthor/panthor_heap.c | 15 +++++++++++++++ | 13 | drivers/gpu/drm/panthor/panthor_fw.c | 8 +++++--- |
8 | 1 file changed, 15 insertions(+) | 14 | drivers/gpu/drm/panthor/panthor_gem.c | 3 ++- |
15 | drivers/gpu/drm/panthor/panthor_gem.h | 2 +- | ||
16 | drivers/gpu/drm/panthor/panthor_heap.c | 6 ++++-- | ||
17 | drivers/gpu/drm/panthor/panthor_sched.c | 9 ++++++--- | ||
18 | 5 files changed, 18 insertions(+), 10 deletions(-) | ||
9 | 19 | ||
20 | diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/drivers/gpu/drm/panthor/panthor_fw.c | ||
23 | +++ b/drivers/gpu/drm/panthor/panthor_fw.c | ||
24 | @@ -XXX,XX +XXX,XX @@ panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev, | ||
25 | DRM_PANTHOR_BO_NO_MMAP, | ||
26 | DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | | ||
27 | DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, | ||
28 | - PANTHOR_VM_KERNEL_AUTO_VA); | ||
29 | + PANTHOR_VM_KERNEL_AUTO_VA, | ||
30 | + "Queue FW interface"); | ||
31 | if (IS_ERR(mem)) | ||
32 | return mem; | ||
33 | |||
34 | @@ -XXX,XX +XXX,XX @@ panthor_fw_alloc_suspend_buf_mem(struct panthor_device *ptdev, size_t size) | ||
35 | return panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), size, | ||
36 | DRM_PANTHOR_BO_NO_MMAP, | ||
37 | DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC, | ||
38 | - PANTHOR_VM_KERNEL_AUTO_VA); | ||
39 | + PANTHOR_VM_KERNEL_AUTO_VA, | ||
40 | + "FW suspend buffer"); | ||
41 | } | ||
42 | |||
43 | static int panthor_fw_load_section_entry(struct panthor_device *ptdev, | ||
44 | @@ -XXX,XX +XXX,XX @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev, | ||
45 | section->mem = panthor_kernel_bo_create(ptdev, panthor_fw_vm(ptdev), | ||
46 | section_size, | ||
47 | DRM_PANTHOR_BO_NO_MMAP, | ||
48 | - vm_map_flags, va); | ||
49 | + vm_map_flags, va, "FW Section"); | ||
50 | if (IS_ERR(section->mem)) | ||
51 | return PTR_ERR(section->mem); | ||
52 | |||
53 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c | ||
54 | index XXXXXXX..XXXXXXX 100644 | ||
55 | --- a/drivers/gpu/drm/panthor/panthor_gem.c | ||
56 | +++ b/drivers/gpu/drm/panthor/panthor_gem.c | ||
57 | @@ -XXX,XX +XXX,XX @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) | ||
58 | struct panthor_kernel_bo * | ||
59 | panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, | ||
60 | size_t size, u32 bo_flags, u32 vm_map_flags, | ||
61 | - u64 gpu_va) | ||
62 | + u64 gpu_va, const char *name) | ||
63 | { | ||
64 | struct drm_gem_shmem_object *obj; | ||
65 | struct panthor_kernel_bo *kbo; | ||
66 | @@ -XXX,XX +XXX,XX @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, | ||
67 | kbo->obj = &obj->base; | ||
68 | bo->flags = bo_flags; | ||
69 | |||
70 | + panthor_gem_kernel_bo_set_label(kbo, name); | ||
71 | /* The system and GPU MMU page size might differ, which becomes a | ||
72 | * problem for FW sections that need to be mapped at explicit address | ||
73 | * since our PAGE_SIZE alignment might cover a VA range that's | ||
74 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h | ||
75 | index XXXXXXX..XXXXXXX 100644 | ||
76 | --- a/drivers/gpu/drm/panthor/panthor_gem.h | ||
77 | +++ b/drivers/gpu/drm/panthor/panthor_gem.h | ||
78 | @@ -XXX,XX +XXX,XX @@ panthor_kernel_bo_vunmap(struct panthor_kernel_bo *bo) | ||
79 | struct panthor_kernel_bo * | ||
80 | panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, | ||
81 | size_t size, u32 bo_flags, u32 vm_map_flags, | ||
82 | - u64 gpu_va); | ||
83 | + u64 gpu_va, const char *name); | ||
84 | |||
85 | void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo); | ||
86 | |||
10 | diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c | 87 | diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c |
11 | index XXXXXXX..XXXXXXX 100644 | 88 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/gpu/drm/panthor/panthor_heap.c | 89 | --- a/drivers/gpu/drm/panthor/panthor_heap.c |
13 | +++ b/drivers/gpu/drm/panthor/panthor_heap.c | 90 | +++ b/drivers/gpu/drm/panthor/panthor_heap.c |
14 | @@ -XXX,XX +XXX,XX @@ static int panthor_alloc_heap_chunk(struct panthor_device *ptdev, | 91 | @@ -XXX,XX +XXX,XX @@ static int panthor_alloc_heap_chunk(struct panthor_device *ptdev, |
15 | struct panthor_heap_chunk *chunk; | 92 | chunk->bo = panthor_kernel_bo_create(ptdev, vm, heap->chunk_size, |
16 | struct panthor_heap_chunk_header *hdr; | 93 | DRM_PANTHOR_BO_NO_MMAP, |
17 | int ret; | 94 | DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC, |
18 | +#ifdef CONFIG_DEBUG_FS | 95 | - PANTHOR_VM_KERNEL_AUTO_VA); |
19 | + struct panthor_gem_object *obj; | 96 | + PANTHOR_VM_KERNEL_AUTO_VA, |
20 | + const char *label; | 97 | + "Tiler heap chunk"); |
21 | +#endif | 98 | if (IS_ERR(chunk->bo)) { |
22 | 99 | ret = PTR_ERR(chunk->bo); | |
23 | chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); | 100 | goto err_free_chunk; |
24 | if (!chunk) | 101 | @@ -XXX,XX +XXX,XX @@ panthor_heap_pool_create(struct panthor_device *ptdev, struct panthor_vm *vm) |
25 | @@ -XXX,XX +XXX,XX @@ static int panthor_alloc_heap_chunk(struct panthor_device *ptdev, | 102 | pool->gpu_contexts = panthor_kernel_bo_create(ptdev, vm, bosize, |
26 | heap->chunk_count++; | 103 | DRM_PANTHOR_BO_NO_MMAP, |
27 | mutex_unlock(&heap->lock); | 104 | DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC, |
28 | 105 | - PANTHOR_VM_KERNEL_AUTO_VA); | |
29 | +#ifdef CONFIG_DEBUG_FS | 106 | + PANTHOR_VM_KERNEL_AUTO_VA, |
30 | + obj = to_panthor_bo(chunk->bo->obj); | 107 | + "Heap pool"); |
31 | + | 108 | if (IS_ERR(pool->gpu_contexts)) { |
32 | + mutex_lock(&ptdev->gems_lock); | 109 | ret = PTR_ERR(pool->gpu_contexts); |
33 | + list_add_tail(&obj->gems_node, &ptdev->gems); | 110 | goto err_destroy_pool; |
34 | + mutex_unlock(&ptdev->gems_lock); | 111 | diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c |
35 | + | 112 | index XXXXXXX..XXXXXXX 100644 |
36 | + label = kstrdup_const("\"Tiler heap chunk\"", GFP_KERNEL); | 113 | --- a/drivers/gpu/drm/panthor/panthor_sched.c |
37 | + panthor_gem_label_bo(chunk->bo->obj, label); | 114 | +++ b/drivers/gpu/drm/panthor/panthor_sched.c |
38 | +#endif | 115 | @@ -XXX,XX +XXX,XX @@ group_create_queue(struct panthor_group *group, |
39 | + | 116 | DRM_PANTHOR_BO_NO_MMAP, |
40 | return 0; | 117 | DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | |
41 | 118 | DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, | |
42 | err_destroy_bo: | 119 | - PANTHOR_VM_KERNEL_AUTO_VA); |
120 | + PANTHOR_VM_KERNEL_AUTO_VA, | ||
121 | + "Ring buffer"); | ||
122 | if (IS_ERR(queue->ringbuf)) { | ||
123 | ret = PTR_ERR(queue->ringbuf); | ||
124 | goto err_free_queue; | ||
125 | @@ -XXX,XX +XXX,XX @@ group_create_queue(struct panthor_group *group, | ||
126 | DRM_PANTHOR_BO_NO_MMAP, | ||
127 | DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | | ||
128 | DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, | ||
129 | - PANTHOR_VM_KERNEL_AUTO_VA); | ||
130 | + PANTHOR_VM_KERNEL_AUTO_VA, | ||
131 | + "fdinfo slots"); | ||
132 | |||
133 | if (IS_ERR(queue->profiling.slots)) { | ||
134 | ret = PTR_ERR(queue->profiling.slots); | ||
135 | @@ -XXX,XX +XXX,XX @@ int panthor_group_create(struct panthor_file *pfile, | ||
136 | DRM_PANTHOR_BO_NO_MMAP, | ||
137 | DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | | ||
138 | DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED, | ||
139 | - PANTHOR_VM_KERNEL_AUTO_VA); | ||
140 | + PANTHOR_VM_KERNEL_AUTO_VA, | ||
141 | + "Group sync objects"); | ||
142 | if (IS_ERR(group->syncobjs)) { | ||
143 | ret = PTR_ERR(group->syncobjs); | ||
144 | goto err_put_group; | ||
43 | -- | 145 | -- |
44 | 2.48.1 | 146 | 2.48.1 |
45 | 147 | diff view generated by jsdifflib |
1 | Add a device DebugFS file that displays a complete list of all the DRM GEM | 1 | Add a device DebugFS file that displays a complete list of all the DRM |
---|---|---|---|
2 | objects that are exposed to UM through a DRM handle. | 2 | GEM objects that are exposed to UM through a DRM handle. |
3 | 3 | ||
4 | Since leaking object identifiers that might belong to a different NS is | 4 | Since leaking object identifiers that might belong to a different NS is |
5 | inadmissible, this functionality is only made available in debug builds | 5 | inadmissible, this functionality is only made available in debug builds |
6 | with DEBUGFS support enabled. | 6 | with DEBUGFS support enabled. |
7 | 7 | ||
8 | File format is that of a table, with each entry displaying a variety of | 8 | File format is that of a table, with each entry displaying a variety of |
9 | fields with information about each GEM object. | 9 | fields with information about each GEM object. |
10 | 10 | ||
11 | Each GEM object entry in the file displays the following information | 11 | Each GEM object entry in the file displays the following information |
12 | fields: Client PID, BO's global name, reference count, BO virtual size, BO | 12 | fields: Client PID, BO's global name, reference count, BO virtual size, |
13 | resize size, VM address in its DRM-managed range, BO label and a flag | 13 | BO resize size, VM address in its DRM-managed range, BO label and a flag |
14 | bitmask. | 14 | bitmask. |
15 | |||
16 | There's also a kflags field for the type of BO. Bit 0 tells us whether | ||
17 | it's a kernel BO, and bit 1 means the BO is mapped onto the FW's address | ||
18 | space. | ||
15 | 19 | ||
16 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> | 20 | Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> |
17 | --- | 21 | --- |
18 | drivers/gpu/drm/panthor/panthor_device.c | 5 ++ | 22 | drivers/gpu/drm/panthor/panthor_device.c | 5 + |
19 | drivers/gpu/drm/panthor/panthor_device.h | 8 ++ | 23 | drivers/gpu/drm/panthor/panthor_device.h | 11 ++ |
20 | drivers/gpu/drm/panthor/panthor_drv.c | 26 ++++++ | 24 | drivers/gpu/drm/panthor/panthor_drv.c | 26 ++++ |
21 | drivers/gpu/drm/panthor/panthor_gem.c | 101 +++++++++++++++++++++++ | 25 | drivers/gpu/drm/panthor/panthor_gem.c | 149 +++++++++++++++++++++++ |
22 | drivers/gpu/drm/panthor/panthor_gem.h | 22 +++++ | 26 | drivers/gpu/drm/panthor/panthor_gem.h | 35 ++++++ |
23 | 5 files changed, 162 insertions(+) | 27 | 5 files changed, 226 insertions(+) |
24 | 28 | ||
25 | diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c | 29 | diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c |
26 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
27 | --- a/drivers/gpu/drm/panthor/panthor_device.c | 31 | --- a/drivers/gpu/drm/panthor/panthor_device.c |
28 | +++ b/drivers/gpu/drm/panthor/panthor_device.c | 32 | +++ b/drivers/gpu/drm/panthor/panthor_device.c |
29 | @@ -XXX,XX +XXX,XX @@ int panthor_device_init(struct panthor_device *ptdev) | 33 | @@ -XXX,XX +XXX,XX @@ int panthor_device_init(struct panthor_device *ptdev) |
30 | pm_runtime_set_autosuspend_delay(ptdev->base.dev, 50); | ||
31 | pm_runtime_use_autosuspend(ptdev->base.dev); | ||
32 | |||
33 | +#ifdef CONFIG_DEBUG_FS | ||
34 | + drmm_mutex_init(&ptdev->base, &ptdev->gems_lock); | ||
35 | + INIT_LIST_HEAD(&ptdev->gems); | ||
36 | +#endif | ||
37 | + | ||
38 | ret = drm_dev_register(&ptdev->base, 0); | ||
39 | if (ret) | 34 | if (ret) |
40 | goto err_disable_autosuspend; | 35 | return ret; |
36 | |||
37 | +#ifdef CONFIG_DEBUG_FS | ||
38 | + drmm_mutex_init(&ptdev->base, &ptdev->gems.lock); | ||
39 | + INIT_LIST_HEAD(&ptdev->gems.node); | ||
40 | +#endif | ||
41 | + | ||
42 | atomic_set(&ptdev->pm.state, PANTHOR_DEVICE_PM_STATE_SUSPENDED); | ||
43 | p = alloc_page(GFP_KERNEL | __GFP_ZERO); | ||
44 | if (!p) | ||
41 | diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h | 45 | diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h |
42 | index XXXXXXX..XXXXXXX 100644 | 46 | index XXXXXXX..XXXXXXX 100644 |
43 | --- a/drivers/gpu/drm/panthor/panthor_device.h | 47 | --- a/drivers/gpu/drm/panthor/panthor_device.h |
44 | +++ b/drivers/gpu/drm/panthor/panthor_device.h | 48 | +++ b/drivers/gpu/drm/panthor/panthor_device.h |
45 | @@ -XXX,XX +XXX,XX @@ struct panthor_device { | 49 | @@ -XXX,XX +XXX,XX @@ struct panthor_device { |
46 | 50 | ||
47 | /** @fast_rate: Maximum device clock frequency. Set by DVFS */ | 51 | /** @fast_rate: Maximum device clock frequency. Set by DVFS */ |
48 | unsigned long fast_rate; | 52 | unsigned long fast_rate; |
49 | + | 53 | + |
50 | +#ifdef CONFIG_DEBUG_FS | 54 | +#ifdef CONFIG_DEBUG_FS |
51 | + /** @gems_lock: Protects the device-wide list of GEM objects. */ | ||
52 | + struct mutex gems_lock; | ||
53 | + | ||
54 | + /** @gems: Device-wide list of GEM objects owned by at least one file. */ | 55 | + /** @gems: Device-wide list of GEM objects owned by at least one file. */ |
55 | + struct list_head gems; | 56 | + struct { |
57 | + /** @gems.lock: Protects the device-wide list of GEM objects. */ | ||
58 | + struct mutex lock; | ||
59 | + | ||
60 | + /** @node: Used to keep track of all the device's DRM objects */ | ||
61 | + struct list_head node; | ||
62 | + } gems; | ||
56 | +#endif | 63 | +#endif |
57 | }; | 64 | }; |
58 | 65 | ||
59 | struct panthor_gpu_usage { | 66 | struct panthor_gpu_usage { |
60 | diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c | 67 | diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c |
... | ... | ||
69 | +{ | 76 | +{ |
70 | + struct drm_info_node *node = m->private; | 77 | + struct drm_info_node *node = m->private; |
71 | + struct drm_device *dev = node->minor->dev; | 78 | + struct drm_device *dev = node->minor->dev; |
72 | + struct panthor_device *ptdev = container_of(dev, struct panthor_device, base); | 79 | + struct panthor_device *ptdev = container_of(dev, struct panthor_device, base); |
73 | + | 80 | + |
74 | + panthor_gem_print_objects(ptdev, m); | 81 | + panthor_gem_debugfs_print_bos(ptdev, m); |
75 | + | 82 | + |
76 | + return 0; | 83 | + return 0; |
77 | +} | 84 | +} |
78 | + | 85 | + |
79 | + | 86 | + |
... | ... | ||
99 | 106 | ||
100 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c | 107 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c |
101 | index XXXXXXX..XXXXXXX 100644 | 108 | index XXXXXXX..XXXXXXX 100644 |
102 | --- a/drivers/gpu/drm/panthor/panthor_gem.c | 109 | --- a/drivers/gpu/drm/panthor/panthor_gem.c |
103 | +++ b/drivers/gpu/drm/panthor/panthor_gem.c | 110 | +++ b/drivers/gpu/drm/panthor/panthor_gem.c |
104 | @@ -XXX,XX +XXX,XX @@ static void panthor_gem_free_object(struct drm_gem_object *obj) | 111 | @@ -XXX,XX +XXX,XX @@ |
112 | /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */ | ||
113 | /* Copyright 2023 Collabora ltd. */ | ||
114 | |||
115 | +#include <linux/cleanup.h> | ||
116 | #include <linux/dma-buf.h> | ||
117 | #include <linux/dma-mapping.h> | ||
118 | #include <linux/err.h> | ||
119 | @@ -XXX,XX +XXX,XX @@ | ||
120 | #include <drm/panthor_drm.h> | ||
121 | |||
122 | #include "panthor_device.h" | ||
123 | +#include "panthor_fw.h" | ||
124 | #include "panthor_gem.h" | ||
125 | #include "panthor_mmu.h" | ||
126 | |||
127 | +#ifdef CONFIG_DEBUG_FS | ||
128 | +static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo, u32 type_mask) | ||
129 | +{ | ||
130 | + INIT_LIST_HEAD(&bo->debugfs.node); | ||
131 | + | ||
132 | + if (!(type_mask & PANTHOR_BO_FW_MAPPED)) { | ||
133 | + bo->debugfs.creator.tgid = current->group_leader->pid; | ||
134 | + get_task_comm(bo->debugfs.creator.process_name, current->group_leader); | ||
135 | + } else { | ||
136 | + bo->debugfs.creator.tgid = 0; | ||
137 | + snprintf(bo->debugfs.creator.process_name, | ||
138 | + sizeof(bo->debugfs.creator.process_name), | ||
139 | + "kernel"); | ||
140 | + } | ||
141 | + | ||
142 | + bo->debugfs.bo_mask = type_mask; | ||
143 | +} | ||
144 | + | ||
145 | +static void panthor_gem_debugfs_bo_add(struct panthor_gem_object *bo, u32 type_mask) | ||
146 | +{ | ||
147 | + struct panthor_device *ptdev = container_of(bo->base.base.dev, | ||
148 | + struct panthor_device, base); | ||
149 | + | ||
150 | + panthor_gem_debugfs_bo_init(bo, type_mask); | ||
151 | + | ||
152 | + mutex_lock(&ptdev->gems.lock); | ||
153 | + list_add_tail(&bo->debugfs.node, &ptdev->gems.node); | ||
154 | + mutex_unlock(&ptdev->gems.lock); | ||
155 | +} | ||
156 | + | ||
157 | +static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) | ||
158 | +{ | ||
159 | + struct panthor_device *ptdev = container_of(bo->base.base.dev, | ||
160 | + struct panthor_device, base); | ||
161 | + | ||
162 | + if (list_empty(&bo->debugfs.node)) | ||
163 | + return; | ||
164 | + | ||
165 | + mutex_lock(&ptdev->gems.lock); | ||
166 | + list_del_init(&bo->debugfs.node); | ||
167 | + mutex_unlock(&ptdev->gems.lock); | ||
168 | +} | ||
169 | + | ||
170 | +#else | ||
171 | +static void panthor_gem_debugfs_bo_add(struct panthor_gem_object *bo, u32 type_mask) {} | ||
172 | +static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) {} | ||
173 | +#endif | ||
174 | + | ||
175 | static void panthor_gem_free_object(struct drm_gem_object *obj) | ||
105 | { | 176 | { |
106 | struct panthor_gem_object *bo = to_panthor_bo(obj); | 177 | struct panthor_gem_object *bo = to_panthor_bo(obj); |
107 | struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem; | 178 | struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem; |
108 | +#ifdef CONFIG_DEBUG_FS | 179 | |
109 | + struct drm_device *dev = bo->base.base.dev; | 180 | + panthor_gem_debugfs_bo_rm(bo); |
110 | + struct panthor_device *ptdev = container_of(dev, struct panthor_device, base); | 181 | + |
111 | + | 182 | /* |
112 | + if (!list_empty(&bo->gems_node)) { | 183 | * Label might have been allocated with kstrdup_const(), |
113 | + mutex_lock(&ptdev->gems_lock); | 184 | * we need to take that into account when freeing the memory |
114 | + list_del_init(&bo->gems_node); | 185 | @@ -XXX,XX +XXX,XX @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, |
115 | + mutex_unlock(&ptdev->gems_lock); | 186 | struct drm_gem_shmem_object *obj; |
116 | + } | 187 | struct panthor_kernel_bo *kbo; |
117 | +#endif | 188 | struct panthor_gem_object *bo; |
118 | 189 | + u32 type_mask = PANTHOR_BO_KERNEL; | |
119 | kfree(bo->label); | ||
120 | mutex_destroy(&bo->label_lock); | ||
121 | @@ -XXX,XX +XXX,XX @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t | ||
122 | drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock); | ||
123 | mutex_init(&obj->label_lock); | ||
124 | |||
125 | +#ifdef CONFIG_DEBUG_FS | ||
126 | + INIT_LIST_HEAD(&obj->gems_node); | ||
127 | + obj->creator.tgid = current->group_leader->pid; | ||
128 | + get_task_comm(obj->creator.process_name, current->group_leader); | ||
129 | +#endif | ||
130 | + | ||
131 | return &obj->base.base; | ||
132 | } | ||
133 | |||
134 | @@ -XXX,XX +XXX,XX @@ panthor_gem_create_with_handle(struct drm_file *file, | ||
135 | int ret; | 190 | int ret; |
136 | struct drm_gem_shmem_object *shmem; | 191 | |
137 | struct panthor_gem_object *bo; | 192 | if (drm_WARN_ON(&ptdev->base, !vm)) |
138 | +#ifdef CONFIG_DEBUG_FS | 193 | @@ -XXX,XX +XXX,XX @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, |
139 | + struct panthor_device *ptdev = | 194 | kbo->obj = &obj->base; |
140 | + container_of(ddev, struct panthor_device, base); | 195 | bo->flags = bo_flags; |
141 | +#endif | 196 | |
142 | 197 | + if (vm == panthor_fw_vm(ptdev)) | |
143 | shmem = drm_gem_shmem_create(ddev, *size); | 198 | + type_mask |= PANTHOR_BO_FW_MAPPED; |
144 | if (IS_ERR(shmem)) | 199 | + |
200 | panthor_gem_kernel_bo_set_label(kbo, name); | ||
201 | + panthor_gem_debugfs_bo_add(to_panthor_bo(kbo->obj), type_mask); | ||
202 | + | ||
203 | /* The system and GPU MMU page size might differ, which becomes a | ||
204 | * problem for FW sections that need to be mapped at explicit address | ||
205 | * since our PAGE_SIZE alignment might cover a VA range that's | ||
145 | @@ -XXX,XX +XXX,XX @@ panthor_gem_create_with_handle(struct drm_file *file, | 206 | @@ -XXX,XX +XXX,XX @@ panthor_gem_create_with_handle(struct drm_file *file, |
146 | /* drop reference from allocate - handle holds it now. */ | 207 | /* drop reference from allocate - handle holds it now. */ |
147 | drm_gem_object_put(&shmem->base); | 208 | drm_gem_object_put(&shmem->base); |
148 | 209 | ||
149 | +#ifdef CONFIG_DEBUG_FS | 210 | + panthor_gem_debugfs_bo_add(bo, 0); |
150 | + mutex_lock(&ptdev->gems_lock); | ||
151 | + list_add_tail(&bo->gems_node, &ptdev->gems); | ||
152 | + mutex_unlock(&ptdev->gems_lock); | ||
153 | +#endif | ||
154 | + | 211 | + |
155 | return ret; | 212 | return ret; |
156 | } | 213 | } |
157 | 214 | ||
158 | @@ -XXX,XX +XXX,XX @@ panthor_gem_label_bo(struct drm_gem_object *obj, const char *label) | 215 | @@ -XXX,XX +XXX,XX @@ panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label) |
159 | 216 | ||
160 | kfree(old_label); | 217 | panthor_gem_bo_set_label(bo->obj, kstrdup_const(str, GFP_KERNEL)); |
161 | } | 218 | } |
162 | + | 219 | + |
163 | +#ifdef CONFIG_DEBUG_FS | 220 | +#ifdef CONFIG_DEBUG_FS |
164 | +static bool panfrost_gem_print_flag(const char *name, | 221 | +static bool panfrost_gem_print_flag(const char *name, |
165 | + bool is_set, | 222 | + bool is_set, |
... | ... | ||
170 | + seq_printf(m, "%s%s", other_flags_printed ? "," : "", name); | 227 | + seq_printf(m, "%s%s", other_flags_printed ? "," : "", name); |
171 | + | 228 | + |
172 | + return is_set | other_flags_printed; | 229 | + return is_set | other_flags_printed; |
173 | +} | 230 | +} |
174 | + | 231 | + |
175 | +void panthor_gem_print_objects(struct panthor_device *ptdev, | 232 | +struct gem_size_totals { |
176 | + struct seq_file *m) | 233 | + size_t size; |
177 | +{ | 234 | + size_t resident; |
178 | + size_t total = 0, total_resident = 0, total_reclaimable = 0; | 235 | + size_t reclaimable; |
236 | +}; | ||
237 | + | ||
238 | +static void panthor_gem_debugfs_bo_print(struct panthor_gem_object *bo, | ||
239 | + struct seq_file *m, | ||
240 | + struct gem_size_totals *totals) | ||
241 | +{ | ||
242 | + unsigned int refcount = kref_read(&bo->base.base.refcount); | ||
243 | + char creator_info[32] = {}; | ||
244 | + bool has_flags = false; | ||
245 | + size_t resident_size; | ||
246 | + | ||
247 | + /* Skip BOs being destroyed. */ | ||
248 | + if (!refcount) | ||
249 | + return; | ||
250 | + | ||
251 | + resident_size = bo->base.pages != NULL ? bo->base.base.size : 0; | ||
252 | + | ||
253 | + snprintf(creator_info, sizeof(creator_info), | ||
254 | + "%s/%d", bo->debugfs.creator.process_name, bo->debugfs.creator.tgid); | ||
255 | + seq_printf(m, "%-32s%-16d%-16d%-16zd%-16zd%-16lx", | ||
256 | + creator_info, | ||
257 | + bo->base.base.name, | ||
258 | + refcount, | ||
259 | + bo->base.base.size, | ||
260 | + resident_size, | ||
261 | + drm_vma_node_start(&bo->base.base.vma_node)); | ||
262 | + | ||
263 | + seq_puts(m, "("); | ||
264 | + has_flags = panfrost_gem_print_flag("imported", bo->base.base.import_attach != NULL, | ||
265 | + has_flags, m); | ||
266 | + has_flags = panfrost_gem_print_flag("exported", bo->base.base.dma_buf != NULL, | ||
267 | + has_flags, m); | ||
268 | + if (bo->base.madv < 0) | ||
269 | + has_flags = panfrost_gem_print_flag("purged", true, has_flags, m); | ||
270 | + else if (bo->base.madv > 0) | ||
271 | + has_flags = panfrost_gem_print_flag("purgeable", true, has_flags, m); | ||
272 | + if (!has_flags) | ||
273 | + seq_puts(m, "none"); | ||
274 | + seq_puts(m, ")"); | ||
275 | + | ||
276 | + seq_printf(m, "%-6s0x%-2x", "", bo->debugfs.bo_mask); | ||
277 | + | ||
278 | + mutex_lock(&bo->label.lock); | ||
279 | + seq_printf(m, "%-6s%-60s", "", bo->label.str ? : NULL); | ||
280 | + mutex_unlock(&bo->label.lock); | ||
281 | + seq_puts(m, "\n"); | ||
282 | + | ||
283 | + totals->size += bo->base.base.size; | ||
284 | + totals->resident += resident_size; | ||
285 | + if (bo->base.madv > 0) | ||
286 | + totals->reclaimable += resident_size; | ||
287 | +} | ||
288 | + | ||
289 | +void panthor_gem_debugfs_print_bos(struct panthor_device *ptdev, | ||
290 | + struct seq_file *m) | ||
291 | +{ | ||
292 | + struct gem_size_totals totals = {0}; | ||
179 | + struct panthor_gem_object *bo; | 293 | + struct panthor_gem_object *bo; |
180 | + | 294 | + |
181 | + seq_puts(m, "created-by global-name refcount size resident-size file-offset flags label\n"); | 295 | + seq_puts(m, "created-by global-name refcount size resident-size file-offset flags kflags label\n"); |
182 | + seq_puts(m, "------------------------------------------------------------------------------------------------------------------------------------------------\n"); | 296 | + seq_puts(m, "------------------------------------------------------------------------------------------------------------------------------------------------\n"); |
183 | + | 297 | + |
184 | + mutex_lock(&ptdev->gems_lock); | 298 | + scoped_guard(mutex, &ptdev->gems.lock) { |
185 | + list_for_each_entry(bo, &ptdev->gems, gems_node) { | 299 | + list_for_each_entry(bo, &ptdev->gems.node, debugfs.node) |
186 | + unsigned int refcount = kref_read(&bo->base.base.refcount); | 300 | + panthor_gem_debugfs_bo_print(bo, m, &totals); |
187 | + char creator_info[32] = {}; | ||
188 | + bool has_flags = false; | ||
189 | + size_t resident_size; | ||
190 | + | ||
191 | + /* Skip BOs being destroyed. */ | ||
192 | + if (!refcount) | ||
193 | + continue; | ||
194 | + | ||
195 | + resident_size = bo->base.pages != NULL ? bo->base.base.size : 0; | ||
196 | + | ||
197 | + snprintf(creator_info, sizeof(creator_info), | ||
198 | + "%s/%d", bo->creator.process_name, bo->creator.tgid); | ||
199 | + seq_printf(m, "%-32s%-16d%-16d%-16zd%-16zd%-16lx", | ||
200 | + creator_info, | ||
201 | + bo->base.base.name, | ||
202 | + refcount, | ||
203 | + bo->base.base.size, | ||
204 | + resident_size, | ||
205 | + drm_vma_node_start(&bo->base.base.vma_node)); | ||
206 | + | ||
207 | + seq_puts(m, "("); | ||
208 | + has_flags = panfrost_gem_print_flag("imported", bo->base.base.import_attach != NULL, | ||
209 | + has_flags, m); | ||
210 | + has_flags = panfrost_gem_print_flag("exported", bo->base.base.dma_buf != NULL, | ||
211 | + has_flags, m); | ||
212 | + if (bo->base.madv < 0) | ||
213 | + has_flags = panfrost_gem_print_flag("purged", true, has_flags, m); | ||
214 | + else if (bo->base.madv > 0) | ||
215 | + has_flags = panfrost_gem_print_flag("purgeable", true, has_flags, m); | ||
216 | + if (!has_flags) | ||
217 | + seq_puts(m, "none"); | ||
218 | + seq_puts(m, ")"); | ||
219 | + | ||
220 | + mutex_lock(&bo->label_lock); | ||
221 | + seq_printf(m, "%-16s%-60s", "", bo->label ? : NULL); | ||
222 | + mutex_unlock(&bo->label_lock); | ||
223 | + seq_puts(m, "\n"); | ||
224 | + | ||
225 | + total += bo->base.base.size; | ||
226 | + total_resident += resident_size; | ||
227 | + if (bo->base.madv > 0) | ||
228 | + total_reclaimable += resident_size; | ||
229 | + } | 301 | + } |
230 | + mutex_unlock(&ptdev->gems_lock); | 302 | + |
231 | + | 303 | + seq_puts(m, "==========================================================================================================================================================\n"); |
232 | + seq_puts(m, "================================================================================================================================================\n"); | ||
233 | + seq_printf(m, "Total size: %zd, Total resident: %zd, Total reclaimable: %zd\n", | 304 | + seq_printf(m, "Total size: %zd, Total resident: %zd, Total reclaimable: %zd\n", |
234 | + total, total_resident, total_reclaimable); | 305 | + totals.size, totals.resident, totals.reclaimable); |
235 | +} | 306 | +} |
236 | +#endif | 307 | +#endif |
237 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h | 308 | diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h |
238 | index XXXXXXX..XXXXXXX 100644 | 309 | index XXXXXXX..XXXXXXX 100644 |
239 | --- a/drivers/gpu/drm/panthor/panthor_gem.h | 310 | --- a/drivers/gpu/drm/panthor/panthor_gem.h |
240 | +++ b/drivers/gpu/drm/panthor/panthor_gem.h | 311 | +++ b/drivers/gpu/drm/panthor/panthor_gem.h |
241 | @@ -XXX,XX +XXX,XX @@ struct panthor_gem_object { | 312 | @@ -XXX,XX +XXX,XX @@ struct panthor_vm; |
242 | 313 | ||
243 | /** @label_lock: Lock that protects access to the @label field. */ | 314 | #define PANTHOR_BO_LABEL_MAXLEN PAGE_SIZE |
244 | struct mutex label_lock; | 315 | |
245 | + | 316 | +#define PANTHOR_BO_KERNEL BIT(0) |
246 | +#ifdef CONFIG_DEBUG_FS | 317 | +#define PANTHOR_BO_FW_MAPPED BIT(1) |
318 | + | ||
319 | +/** | ||
320 | + * struct panthor_gem_debugfs - GEM object's DebugFS list information | ||
321 | + */ | ||
322 | +struct panthor_gem_debugfs { | ||
247 | + /** | 323 | + /** |
248 | + * @gems_node: Node used to insert the object in the device-wide list of | 324 | + * @node: Node used to insert the object in the device-wide list of |
249 | + * GEM objects, to display information about it through a DebugFS file. | 325 | + * GEM objects, to display information about it through a DebugFS file. |
250 | + */ | 326 | + */ |
251 | + struct list_head gems_node; | 327 | + struct list_head node; |
252 | + | 328 | + |
253 | + /** @creator: Information about the UM process which created the GEM. */ | 329 | + /** @creator: Information about the UM process which created the GEM. */ |
254 | + struct { | 330 | + struct { |
255 | + /** @process_name: Group leader name in owning thread's process */ | 331 | + /** @creator.process_name: Group leader name in owning thread's process */ |
256 | + char process_name[TASK_COMM_LEN]; | 332 | + char process_name[TASK_COMM_LEN]; |
257 | + | 333 | + |
258 | + /** @tgid: PID of the thread's group leader within its process */ | 334 | + /** @creator.tgid: PID of the thread's group leader within its process */ |
259 | + pid_t tgid; | 335 | + pid_t tgid; |
260 | + } creator; | 336 | + } creator; |
337 | + | ||
338 | + /** @bo_mask: Bitmask encoding BO type as {USER, KERNEL} x {GPU, FW} */ | ||
339 | + u32 bo_mask; | ||
340 | +}; | ||
341 | + | ||
342 | /** | ||
343 | * struct panthor_gem_object - Driver specific GEM object. | ||
344 | */ | ||
345 | @@ -XXX,XX +XXX,XX @@ struct panthor_gem_object { | ||
346 | /** @lock.str: Protects access to the @label.str field. */ | ||
347 | struct mutex lock; | ||
348 | } label; | ||
349 | + | ||
350 | +#ifdef CONFIG_DEBUG_FS | ||
351 | + struct panthor_gem_debugfs debugfs; | ||
261 | +#endif | 352 | +#endif |
262 | }; | 353 | }; |
263 | 354 | ||
264 | /** | 355 | /** |
265 | @@ -XXX,XX +XXX,XX @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, | 356 | @@ -XXX,XX +XXX,XX @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, |
266 | 357 | ||
267 | void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo); | 358 | void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo); |
268 | 359 | ||
269 | +#ifdef CONFIG_DEBUG_FS | 360 | +#ifdef CONFIG_DEBUG_FS |
270 | +void panthor_gem_print_objects(struct panthor_device *pfdev, | 361 | +void panthor_gem_debugfs_print_bos(struct panthor_device *pfdev, |
271 | + struct seq_file *m); | 362 | + struct seq_file *m); |
272 | +#endif | 363 | +#endif |
273 | + | 364 | + |
274 | #endif /* __PANTHOR_GEM_H__ */ | 365 | #endif /* __PANTHOR_GEM_H__ */ |
275 | -- | 366 | -- |
276 | 2.48.1 | 367 | 2.48.1 |
277 | 368 | diff view generated by jsdifflib |