The JPEG 2.0, 3.0 and 4.0 software initialization callbacks create their
rings before allocating register dump storage and creating the reset
mask sysfs file. If either of the latter steps fails, the callbacks
return without releasing the initialized JPEG resources, including the
ring buffers and vmid_wait fence reference. The IP block's status.sw flag
has not been set, so the common error cleanup skips its sw_fini callback.

Suspend the JPEG work and release the JPEG software resources on these
late failures. amdgpu_jpeg_sw_fini() also releases the register dump
storage if it was successfully allocated before sysfs creation failed.

Fixes: 63d5f8db5313 ("drm/amdgpu: Enable devcoredump for JPEG2_0_0")
Fixes: d949e91b42f2 ("drm/amdgpu: Enable devcoredump for JPEG3_0_0")
Fixes: c3dddd602967 ("drm/amdgpu: Enable devcoredump for JPEG4_0_0")
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_v2_0.c | 9 ++++++++-
 drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c | 9 ++++++++-
 drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c | 9 ++++++++-
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c 
b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
index 72069b77f6f1..0707e065160a 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
@@ -115,14 +115,21 @@ static int jpeg_v2_0_sw_init(struct amdgpu_ip_block 
*ip_block)
 
        r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_2_0, 
ARRAY_SIZE(jpeg_reg_list_2_0));
        if (r)
-               return r;
+               goto err_jpeg;
 
        adev->jpeg.supported_reset =
                amdgpu_get_soft_full_reset_mask(adev->jpeg.inst[0].ring_dec);
        if (!amdgpu_sriov_vf(adev))
                adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
        r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
+       if (r)
+               goto err_jpeg;
+
+       return 0;
 
+err_jpeg:
+       amdgpu_jpeg_suspend(adev);
+       amdgpu_jpeg_sw_fini(adev);
        return r;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c 
b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
index 564e40899df2..f88200bcb2b2 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
@@ -130,14 +130,21 @@ static int jpeg_v3_0_sw_init(struct amdgpu_ip_block 
*ip_block)
 
        r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_3_0, 
ARRAY_SIZE(jpeg_reg_list_3_0));
        if (r)
-               return r;
+               goto err_jpeg;
 
        adev->jpeg.supported_reset =
                amdgpu_get_soft_full_reset_mask(adev->jpeg.inst[0].ring_dec);
        if (!amdgpu_sriov_vf(adev))
                adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
        r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
+       if (r)
+               goto err_jpeg;
+
+       return 0;
 
+err_jpeg:
+       amdgpu_jpeg_suspend(adev);
+       amdgpu_jpeg_sw_fini(adev);
        return r;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c 
b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
index b29ca3a49939..454f16f24d7b 100644
--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
@@ -141,14 +141,21 @@ static int jpeg_v4_0_sw_init(struct amdgpu_ip_block 
*ip_block)
 
        r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0, 
ARRAY_SIZE(jpeg_reg_list_4_0));
        if (r)
-               return r;
+               goto err_jpeg;
 
        adev->jpeg.supported_reset =
                amdgpu_get_soft_full_reset_mask(adev->jpeg.inst[0].ring_dec);
        if (!amdgpu_sriov_vf(adev))
                adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
        r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
+       if (r)
+               goto err_jpeg;
+
+       return 0;
 
+err_jpeg:
+       amdgpu_jpeg_suspend(adev);
+       amdgpu_jpeg_sw_fini(adev);
        return r;
 }
 
-- 
2.34.1

Reply via email to