mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-11-27 01:11:31 +00:00
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: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com> Signed-off-by: Kent Russell <kent.russell@amd.com> Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
This commit is contained in:
parent
8e05247d4c
commit
4f449311e9
4 changed files with 132 additions and 79 deletions
|
|
@ -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,
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
|
|
||||||
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 @@
|
||||||
#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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 @@ err:
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
* 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)
|
||||||
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 {
|
||||||
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 {
|
||||||
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__ */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue