| From 22d8ef1ee196aa0c1f2edbf95fe34deff6895909 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 30 Mar 2026 14:51:45 -0300 |
| Subject: drm/vc4: Fix a memory leak in hang state error path |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Maíra Canal <mcanal@igalia.com> |
| |
| [ Upstream commit 9525d169e5fd481538cf8c663cc5839e54f2e481 ] |
| |
| When vc4_save_hang_state() encounters an early return condition, it |
| returns without freeing the previously allocated `kernel_state`, |
| leaking memory. |
| |
| Add the missing kfree() calls by consolidating the early return paths |
| into a single place. |
| |
| Fixes: 214613656b51 ("drm/vc4: Add an interface for capturing the GPU state after a hang.") |
| Reviewed-by: Melissa Wen <mwen@igalia.com> |
| Link: https://patch.msgid.link/20260330-vc4-misc-fixes-v1-3-92defc940a29@igalia.com |
| Signed-off-by: Maíra Canal <mcanal@igalia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/vc4/vc4_gem.c | 18 ++++++++++-------- |
| 1 file changed, 10 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c |
| index c446684a72183..0d88226b17deb 100644 |
| --- a/drivers/gpu/drm/vc4/vc4_gem.c |
| +++ b/drivers/gpu/drm/vc4/vc4_gem.c |
| @@ -169,10 +169,8 @@ vc4_save_hang_state(struct drm_device *dev) |
| spin_lock_irqsave(&vc4->job_lock, irqflags); |
| exec[0] = vc4_first_bin_job(vc4); |
| exec[1] = vc4_first_render_job(vc4); |
| - if (!exec[0] && !exec[1]) { |
| - spin_unlock_irqrestore(&vc4->job_lock, irqflags); |
| - return; |
| - } |
| + if (!exec[0] && !exec[1]) |
| + goto err_free_state; |
| |
| /* Get the bos from both binner and renderer into hang state. */ |
| state->bo_count = 0; |
| @@ -189,10 +187,8 @@ vc4_save_hang_state(struct drm_device *dev) |
| kernel_state->bo = kcalloc(state->bo_count, |
| sizeof(*kernel_state->bo), GFP_ATOMIC); |
| |
| - if (!kernel_state->bo) { |
| - spin_unlock_irqrestore(&vc4->job_lock, irqflags); |
| - return; |
| - } |
| + if (!kernel_state->bo) |
| + goto err_free_state; |
| |
| k = 0; |
| for (i = 0; i < 2; i++) { |
| @@ -284,6 +280,12 @@ vc4_save_hang_state(struct drm_device *dev) |
| vc4->hang_state = kernel_state; |
| spin_unlock_irqrestore(&vc4->job_lock, irqflags); |
| } |
| + |
| + return; |
| + |
| +err_free_state: |
| + spin_unlock_irqrestore(&vc4->job_lock, irqflags); |
| + kfree(kernel_state); |
| } |
| |
| static void |
| -- |
| 2.53.0 |
| |