summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaíra Canal <mcanal@igalia.com>2024-10-04 15:36:00 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-10-17 16:22:26 +0300
commit75452da51e2403e14be007df80d133e1443fc967 (patch)
treeeb122188794d209bcbcda7a565c54e8352095289
parent0c9e9a3a4873705740b19300cadc6599170646ef (diff)
downloadlinux-75452da51e2403e14be007df80d133e1443fc967.tar.xz
drm/vc4: Stop the active perfmon before being destroyed
commit 0b2ad4f6f2bec74a5287d96cb2325a5e11706f22 upstream. Upon closing the file descriptor, the active performance monitor is not stopped. Although all perfmons are destroyed in `vc4_perfmon_close_file()`, the active performance monitor's pointer (`vc4->active_perfmon`) is still retained. If we open a new file descriptor and submit a few jobs with performance monitors, the driver will attempt to stop the active performance monitor using the stale pointer in `vc4->active_perfmon`. However, this pointer is no longer valid because the previous process has already terminated, and all performance monitors associated with it have been destroyed and freed. To fix this, when the active performance monitor belongs to a given process, explicitly stop it before destroying and freeing it. Cc: stable@vger.kernel.org # v4.17+ Cc: Boris Brezillon <bbrezillon@kernel.org> Cc: Juan A. Suarez Romero <jasuarez@igalia.com> Fixes: 65101d8c9108 ("drm/vc4: Expose performance counters to userspace") Signed-off-by: Maíra Canal <mcanal@igalia.com> Reviewed-by: Juan A. Suarez <jasuarez@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241004123817.890016-2-mcanal@igalia.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/vc4/vc4_perfmon.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c
index c4ac2c946238..c00a5cc2316d 100644
--- a/drivers/gpu/drm/vc4/vc4_perfmon.c
+++ b/drivers/gpu/drm/vc4/vc4_perfmon.c
@@ -116,6 +116,11 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file)
static int vc4_perfmon_idr_del(int id, void *elem, void *data)
{
struct vc4_perfmon *perfmon = elem;
+ struct vc4_dev *vc4 = (struct vc4_dev *)data;
+
+ /* If the active perfmon is being destroyed, stop it first */
+ if (perfmon == vc4->active_perfmon)
+ vc4_perfmon_stop(vc4, perfmon, false);
vc4_perfmon_put(perfmon);
@@ -130,7 +135,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file)
return;
mutex_lock(&vc4file->perfmon.lock);
- idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL);
+ idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, vc4);
idr_destroy(&vc4file->perfmon.idr);
mutex_unlock(&vc4file->perfmon.lock);
mutex_destroy(&vc4file->perfmon.lock);