Skip to content

Commit f701acb

Browse files
fxkuehlalexdeucher
authored andcommitted
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 <[email protected]> Signed-off-by: Felix Kuehling <[email protected]> Signed-off-by: Ma Jun <[email protected]> Reviewed-by: Felix Kuehling <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 88733d6 commit f701acb

File tree

1 file changed

+65
-55
lines changed

1 file changed

+65
-55
lines changed

drivers/gpu/drm/amd/amdkfd/kfd_topology.c

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,21 +1805,75 @@ static void kfd_fill_cache_non_crat_info(struct kfd_topology_device *dev, struct
18051805
pr_debug("Added [%d] GPU cache entries\n", num_of_entries);
18061806
}
18071807

1808+
static int kfd_topology_add_device_locked(struct kfd_dev *gpu, uint32_t gpu_id,
1809+
struct kfd_topology_device **dev)
1810+
{
1811+
int proximity_domain = ++topology_crat_proximity_domain;
1812+
struct list_head temp_topology_device_list;
1813+
void *crat_image = NULL;
1814+
size_t image_size = 0;
1815+
int res;
1816+
1817+
res = kfd_create_crat_image_virtual(&crat_image, &image_size,
1818+
COMPUTE_UNIT_GPU, gpu,
1819+
proximity_domain);
1820+
if (res) {
1821+
pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n",
1822+
gpu_id);
1823+
topology_crat_proximity_domain--;
1824+
goto err;
1825+
}
1826+
1827+
INIT_LIST_HEAD(&temp_topology_device_list);
1828+
1829+
res = kfd_parse_crat_table(crat_image,
1830+
&temp_topology_device_list,
1831+
proximity_domain);
1832+
if (res) {
1833+
pr_err("Error parsing VCRAT for GPU (ID: 0x%x)\n",
1834+
gpu_id);
1835+
topology_crat_proximity_domain--;
1836+
goto err;
1837+
}
1838+
1839+
kfd_topology_update_device_list(&temp_topology_device_list,
1840+
&topology_device_list);
1841+
1842+
*dev = kfd_assign_gpu(gpu);
1843+
if (WARN_ON(!*dev)) {
1844+
res = -ENODEV;
1845+
goto err;
1846+
}
1847+
1848+
/* Fill the cache affinity information here for the GPUs
1849+
* using VCRAT
1850+
*/
1851+
kfd_fill_cache_non_crat_info(*dev, gpu);
1852+
1853+
/* Update the SYSFS tree, since we added another topology
1854+
* device
1855+
*/
1856+
res = kfd_topology_update_sysfs();
1857+
if (!res)
1858+
sys_props.generation_count++;
1859+
else
1860+
pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n",
1861+
gpu_id, res);
1862+
1863+
err:
1864+
kfd_destroy_crat_image(crat_image);
1865+
return res;
1866+
}
1867+
18081868
int kfd_topology_add_device(struct kfd_dev *gpu)
18091869
{
18101870
uint32_t gpu_id;
18111871
struct kfd_topology_device *dev;
18121872
struct kfd_cu_info cu_info;
18131873
int res = 0;
1814-
struct list_head temp_topology_device_list;
1815-
void *crat_image = NULL;
1816-
size_t image_size = 0;
1817-
int proximity_domain;
18181874
int i;
18191875
const char *asic_name = amdgpu_asic_name[gpu->adev->asic_type];
18201876

1821-
INIT_LIST_HEAD(&temp_topology_device_list);
1822-
18231877
gpu_id = kfd_generate_gpu_id(gpu);
18241878
pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
18251879

@@ -1831,54 +1885,11 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
18311885
*/
18321886
down_write(&topology_lock);
18331887
dev = kfd_assign_gpu(gpu);
1834-
if (!dev) {
1835-
proximity_domain = ++topology_crat_proximity_domain;
1836-
1837-
res = kfd_create_crat_image_virtual(&crat_image, &image_size,
1838-
COMPUTE_UNIT_GPU, gpu,
1839-
proximity_domain);
1840-
if (res) {
1841-
pr_err("Error creating VCRAT for GPU (ID: 0x%x)\n",
1842-
gpu_id);
1843-
topology_crat_proximity_domain--;
1844-
return res;
1845-
}
1846-
1847-
res = kfd_parse_crat_table(crat_image,
1848-
&temp_topology_device_list,
1849-
proximity_domain);
1850-
if (res) {
1851-
pr_err("Error parsing VCRAT for GPU (ID: 0x%x)\n",
1852-
gpu_id);
1853-
topology_crat_proximity_domain--;
1854-
goto err;
1855-
}
1856-
1857-
kfd_topology_update_device_list(&temp_topology_device_list,
1858-
&topology_device_list);
1859-
1860-
dev = kfd_assign_gpu(gpu);
1861-
if (WARN_ON(!dev)) {
1862-
res = -ENODEV;
1863-
goto err;
1864-
}
1865-
1866-
/* Fill the cache affinity information here for the GPUs
1867-
* using VCRAT
1868-
*/
1869-
kfd_fill_cache_non_crat_info(dev, gpu);
1870-
1871-
/* Update the SYSFS tree, since we added another topology
1872-
* device
1873-
*/
1874-
res = kfd_topology_update_sysfs();
1875-
if (!res)
1876-
sys_props.generation_count++;
1877-
else
1878-
pr_err("Failed to update GPU (ID: 0x%x) to sysfs topology. res=%d\n",
1879-
gpu_id, res);
1880-
}
1888+
if (!dev)
1889+
res = kfd_topology_add_device_locked(gpu, gpu_id, &dev);
18811890
up_write(&topology_lock);
1891+
if (res)
1892+
return res;
18821893

18831894
dev->gpu_id = gpu_id;
18841895
gpu->id = gpu_id;
@@ -2003,8 +2014,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
20032014

20042015
if (!res)
20052016
kfd_notify_gpu_change(gpu_id, 1);
2006-
err:
2007-
kfd_destroy_crat_image(crat_image);
2017+
20082018
return res;
20092019
}
20102020

0 commit comments

Comments
 (0)