Commit 4f449311 authored by Harish Kasiviswanathan's avatar Harish Kasiviswanathan Committed by Oded Gabbay

drm/amdkfd: Decouple CRAT parsing from device list update

Currently, CRAT parsing is intertwined with topology_device_list and
hence repeated calls to kfd_parse_crat_table() will fail. Decouple
kfd_parse_crat_table() and topology_device_list.

kfd_parse_crat_table() will parse CRAT and add topology devices to a
temporary list temp_topology_device_list and then
kfd_topology_update_device_list will move contents from temporary list to
master list.
Signed-off-by: default avatarHarish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Signed-off-by: default avatarKent Russell <kent.russell@amd.com>
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent 8e05247d
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include "kfd_crat.h" #include "kfd_crat.h"
#include "kfd_topology.h" #include "kfd_topology.h"
static int topology_crat_parsed;
extern struct list_head topology_device_list;
extern struct kfd_system_properties sys_props; extern struct kfd_system_properties sys_props;
static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
...@@ -57,16 +55,18 @@ static void kfd_populated_cu_info_gpu(struct kfd_topology_device *dev, ...@@ -57,16 +55,18 @@ static void kfd_populated_cu_info_gpu(struct kfd_topology_device *dev,
pr_info("CU GPU: id_base=%d\n", cu->processor_id_low); pr_info("CU GPU: id_base=%d\n", cu->processor_id_low);
} }
/* kfd_parse_subtype_cu is called when the topology mutex is already acquired */ /* kfd_parse_subtype_cu - parse compute unit subtypes and attach it to correct
static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu) * topology device present in the device_list
*/
static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu,
struct list_head *device_list)
{ {
struct kfd_topology_device *dev; struct kfd_topology_device *dev;
int i = 0;
pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n", pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n",
cu->proximity_domain, cu->hsa_capability); cu->proximity_domain, cu->hsa_capability);
list_for_each_entry(dev, &topology_device_list, list) { list_for_each_entry(dev, device_list, list) {
if (cu->proximity_domain == i) { if (cu->proximity_domain == dev->proximity_domain) {
if (cu->flags & CRAT_CU_FLAGS_CPU_PRESENT) if (cu->flags & CRAT_CU_FLAGS_CPU_PRESENT)
kfd_populated_cu_info_cpu(dev, cu); kfd_populated_cu_info_cpu(dev, cu);
...@@ -74,26 +74,24 @@ static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu) ...@@ -74,26 +74,24 @@ static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu)
kfd_populated_cu_info_gpu(dev, cu); kfd_populated_cu_info_gpu(dev, cu);
break; break;
} }
i++;
} }
return 0; return 0;
} }
/* /* kfd_parse_subtype_mem - parse memory subtypes and attach it to correct
* kfd_parse_subtype_mem is called when the topology mutex is * topology device present in the device_list
* already acquired
*/ */
static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem) static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem,
struct list_head *device_list)
{ {
struct kfd_mem_properties *props; struct kfd_mem_properties *props;
struct kfd_topology_device *dev; struct kfd_topology_device *dev;
int i = 0;
pr_info("Found memory entry in CRAT table with proximity_domain=%d\n", pr_info("Found memory entry in CRAT table with proximity_domain=%d\n",
mem->proximity_domain); mem->proximity_domain);
list_for_each_entry(dev, &topology_device_list, list) { list_for_each_entry(dev, device_list, list) {
if (mem->proximity_domain == i) { if (mem->proximity_domain == dev->proximity_domain) {
props = kfd_alloc_struct(props); props = kfd_alloc_struct(props);
if (!props) if (!props)
return -ENOMEM; return -ENOMEM;
...@@ -118,17 +116,16 @@ static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem) ...@@ -118,17 +116,16 @@ static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem)
break; break;
} }
i++;
} }
return 0; return 0;
} }
/* /* kfd_parse_subtype_cache - parse cache subtypes and attach it to correct
* kfd_parse_subtype_cache is called when the topology mutex * topology device present in the device_list
* is already acquired
*/ */
static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache) static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache,
struct list_head *device_list)
{ {
struct kfd_cache_properties *props; struct kfd_cache_properties *props;
struct kfd_topology_device *dev; struct kfd_topology_device *dev;
...@@ -137,7 +134,7 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache) ...@@ -137,7 +134,7 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache)
id = cache->processor_id_low; id = cache->processor_id_low;
pr_info("Found cache entry in CRAT table with processor_id=%d\n", id); pr_info("Found cache entry in CRAT table with processor_id=%d\n", id);
list_for_each_entry(dev, &topology_device_list, list) list_for_each_entry(dev, device_list, list)
if (id == dev->node_props.cpu_core_id_base || if (id == dev->node_props.cpu_core_id_base ||
id == dev->node_props.simd_id_base) { id == dev->node_props.simd_id_base) {
props = kfd_alloc_struct(props); props = kfd_alloc_struct(props);
...@@ -171,15 +168,14 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache) ...@@ -171,15 +168,14 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache)
return 0; return 0;
} }
/* /* kfd_parse_subtype_iolink - parse iolink subtypes and attach it to correct
* kfd_parse_subtype_iolink is called when the topology mutex * topology device present in the device_list
* is already acquired
*/ */
static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink) static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink,
struct list_head *device_list)
{ {
struct kfd_iolink_properties *props; struct kfd_iolink_properties *props;
struct kfd_topology_device *dev; struct kfd_topology_device *dev;
uint32_t i = 0;
uint32_t id_from; uint32_t id_from;
uint32_t id_to; uint32_t id_to;
...@@ -187,8 +183,8 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink) ...@@ -187,8 +183,8 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink)
id_to = iolink->proximity_domain_to; id_to = iolink->proximity_domain_to;
pr_info("Found IO link entry in CRAT table with id_from=%d\n", id_from); pr_info("Found IO link entry in CRAT table with id_from=%d\n", id_from);
list_for_each_entry(dev, &topology_device_list, list) { list_for_each_entry(dev, device_list, list) {
if (id_from == i) { if (id_from == dev->proximity_domain) {
props = kfd_alloc_struct(props); props = kfd_alloc_struct(props);
if (!props) if (!props)
return -ENOMEM; return -ENOMEM;
...@@ -216,13 +212,18 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink) ...@@ -216,13 +212,18 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink)
break; break;
} }
i++;
} }
return 0; return 0;
} }
static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr) /* kfd_parse_subtype - parse subtypes and attach it to correct topology device
* present in the device_list
* @sub_type_hdr - subtype section of crat_image
* @device_list - list of topology devices present in this crat_image
*/
static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr,
struct list_head *device_list)
{ {
struct crat_subtype_computeunit *cu; struct crat_subtype_computeunit *cu;
struct crat_subtype_memory *mem; struct crat_subtype_memory *mem;
...@@ -233,15 +234,15 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr) ...@@ -233,15 +234,15 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
switch (sub_type_hdr->type) { switch (sub_type_hdr->type) {
case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY: case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY:
cu = (struct crat_subtype_computeunit *)sub_type_hdr; cu = (struct crat_subtype_computeunit *)sub_type_hdr;
ret = kfd_parse_subtype_cu(cu); ret = kfd_parse_subtype_cu(cu, device_list);
break; break;
case CRAT_SUBTYPE_MEMORY_AFFINITY: case CRAT_SUBTYPE_MEMORY_AFFINITY:
mem = (struct crat_subtype_memory *)sub_type_hdr; mem = (struct crat_subtype_memory *)sub_type_hdr;
ret = kfd_parse_subtype_mem(mem); ret = kfd_parse_subtype_mem(mem, device_list);
break; break;
case CRAT_SUBTYPE_CACHE_AFFINITY: case CRAT_SUBTYPE_CACHE_AFFINITY:
cache = (struct crat_subtype_cache *)sub_type_hdr; cache = (struct crat_subtype_cache *)sub_type_hdr;
ret = kfd_parse_subtype_cache(cache); ret = kfd_parse_subtype_cache(cache, device_list);
break; break;
case CRAT_SUBTYPE_TLB_AFFINITY: case CRAT_SUBTYPE_TLB_AFFINITY:
/* /*
...@@ -257,7 +258,7 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr) ...@@ -257,7 +258,7 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
break; break;
case CRAT_SUBTYPE_IOLINK_AFFINITY: case CRAT_SUBTYPE_IOLINK_AFFINITY:
iolink = (struct crat_subtype_iolink *)sub_type_hdr; iolink = (struct crat_subtype_iolink *)sub_type_hdr;
ret = kfd_parse_subtype_iolink(iolink); ret = kfd_parse_subtype_iolink(iolink, device_list);
break; break;
default: default:
pr_warn("Unknown subtype %d in CRAT\n", pr_warn("Unknown subtype %d in CRAT\n",
...@@ -267,12 +268,23 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr) ...@@ -267,12 +268,23 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
return ret; return ret;
} }
int kfd_parse_crat_table(void *crat_image) /* kfd_parse_crat_table - parse CRAT table. For each node present in CRAT
* create a kfd_topology_device and add in to device_list. Also parse
* CRAT subtypes and attach it to appropriate kfd_topology_device
* @crat_image - input image containing CRAT
* @device_list - [OUT] list of kfd_topology_device generated after
* parsing crat_image
* @proximity_domain - Proximity domain of the first device in the table
*
* Return - 0 if successful else -ve value
*/
int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
uint32_t proximity_domain)
{ {
struct kfd_topology_device *top_dev; struct kfd_topology_device *top_dev;
struct crat_subtype_generic *sub_type_hdr; struct crat_subtype_generic *sub_type_hdr;
uint16_t node_id; uint16_t node_id;
int ret; int ret = 0;
struct crat_header *crat_table = (struct crat_header *)crat_image; struct crat_header *crat_table = (struct crat_header *)crat_image;
uint16_t num_nodes; uint16_t num_nodes;
uint32_t image_len; uint32_t image_len;
...@@ -280,17 +292,26 @@ int kfd_parse_crat_table(void *crat_image) ...@@ -280,17 +292,26 @@ int kfd_parse_crat_table(void *crat_image)
if (!crat_image) if (!crat_image)
return -EINVAL; return -EINVAL;
if (!list_empty(device_list)) {
pr_warn("Error device list should be empty\n");
return -EINVAL;
}
num_nodes = crat_table->num_domains; num_nodes = crat_table->num_domains;
image_len = crat_table->length; image_len = crat_table->length;
pr_info("Parsing CRAT table with %d nodes\n", num_nodes); pr_info("Parsing CRAT table with %d nodes\n", num_nodes);
for (node_id = 0; node_id < num_nodes; node_id++) { for (node_id = 0; node_id < num_nodes; node_id++) {
top_dev = kfd_create_topology_device(); top_dev = kfd_create_topology_device(device_list);
if (!top_dev) { if (!top_dev)
kfd_release_live_view(); break;
return -ENOMEM; top_dev->proximity_domain = proximity_domain++;
} }
if (!top_dev) {
ret = -ENOMEM;
goto err;
} }
sys_props.platform_id = sys_props.platform_id =
...@@ -302,21 +323,20 @@ int kfd_parse_crat_table(void *crat_image) ...@@ -302,21 +323,20 @@ int kfd_parse_crat_table(void *crat_image)
while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) < while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) <
((char *)crat_image) + image_len) { ((char *)crat_image) + image_len) {
if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) { if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) {
ret = kfd_parse_subtype(sub_type_hdr); ret = kfd_parse_subtype(sub_type_hdr, device_list);
if (ret != 0) { if (ret)
kfd_release_live_view(); break;
return ret;
}
} }
sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr +
sub_type_hdr->length); sub_type_hdr->length);
} }
sys_props.generation_count++; err:
topology_crat_parsed = 1; if (ret)
kfd_release_topology_device_list(device_list);
return 0; return ret;
} }
/* /*
......
...@@ -293,6 +293,7 @@ struct cdit_header { ...@@ -293,6 +293,7 @@ struct cdit_header {
int kfd_create_crat_image_acpi(void **crat_image, size_t *size); int kfd_create_crat_image_acpi(void **crat_image, size_t *size);
void kfd_destroy_crat_image(void *crat_image); void kfd_destroy_crat_image(void *crat_image);
int kfd_parse_crat_table(void *crat_image); int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
uint32_t proximity_domain);
#endif /* KFD_CRAT_H_INCLUDED */ #endif /* KFD_CRAT_H_INCLUDED */
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
#include "kfd_topology.h" #include "kfd_topology.h"
#include "kfd_device_queue_manager.h" #include "kfd_device_queue_manager.h"
struct list_head topology_device_list; /* topology_device_list - Master list of all topology devices */
static struct list_head topology_device_list;
struct kfd_system_properties sys_props; struct kfd_system_properties sys_props;
static DECLARE_RWSEM(topology_lock); static DECLARE_RWSEM(topology_lock);
...@@ -105,24 +106,27 @@ static void kfd_release_topology_device(struct kfd_topology_device *dev) ...@@ -105,24 +106,27 @@ static void kfd_release_topology_device(struct kfd_topology_device *dev)
} }
kfree(dev); kfree(dev);
sys_props.num_devices--;
} }
void kfd_release_live_view(void) void kfd_release_topology_device_list(struct list_head *device_list)
{ {
struct kfd_topology_device *dev; struct kfd_topology_device *dev;
while (topology_device_list.next != &topology_device_list) { while (!list_empty(device_list)) {
dev = container_of(topology_device_list.next, dev = list_first_entry(device_list,
struct kfd_topology_device, list); struct kfd_topology_device, list);
kfd_release_topology_device(dev); kfd_release_topology_device(dev);
}
} }
static void kfd_release_live_view(void)
{
kfd_release_topology_device_list(&topology_device_list);
memset(&sys_props, 0, sizeof(sys_props)); memset(&sys_props, 0, sizeof(sys_props));
} }
struct kfd_topology_device *kfd_create_topology_device(void) struct kfd_topology_device *kfd_create_topology_device(
struct list_head *device_list)
{ {
struct kfd_topology_device *dev; struct kfd_topology_device *dev;
...@@ -136,8 +140,7 @@ struct kfd_topology_device *kfd_create_topology_device(void) ...@@ -136,8 +140,7 @@ struct kfd_topology_device *kfd_create_topology_device(void)
INIT_LIST_HEAD(&dev->cache_props); INIT_LIST_HEAD(&dev->cache_props);
INIT_LIST_HEAD(&dev->io_link_props); INIT_LIST_HEAD(&dev->io_link_props);
list_add_tail(&dev->list, &topology_device_list); list_add_tail(&dev->list, device_list);
sys_props.num_devices++;
return dev; return dev;
} }
...@@ -682,16 +685,32 @@ static void kfd_topology_release_sysfs(void) ...@@ -682,16 +685,32 @@ static void kfd_topology_release_sysfs(void)
} }
} }
/* Called with write topology_lock acquired */
static void kfd_topology_update_device_list(struct list_head *temp_list,
struct list_head *master_list)
{
while (!list_empty(temp_list)) {
list_move_tail(temp_list->next, master_list);
sys_props.num_devices++;
}
}
int kfd_topology_init(void) int kfd_topology_init(void)
{ {
void *crat_image = NULL; void *crat_image = NULL;
size_t image_size = 0; size_t image_size = 0;
int ret; int ret;
struct list_head temp_topology_device_list;
/* /* topology_device_list - Master list of all topology devices
* Initialize the head for the topology device list * temp_topology_device_list - temporary list created while parsing CRAT
* or VCRAT. Once parsing is complete the contents of list is moved to
* topology_device_list
*/ */
/* Initialize the head for the both the lists */
INIT_LIST_HEAD(&topology_device_list); INIT_LIST_HEAD(&topology_device_list);
INIT_LIST_HEAD(&temp_topology_device_list);
init_rwsem(&topology_lock); init_rwsem(&topology_lock);
memset(&sys_props, 0, sizeof(sys_props)); memset(&sys_props, 0, sizeof(sys_props));
...@@ -701,7 +720,8 @@ int kfd_topology_init(void) ...@@ -701,7 +720,8 @@ int kfd_topology_init(void)
*/ */
ret = kfd_create_crat_image_acpi(&crat_image, &image_size); ret = kfd_create_crat_image_acpi(&crat_image, &image_size);
if (!ret) { if (!ret) {
ret = kfd_parse_crat_table(crat_image); ret = kfd_parse_crat_table(crat_image,
&temp_topology_device_list, 0);
if (ret) if (ret)
goto err; goto err;
} else if (ret == -ENODATA) { } else if (ret == -ENODATA) {
...@@ -714,12 +734,15 @@ int kfd_topology_init(void) ...@@ -714,12 +734,15 @@ int kfd_topology_init(void)
} }
down_write(&topology_lock); down_write(&topology_lock);
kfd_topology_update_device_list(&temp_topology_device_list,
&topology_device_list);
ret = kfd_topology_update_sysfs(); ret = kfd_topology_update_sysfs();
up_write(&topology_lock); up_write(&topology_lock);
if (!ret) if (!ret) {
sys_props.generation_count++;
pr_info("Finished initializing topology\n"); pr_info("Finished initializing topology\n");
else } else
pr_err("Failed to update topology in sysfs ret=%d\n", ret); pr_err("Failed to update topology in sysfs ret=%d\n", ret);
err: err:
...@@ -729,8 +752,10 @@ int kfd_topology_init(void) ...@@ -729,8 +752,10 @@ int kfd_topology_init(void)
void kfd_topology_shutdown(void) void kfd_topology_shutdown(void)
{ {
down_write(&topology_lock);
kfd_topology_release_sysfs(); kfd_topology_release_sysfs();
kfd_release_live_view(); kfd_release_live_view();
up_write(&topology_lock);
} }
static void kfd_debug_print_topology(void) static void kfd_debug_print_topology(void)
...@@ -806,13 +831,15 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -806,13 +831,15 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
uint32_t gpu_id; uint32_t gpu_id;
struct kfd_topology_device *dev; struct kfd_topology_device *dev;
struct kfd_cu_info cu_info; struct kfd_cu_info cu_info;
int res; int res = 0;
struct list_head temp_topology_device_list;
INIT_LIST_HEAD(&temp_topology_device_list);
gpu_id = kfd_generate_gpu_id(gpu); gpu_id = kfd_generate_gpu_id(gpu);
pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id); pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
down_write(&topology_lock);
/* /*
* Try to assign the GPU to existing topology device (generated from * Try to assign the GPU to existing topology device (generated from
* CRAT table * CRAT table
...@@ -821,11 +848,12 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -821,11 +848,12 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
if (!dev) { if (!dev) {
pr_info("GPU was not found in the current topology. Extending.\n"); pr_info("GPU was not found in the current topology. Extending.\n");
kfd_debug_print_topology(); kfd_debug_print_topology();
dev = kfd_create_topology_device(); dev = kfd_create_topology_device(&temp_topology_device_list);
if (!dev) { if (!dev) {
res = -ENOMEM; res = -ENOMEM;
goto err; goto err;
} }
dev->gpu = gpu; dev->gpu = gpu;
/* /*
...@@ -833,12 +861,18 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -833,12 +861,18 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
* GPU vBIOS * GPU vBIOS
*/ */
down_write(&topology_lock);
kfd_topology_update_device_list(&temp_topology_device_list,
&topology_device_list);
/* Update the SYSFS tree, since we added another topology /* Update the SYSFS tree, since we added another topology
* device * device
*/ */
if (kfd_topology_update_sysfs() < 0) if (kfd_topology_update_sysfs() < 0)
kfd_topology_release_sysfs(); kfd_topology_release_sysfs();
up_write(&topology_lock);
} }
dev->gpu_id = gpu_id; dev->gpu_id = gpu_id;
...@@ -859,30 +893,26 @@ int kfd_topology_add_device(struct kfd_dev *gpu) ...@@ -859,30 +893,26 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
pr_info("Adding doorbell packet type capability\n"); pr_info("Adding doorbell packet type capability\n");
} }
res = 0; if (!res)
err:
up_write(&topology_lock);
if (res == 0)
kfd_notify_gpu_change(gpu_id, 1); kfd_notify_gpu_change(gpu_id, 1);
err:
return res; return res;
} }
int kfd_topology_remove_device(struct kfd_dev *gpu) int kfd_topology_remove_device(struct kfd_dev *gpu)
{ {
struct kfd_topology_device *dev; struct kfd_topology_device *dev, *tmp;
uint32_t gpu_id; uint32_t gpu_id;
int res = -ENODEV; int res = -ENODEV;
down_write(&topology_lock); down_write(&topology_lock);
list_for_each_entry(dev, &topology_device_list, list) list_for_each_entry_safe(dev, tmp, &topology_device_list, list)
if (dev->gpu == gpu) { if (dev->gpu == gpu) {
gpu_id = dev->gpu_id; gpu_id = dev->gpu_id;
kfd_remove_sysfs_node_entry(dev); kfd_remove_sysfs_node_entry(dev);
kfd_release_topology_device(dev); kfd_release_topology_device(dev);
sys_props.num_devices--;
res = 0; res = 0;
if (kfd_topology_update_sysfs() < 0) if (kfd_topology_update_sysfs() < 0)
kfd_topology_release_sysfs(); kfd_topology_release_sysfs();
......
...@@ -135,6 +135,7 @@ struct kfd_iolink_properties { ...@@ -135,6 +135,7 @@ struct kfd_iolink_properties {
struct kfd_topology_device { struct kfd_topology_device {
struct list_head list; struct list_head list;
uint32_t gpu_id; uint32_t gpu_id;
uint32_t proximity_domain;
struct kfd_node_properties node_props; struct kfd_node_properties node_props;
uint32_t mem_bank_count; uint32_t mem_bank_count;
struct list_head mem_props; struct list_head mem_props;
...@@ -164,7 +165,8 @@ struct kfd_system_properties { ...@@ -164,7 +165,8 @@ struct kfd_system_properties {
struct attribute attr_props; struct attribute attr_props;
}; };
struct kfd_topology_device *kfd_create_topology_device(void); struct kfd_topology_device *kfd_create_topology_device(
void kfd_release_live_view(void); struct list_head *device_list);
void kfd_release_topology_device_list(struct list_head *device_list);
#endif /* __KFD_TOPOLOGY_H__ */ #endif /* __KFD_TOPOLOGY_H__ */
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