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

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
Loading
Loading
Loading
Loading
+65 −55
Original line number Diff line number Diff line
@@ -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);
}

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;
	struct kfd_topology_device *dev;
	struct kfd_cu_info cu_info;
	int res = 0;
	int proximity_domain = ++topology_crat_proximity_domain;
	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);

	/* 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;
	int res;

	res = kfd_create_crat_image_virtual(&crat_image, &image_size,
					    COMPUTE_UNIT_GPU, 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",
		       gpu_id);
		topology_crat_proximity_domain--;
			return res;
		goto err;
	}

	INIT_LIST_HEAD(&temp_topology_device_list);

	res = kfd_parse_crat_table(crat_image,
				   &temp_topology_device_list,
				   proximity_domain);
@@ -1857,8 +1839,8 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
	kfd_topology_update_device_list(&temp_topology_device_list,
					&topology_device_list);

		dev = kfd_assign_gpu(gpu);
		if (WARN_ON(!dev)) {
	*dev = kfd_assign_gpu(gpu);
	if (WARN_ON(!*dev)) {
		res = -ENODEV;
		goto err;
	}
@@ -1866,7 +1848,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
	/* Fill the cache affinity information here for the GPUs
	 * 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
	 * device
@@ -1877,8 +1859,37 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
	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;
	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);
	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;
}