diff options
author | Felix Kuehling <felix.kuehling@gmail.com> | 2022-11-16 15:38:44 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2022-11-23 10:31:31 -0500 |
commit | f701acb6a4ed0acc0ba85a7ee18b12a75c0c58f0 (patch) | |
tree | 22bb1f5ce1f9b824ad2328fb5aff1fda91422419 | |
parent | 88733d68014f06d4aae8ef0673ee31602ef1f0a7 (diff) | |
download | linux-f701acb6a4ed0acc0ba85a7ee18b12a75c0c58f0.tar.bz2 |
drm/amdkfd: Release the topology_lock in error case
Move the topology-locked part of kfd_topology_add_device into a separate
function to simlpify error handling and release the topology lock
consistently.
Reported-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Felix Kuehling <felix.kuehling@gmail.com>
Signed-off-by: Ma Jun <Jun.Ma2@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 120 |
1 files changed, 65 insertions, 55 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index ef9c6fdfb88d..6f01ebc8557b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1805,21 +1805,75 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct pr_debug("Added [%d] GPU cache entries\n", num_of_entries); } +static int kfd_topology_add_device_locked(struct kfd_dev *gpu, uint32_t gpu_id, + struct kfd_topology_device **dev) +{ + int proximity_domain = ++topology_crat_proximity_domain; + struct list_head temp_topology_device_list; + void *crat_image = NULL; + size_t image_size = 0; + int res; + + res = kfd_create_crat_image_virtual(&crat_image, &image_size, + COMPUTE_UNIT_GPU, gpu, + proximity_domain); + if (res) { + pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n", + gpu_id); + topology_crat_proximity_domain--; + goto err; + } + + INIT_LIST_HEAD(&temp_topology_device_list); + + res = kfd_parse_crat_table(crat_image, + &temp_topology_device_list, + proximity_domain); + if (res) { + pr_err("Error parsing VCRAT for GPU (ID: 0x%x)\n", + gpu_id); + topology_crat_proximity_domain--; + goto err; + } + + kfd_topology_update_device_list(&temp_topology_device_list, + &topology_device_list); + + *dev = kfd_assign_gpu(gpu); + if (WARN_ON(!*dev)) { + res = -ENODEV; + goto err; + } + + /* Fill the cache affinity information here for the GPUs + * using VCRAT + */ + kfd_fill_cache_non_crat_info(*dev, gpu); + + /* Update the SYSFS tree, since we added another topology + * device + */ + res = kfd_topology_update_sysfs(); + if (!res) + sys_props.generation_count++; + else + pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n", + gpu_id, res); + +err: + kfd_destroy_crat_image(crat_image); + return res; +} + int kfd_topology_add_device(struct kfd_dev *gpu) { uint32_t gpu_id; struct kfd_topology_device *dev; struct kfd_cu_info cu_info; int res = 0; - struct list_head temp_topology_device_list; - void *crat_image = NULL; - size_t image_size = 0; - int proximity_domain; int i; const char *asic_name = amdgpu_asic_name[gpu->adev->asic_type]; - INIT_LIST_HEAD(&temp_topology_device_list); - gpu_id = kfd_generate_gpu_id(gpu); pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id); @@ -1831,54 +1885,11 @@ int kfd_topology_add_device(struct kfd_dev *gpu) */ down_write(&topology_lock); dev = kfd_assign_gpu(gpu); - if (!dev) { - proximity_domain = ++topology_crat_proximity_domain; - - res = kfd_create_crat_image_virtual(&crat_image, &image_size, - COMPUTE_UNIT_GPU, gpu, - proximity_domain); - if (res) { - pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n", - gpu_id); - topology_crat_proximity_domain--; - return res; - } - - res = kfd_parse_crat_table(crat_image, - &temp_topology_device_list, - proximity_domain); - if (res) { - pr_err("Error parsing VCRAT for GPU (ID: 0x%x)\n", - gpu_id); - topology_crat_proximity_domain--; - goto err; - } - - kfd_topology_update_device_list(&temp_topology_device_list, - &topology_device_list); - - dev = kfd_assign_gpu(gpu); - if (WARN_ON(!dev)) { - res = -ENODEV; - goto err; - } - - /* Fill the cache affinity information here for the GPUs - * using VCRAT - */ - kfd_fill_cache_non_crat_info(dev, gpu); - - /* Update the SYSFS tree, since we added another topology - * device - */ - res = kfd_topology_update_sysfs(); - if (!res) - sys_props.generation_count++; - else - pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n", - gpu_id, res); - } + if (!dev) + res = kfd_topology_add_device_locked(gpu, gpu_id, &dev); up_write(&topology_lock); + if (res) + return res; dev->gpu_id = gpu_id; gpu->id = gpu_id; @@ -2003,8 +2014,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) if (!res) kfd_notify_gpu_change(gpu_id, 1); -err: - kfd_destroy_crat_image(crat_image); + return res; } |