Public
> -----Original Message-----
> From: McRae, Geoffrey <[email protected]>
> Sent: Thursday, July 9, 2026 12:53 AM
> To: Deucher, Alexander <[email protected]>
> Cc: Koenig, Christian <[email protected]>; amd-
> [email protected]; McRae, Geoffrey <[email protected]>
> Subject: [PATCH v2] drm/amdgpu: fix sysfs duplicate errors and incomplete
> unwind in ip_init
>
> When amdgpu_device_ip_init() fails partway through, IP blocks that had
> completed sw_init() were never unwound, leaving sysfs files registered.
> On the next device init attempt this produced duplicate filename errors:
>
> sysfs: cannot create duplicate filename '.../enforce_isolation'
> sysfs: cannot create duplicate filename '.../sdma_reset_mask'
> sysfs: cannot create duplicate filename '.../vcn_reset_mask'
> sysfs: cannot create duplicate filename '.../jpeg_reset_mask'
> sysfs: cannot create duplicate filename '.../vpe_reset_mask'
> sysfs: cannot create duplicate filename '.../current_memory_partition'
> sysfs: cannot create duplicate filename '.../available_memory_partition'
>
> Fix the init_failed unwind path in amdgpu_device_ip_init() to properly reverse
> all initialisation performed by the function:
>
> - Call sw_fini() in reverse order for all IP blocks where status.sw is
> true, mirroring amdgpu_device_ip_fini().
>
> - For the GMC block, free the resources allocated during its early
> hw_init phase in the correct reverse order: seq64, static CSA,
> writeback buffer, and mem scratch page.
>
> - Free resources initialised after the IP block loop: ucode BO, IB
> pool, KFD device, TTM buffer funcs, and the SRIOV vf2pf data
> exchange work item.
>
> Additionally, fix amdgpu_gfx_sysfs_init() to properly unwind partially
> registered gfx sysfs files on registration failure, and drop the
> now-unnecessary
> kobj.sd liveness guard from amdgpu_gfx_sysfs_fini() since
> device_remove_file() is safe to call during sysfs teardown.
>
> Signed-off-by: Geoffrey McRae <[email protected]>
> Cc: Alex Deucher <[email protected]>
> Cc: Christian König <[email protected]>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 21
> ++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 23 +++++++++++++++-----
> --
> 2 files changed, 37 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 70d07ca187a3..9630ad5f3048 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -2491,6 +2491,27 @@ static int amdgpu_device_ip_init(struct
> amdgpu_device *adev)
> r = amdgpu_cper_init(adev);
>
> init_failed:
> + if (r) {
> + amdgpu_amdkfd_device_fini_sw(adev);
> + amdgpu_ttm_disable_buffer_funcs(adev);
> + if (amdgpu_sriov_vf(adev))
> + amdgpu_virt_fini_data_exchange(adev);
> + amdgpu_ucode_free_bo(adev);
> + amdgpu_ib_pool_fini(adev);
> + for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
> + if (!adev->ip_blocks[i].status.sw)
> + continue;
> + if (adev->ip_blocks[i].version->type ==
> AMD_IP_BLOCK_TYPE_GMC) {
> + amdgpu_seq64_fini(adev);
> + amdgpu_free_static_csa(&adev-
> >virt.csa_obj);
> + amdgpu_device_wb_fini(adev);
> + amdgpu_device_mem_scratch_fini(adev);
> + }
> + if (adev->ip_blocks[i].version->funcs->sw_fini)
> + adev->ip_blocks[i].version->funcs-
> >sw_fini(&adev->ip_blocks[i]);
> + adev->ip_blocks[i].status.sw = false;
> + }
Also need to unwind all of the other stuff in that function (hw_init(), ucode
bo allocation, etc.). Might be easier to call amdgpu_device_ip_fini() instead
to cover all of the unwinding properly.
Alex
> + }
>
> return r;
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> index 982b41606d48..0ab4c73c102a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
> @@ -2182,23 +2182,32 @@ int amdgpu_gfx_sysfs_init(struct
> amdgpu_device *adev)
> }
>
> r = amdgpu_gfx_sysfs_isolation_shader_init(adev);
> - if (r)
> + if (r) {
> dev_err(adev->dev, "failed to create isolation sysfs files");
> + goto err_isolation_shader;
> + }
>
> r = amdgpu_gfx_sysfs_reset_mask_init(adev);
> - if (r)
> + if (r) {
> dev_err(adev->dev, "failed to create reset mask sysfs files");
> + goto err_reset_mask;
> + }
> +
> + return 0;
>
> +err_reset_mask:
> + amdgpu_gfx_sysfs_reset_mask_fini(adev);
> + amdgpu_gfx_sysfs_isolation_shader_fini(adev);
> +err_isolation_shader:
> + amdgpu_gfx_sysfs_xcp_fini(adev);
> return r;
> }
>
> void amdgpu_gfx_sysfs_fini(struct amdgpu_device *adev) {
> - if (adev->dev->kobj.sd) {
> - amdgpu_gfx_sysfs_xcp_fini(adev);
> - amdgpu_gfx_sysfs_isolation_shader_fini(adev);
> - amdgpu_gfx_sysfs_reset_mask_fini(adev);
> - }
> + amdgpu_gfx_sysfs_xcp_fini(adev);
> + amdgpu_gfx_sysfs_isolation_shader_fini(adev);
> + amdgpu_gfx_sysfs_reset_mask_fini(adev);
> }
>
> static void amdgpu_gfx_reset_start_compute_scheds(struct amdgpu_device
> *adev,
> --
> 2.43.0