Commit f701acb6 authored by Felix Kuehling's avatar Felix Kuehling Committed by Alex Deucher

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: default avatarDan Carpenter <error27@gmail.com>
Signed-off-by: default avatarFelix Kuehling <felix.kuehling@gmail.com>
Signed-off-by: default avatarMa Jun <Jun.Ma2@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 88733d68
...@@ -1805,34 +1805,14 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct ...@@ -1805,34 +1805,14 @@ 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); pr_debug("Added [%d] GPU cache entries\n", num_of_entries);
} }
int kfd_topology_add_device(struct kfd_dev *gpu) static int kfd_topology_add_device_locked(struct kfd_dev *gpu, uint32_t gpu_id,
struct kfd_topology_device **dev)
{ {
uint32_t gpu_id; int proximity_domain = ++topology_crat_proximity_domain;
struct kfd_topology_device *dev;
struct kfd_cu_info cu_info;
int res = 0;
struct list_head temp_topology_device_list; struct list_head temp_topology_device_list;
void *crat_image = NULL; void *crat_image = NULL;
size_t image_size = 0; size_t image_size = 0;
int proximity_domain; int res;
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);
/* Check to see if this gpu device exists in the topology_device_list.
* If so, assign the gpu to that device,
* else create a Virtual CRAT for this gpu device and then parse that
* CRAT to create a new topology device. Once created assign the gpu to
* that topology device
*/
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, res = kfd_create_crat_image_virtual(&crat_image, &image_size,
COMPUTE_UNIT_GPU, gpu, COMPUTE_UNIT_GPU, gpu,
...@@ -1841,9 +1821,11 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -1841,9 +1821,11 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n", pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n",
gpu_id); gpu_id);
topology_crat_proximity_domain--; topology_crat_proximity_domain--;
return res; goto err;
} }
INIT_LIST_HEAD(&temp_topology_device_list);
res = kfd_parse_crat_table(crat_image, res = kfd_parse_crat_table(crat_image,
&temp_topology_device_list, &temp_topology_device_list,
proximity_domain); proximity_domain);
...@@ -1857,8 +1839,8 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -1857,8 +1839,8 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
kfd_topology_update_device_list(&temp_topology_device_list, kfd_topology_update_device_list(&temp_topology_device_list,
&topology_device_list); &topology_device_list);
dev = kfd_assign_gpu(gpu); *dev = kfd_assign_gpu(gpu);
if (WARN_ON(!dev)) { if (WARN_ON(!*dev)) {
res = -ENODEV; res = -ENODEV;
goto err; goto err;
} }
...@@ -1866,7 +1848,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -1866,7 +1848,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
/* Fill the cache affinity information here for the GPUs /* Fill the cache affinity information here for the GPUs
* using VCRAT * using VCRAT
*/ */
kfd_fill_cache_non_crat_info(dev, gpu); kfd_fill_cache_non_crat_info(*dev, gpu);
/* Update the SYSFS tree, since we added another topology /* Update the SYSFS tree, since we added another topology
* device * device
...@@ -1877,8 +1859,37 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -1877,8 +1859,37 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
else else
pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n", pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n",
gpu_id, res); 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;
int i;
const char *asic_name = amdgpu_asic_name[gpu->adev->asic_type];
gpu_id = kfd_generate_gpu_id(gpu);
pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
/* Check to see if this gpu device exists in the topology_device_list.
* If so, assign the gpu to that device,
* else create a Virtual CRAT for this gpu device and then parse that
* CRAT to create a new topology device. Once created assign the gpu to
* that topology device
*/
down_write(&topology_lock);
dev = kfd_assign_gpu(gpu);
if (!dev)
res = kfd_topology_add_device_locked(gpu, gpu_id, &dev);
up_write(&topology_lock); up_write(&topology_lock);
if (res)
return res;
dev->gpu_id = gpu_id; dev->gpu_id = gpu_id;
gpu->id = gpu_id; gpu->id = gpu_id;
...@@ -2003,8 +2014,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -2003,8 +2014,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
if (!res) if (!res)
kfd_notify_gpu_change(gpu_id, 1); kfd_notify_gpu_change(gpu_id, 1);
err:
kfd_destroy_crat_image(crat_image);
return res; return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment