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; + } + } 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
