jpeg_v4_0_5_sw_init() returns directly when
amdgpu_jpeg_reg_dump_init() or amdgpu_jpeg_sysfs_reset_mask_init()
fails, after all JPEG rings have been initialized successfully.
amdgpu_ring_init() allocated the ring buffers, writeback slots and the
vmid fences, and only amdgpu_ring_fini(), called through
amdgpu_jpeg_sw_fini(), releases them. Because the IP block's status.sw is
only set after sw_init() succeeds, the upper layers skip sw_fini() for
this block and the resources are leaked.
Unwind with amdgpu_jpeg_sw_fini(), as the other JPEG implementations do.
Fixes: 2b0ccf3923b5 ("drm/amdgpu: Enable devcoredump for JPEG4_0_5")
Cc: [email protected]
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
index 4da3f9c995c1..fb9bbe93fbe0 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
@@ -173,7 +173,7 @@ static int jpeg_v4_0_5_sw_init(struct amdgpu_ip_block
*ip_block)
r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0_5,
ARRAY_SIZE(jpeg_reg_list_4_0_5));
if (r)
- return r;
+ goto err_jpeg;
adev->jpeg.supported_reset =
amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
@@ -181,9 +181,14 @@ static int jpeg_v4_0_5_sw_init(struct amdgpu_ip_block
*ip_block)
adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
if (r)
- return r;
+ goto err_jpeg;
return 0;
+
+err_jpeg:
+ amdgpu_jpeg_suspend(adev);
+ amdgpu_jpeg_sw_fini(adev);
+ return r;
}
/**
--
2.34.1