aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHarish Kasiviswanathan <harish.kasiviswanathan@amd.com>2017-12-08 23:08:52 -0500
committerOded Gabbay <oded.gabbay@gmail.com>2017-12-08 23:08:52 -0500
commit4f449311e9aa177bd224e7b13cb0f6a55c524bcb (patch)
treefcacee39110db75947b4f5fc0917da8c4afa6944 /drivers
parent8e05247d4c23ff1c91682cf28d2ddb4210808e7d (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_crat.c118
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_crat.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c84
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.h6
4 files changed, 132 insertions, 79 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
index aa754c1ff682..bae91fdeba6d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
@@ -23,8 +23,6 @@
23#include "kfd_crat.h" 23#include "kfd_crat.h"
24#include "kfd_topology.h" 24#include "kfd_topology.h"
25 25
26static int topology_crat_parsed;
27extern struct list_head topology_device_list;
28extern struct kfd_system_properties sys_props; 26extern struct kfd_system_properties sys_props;
29 27
30static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, 28static 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 pr_info("CU GPU: id_base=%d\n", cu->processor_id_low); 55 pr_info("CU GPU: id_base=%d\n", cu->processor_id_low);
58} 56}
59 57
60/* kfd_parse_subtype_cu is called when the topology mutex is already acquired */ 58/* kfd_parse_subtype_cu - parse compute unit subtypes and attach it to correct
61static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu) 59 * topology device present in the device_list
60 */
61static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu,
62 struct list_head *device_list)
62{ 63{
63 struct kfd_topology_device *dev; 64 struct kfd_topology_device *dev;
64 int i = 0;
65 65
66 pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n", 66 pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n",
67 cu->proximity_domain, cu->hsa_capability); 67 cu->proximity_domain, cu->hsa_capability);
68 list_for_each_entry(dev, &topology_device_list, list) { 68 list_for_each_entry(dev, device_list, list) {
69 if (cu->proximity_domain == i) { 69 if (cu->proximity_domain == dev->proximity_domain) {
70 if (cu->flags & CRAT_CU_FLAGS_CPU_PRESENT) 70 if (cu->flags & CRAT_CU_FLAGS_CPU_PRESENT)
71 kfd_populated_cu_info_cpu(dev, cu); 71 kfd_populated_cu_info_cpu(dev, cu);
72 72
@@ -74,26 +74,24 @@ static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu)
74 kfd_populated_cu_info_gpu(dev, cu); 74 kfd_populated_cu_info_gpu(dev, cu);
75 break; 75 break;
76 } 76 }
77 i++;
78 } 77 }
79 78
80 return 0; 79 return 0;
81} 80}
82 81
83/* 82/* kfd_parse_subtype_mem - parse memory subtypes and attach it to correct
84 * kfd_parse_subtype_mem is called when the topology mutex is 83 * topology device present in the device_list
85 * already acquired
86 */ 84 */
87static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem) 85static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem,
86 struct list_head *device_list)
88{ 87{
89 struct kfd_mem_properties *props; 88 struct kfd_mem_properties *props;
90 struct kfd_topology_device *dev; 89 struct kfd_topology_device *dev;
91 int i = 0;
92 90
93 pr_info("Found memory entry in CRAT table with proximity_domain=%d\n", 91 pr_info("Found memory entry in CRAT table with proximity_domain=%d\n",
94 mem->proximity_domain); 92 mem->proximity_domain);
95 list_for_each_entry(dev, &topology_device_list, list) { 93 list_for_each_entry(dev, device_list, list) {
96 if (mem->proximity_domain == i) { 94 if (mem->proximity_domain == dev->proximity_domain) {
97 props = kfd_alloc_struct(props); 95 props = kfd_alloc_struct(props);
98 if (!props) 96 if (!props)
99 return -ENOMEM; 97 return -ENOMEM;
@@ -118,17 +116,16 @@ static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem)
118 116
119 break; 117 break;
120 } 118 }
121 i++;
122 } 119 }
123 120
124 return 0; 121 return 0;
125} 122}
126 123
127/* 124/* kfd_parse_subtype_cache - parse cache subtypes and attach it to correct
128 * kfd_parse_subtype_cache is called when the topology mutex 125 * topology device present in the device_list
129 * is already acquired
130 */ 126 */
131static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache) 127static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache,
128 struct list_head *device_list)
132{ 129{
133 struct kfd_cache_properties *props; 130 struct kfd_cache_properties *props;
134 struct kfd_topology_device *dev; 131 struct kfd_topology_device *dev;
@@ -137,7 +134,7 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache)
137 id = cache->processor_id_low; 134 id = cache->processor_id_low;
138 135
139 pr_info("Found cache entry in CRAT table with processor_id=%d\n", id); 136 pr_info("Found cache entry in CRAT table with processor_id=%d\n", id);
140 list_for_each_entry(dev, &topology_device_list, list) 137 list_for_each_entry(dev, device_list, list)
141 if (id == dev->node_props.cpu_core_id_base || 138 if (id == dev->node_props.cpu_core_id_base ||
142 id == dev->node_props.simd_id_base) { 139 id == dev->node_props.simd_id_base) {
143 props = kfd_alloc_struct(props); 140 props = kfd_alloc_struct(props);
@@ -171,15 +168,14 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache)
171 return 0; 168 return 0;
172} 169}
173 170
174/* 171/* kfd_parse_subtype_iolink - parse iolink subtypes and attach it to correct
175 * kfd_parse_subtype_iolink is called when the topology mutex 172 * topology device present in the device_list
176 * is already acquired
177 */ 173 */
178static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink) 174static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink,
175 struct list_head *device_list)
179{ 176{
180 struct kfd_iolink_properties *props; 177 struct kfd_iolink_properties *props;
181 struct kfd_topology_device *dev; 178 struct kfd_topology_device *dev;
182 uint32_t i = 0;
183 uint32_t id_from; 179 uint32_t id_from;
184 uint32_t id_to; 180 uint32_t id_to;
185 181
@@ -187,8 +183,8 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink)
187 id_to = iolink->proximity_domain_to; 183 id_to = iolink->proximity_domain_to;
188 184
189 pr_info("Found IO link entry in CRAT table with id_from=%d\n", id_from); 185 pr_info("Found IO link entry in CRAT table with id_from=%d\n", id_from);
190 list_for_each_entry(dev, &topology_device_list, list) { 186 list_for_each_entry(dev, device_list, list) {
191 if (id_from == i) { 187 if (id_from == dev->proximity_domain) {
192 props = kfd_alloc_struct(props); 188 props = kfd_alloc_struct(props);
193 if (!props) 189 if (!props)
194 return -ENOMEM; 190 return -ENOMEM;
@@ -216,13 +212,18 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink)
216 212
217 break; 213 break;
218 } 214 }
219 i++;
220 } 215 }
221 216
222 return 0; 217 return 0;
223} 218}
224 219
225static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr) 220/* kfd_parse_subtype - parse subtypes and attach it to correct topology device
221 * present in the device_list
222 * @sub_type_hdr - subtype section of crat_image
223 * @device_list - list of topology devices present in this crat_image
224 */
225static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr,
226 struct list_head *device_list)
226{ 227{
227 struct crat_subtype_computeunit *cu; 228 struct crat_subtype_computeunit *cu;
228 struct crat_subtype_memory *mem; 229 struct crat_subtype_memory *mem;
@@ -233,15 +234,15 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
233 switch (sub_type_hdr->type) { 234 switch (sub_type_hdr->type) {
234 case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY: 235 case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY:
235 cu = (struct crat_subtype_computeunit *)sub_type_hdr; 236 cu = (struct crat_subtype_computeunit *)sub_type_hdr;
236 ret = kfd_parse_subtype_cu(cu); 237 ret = kfd_parse_subtype_cu(cu, device_list);
237 break; 238 break;
238 case CRAT_SUBTYPE_MEMORY_AFFINITY: 239 case CRAT_SUBTYPE_MEMORY_AFFINITY:
239 mem = (struct crat_subtype_memory *)sub_type_hdr; 240 mem = (struct crat_subtype_memory *)sub_type_hdr;
240 ret = kfd_parse_subtype_mem(mem); 241 ret = kfd_parse_subtype_mem(mem, device_list);
241 break; 242 break;
242 case CRAT_SUBTYPE_CACHE_AFFINITY: 243 case CRAT_SUBTYPE_CACHE_AFFINITY:
243 cache = (struct crat_subtype_cache *)sub_type_hdr; 244 cache = (struct crat_subtype_cache *)sub_type_hdr;
244 ret = kfd_parse_subtype_cache(cache); 245 ret = kfd_parse_subtype_cache(cache, device_list);
245 break; 246 break;
246 case CRAT_SUBTYPE_TLB_AFFINITY: 247 case CRAT_SUBTYPE_TLB_AFFINITY:
247 /* 248 /*
@@ -257,7 +258,7 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
257 break; 258 break;
258 case CRAT_SUBTYPE_IOLINK_AFFINITY: 259 case CRAT_SUBTYPE_IOLINK_AFFINITY:
259 iolink = (struct crat_subtype_iolink *)sub_type_hdr; 260 iolink = (struct crat_subtype_iolink *)sub_type_hdr;
260 ret = kfd_parse_subtype_iolink(iolink); 261 ret = kfd_parse_subtype_iolink(iolink, device_list);
261 break; 262 break;
262 default: 263 default:
263 pr_warn("Unknown subtype %d in CRAT\n", 264 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 return ret; 268 return ret;
268} 269}
269 270
270int kfd_parse_crat_table(void *crat_image) 271/* kfd_parse_crat_table - parse CRAT table. For each node present in CRAT
272 * create a kfd_topology_device and add in to device_list. Also parse
273 * CRAT subtypes and attach it to appropriate kfd_topology_device
274 * @crat_image - input image containing CRAT
275 * @device_list - [OUT] list of kfd_topology_device generated after
276 * parsing crat_image
277 * @proximity_domain - Proximity domain of the first device in the table
278 *
279 * Return - 0 if successful else -ve value
280 */
281int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
282 uint32_t proximity_domain)
271{ 283{
272 struct kfd_topology_device *top_dev; 284 struct kfd_topology_device *top_dev;
273 struct crat_subtype_generic *sub_type_hdr; 285 struct crat_subtype_generic *sub_type_hdr;
274 uint16_t node_id; 286 uint16_t node_id;
275 int ret; 287 int ret = 0;
276 struct crat_header *crat_table = (struct crat_header *)crat_image; 288 struct crat_header *crat_table = (struct crat_header *)crat_image;
277 uint16_t num_nodes; 289 uint16_t num_nodes;
278 uint32_t image_len; 290 uint32_t image_len;
@@ -280,17 +292,26 @@ int kfd_parse_crat_table(void *crat_image)
280 if (!crat_image) 292 if (!crat_image)
281 return -EINVAL; 293 return -EINVAL;
282 294
295 if (!list_empty(device_list)) {
296 pr_warn("Error device list should be empty\n");
297 return -EINVAL;
298 }
299
283 num_nodes = crat_table->num_domains; 300 num_nodes = crat_table->num_domains;
284 image_len = crat_table->length; 301 image_len = crat_table->length;
285 302
286 pr_info("Parsing CRAT table with %d nodes\n", num_nodes); 303 pr_info("Parsing CRAT table with %d nodes\n", num_nodes);
287 304
288 for (node_id = 0; node_id < num_nodes; node_id++) { 305 for (node_id = 0; node_id < num_nodes; node_id++) {
289 top_dev = kfd_create_topology_device(); 306 top_dev = kfd_create_topology_device(device_list);
290 if (!top_dev) { 307 if (!top_dev)
291 kfd_release_live_view(); 308 break;
292 return -ENOMEM; 309 top_dev->proximity_domain = proximity_domain++;
293 } 310 }
311
312 if (!top_dev) {
313 ret = -ENOMEM;
314 goto err;
294 } 315 }
295 316
296 sys_props.platform_id = 317 sys_props.platform_id =
@@ -302,21 +323,20 @@ int kfd_parse_crat_table(void *crat_image)
302 while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) < 323 while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) <
303 ((char *)crat_image) + image_len) { 324 ((char *)crat_image) + image_len) {
304 if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) { 325 if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) {
305 ret = kfd_parse_subtype(sub_type_hdr); 326 ret = kfd_parse_subtype(sub_type_hdr, device_list);
306 if (ret != 0) { 327 if (ret)
307 kfd_release_live_view(); 328 break;
308 return ret;
309 }
310 } 329 }
311 330
312 sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + 331 sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr +
313 sub_type_hdr->length); 332 sub_type_hdr->length);
314 } 333 }
315 334
316 sys_props.generation_count++; 335err:
317 topology_crat_parsed = 1; 336 if (ret)
337 kfd_release_topology_device_list(device_list);
318 338
319 return 0; 339 return ret;
320} 340}
321 341
322/* 342/*
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
index da83105d127d..4e683ae2212b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
@@ -293,6 +293,7 @@ struct cdit_header {
293 293
294int kfd_create_crat_image_acpi(void **crat_image, size_t *size); 294int kfd_create_crat_image_acpi(void **crat_image, size_t *size);
295void kfd_destroy_crat_image(void *crat_image); 295void kfd_destroy_crat_image(void *crat_image);
296int kfd_parse_crat_table(void *crat_image); 296int kfd_parse_crat_table(void *crat_image, struct list_head *device_list,
297 uint32_t proximity_domain);
297 298
298#endif /* KFD_CRAT_H_INCLUDED */ 299#endif /* KFD_CRAT_H_INCLUDED */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 35da4af28c87..f64350b90812 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -34,7 +34,8 @@
34#include "kfd_topology.h" 34#include "kfd_topology.h"
35#include "kfd_device_queue_manager.h" 35#include "kfd_device_queue_manager.h"
36 36
37struct list_head topology_device_list; 37/* topology_device_list - Master list of all topology devices */
38static struct list_head topology_device_list;
38struct kfd_system_properties sys_props; 39struct kfd_system_properties sys_props;
39 40
40static DECLARE_RWSEM(topology_lock); 41static DECLARE_RWSEM(topology_lock);
@@ -105,24 +106,27 @@ static void kfd_release_topology_device(struct kfd_topology_device *dev)
105 } 106 }
106 107
107 kfree(dev); 108 kfree(dev);
108
109 sys_props.num_devices--;
110} 109}
111 110
112void kfd_release_live_view(void) 111void kfd_release_topology_device_list(struct list_head *device_list)
113{ 112{
114 struct kfd_topology_device *dev; 113 struct kfd_topology_device *dev;
115 114
116 while (topology_device_list.next != &topology_device_list) { 115 while (!list_empty(device_list)) {
117 dev = container_of(topology_device_list.next, 116 dev = list_first_entry(device_list,
118 struct kfd_topology_device, list); 117 struct kfd_topology_device, list);
119 kfd_release_topology_device(dev); 118 kfd_release_topology_device(dev);
119 }
120} 120}
121 121
122static void kfd_release_live_view(void)
123{
124 kfd_release_topology_device_list(&topology_device_list);
122 memset(&sys_props, 0, sizeof(sys_props)); 125 memset(&sys_props, 0, sizeof(sys_props));
123} 126}
124 127
125struct kfd_topology_device *kfd_create_topology_device(void) 128struct kfd_topology_device *kfd_create_topology_device(
129 struct list_head *device_list)
126{ 130{
127 struct kfd_topology_device *dev; 131 struct kfd_topology_device *dev;
128 132
@@ -136,8 +140,7 @@ struct kfd_topology_device *kfd_create_topology_device(void)
136 INIT_LIST_HEAD(&dev->cache_props); 140 INIT_LIST_HEAD(&dev->cache_props);
137 INIT_LIST_HEAD(&dev->io_link_props); 141 INIT_LIST_HEAD(&dev->io_link_props);
138 142
139 list_add_tail(&dev->list, &topology_device_list); 143 list_add_tail(&dev->list, device_list);
140 sys_props.num_devices++;
141 144
142 return dev; 145 return dev;
143} 146}
@@ -682,16 +685,32 @@ static void kfd_topology_release_sysfs(void)
682 } 685 }
683} 686}
684 687
688/* Called with write topology_lock acquired */
689static void kfd_topology_update_device_list(struct list_head *temp_list,
690 struct list_head *master_list)
691{
692 while (!list_empty(temp_list)) {
693 list_move_tail(temp_list->next, master_list);
694 sys_props.num_devices++;
695 }
696}
697
685int kfd_topology_init(void) 698int kfd_topology_init(void)
686{ 699{
687 void *crat_image = NULL; 700 void *crat_image = NULL;
688 size_t image_size = 0; 701 size_t image_size = 0;
689 int ret; 702 int ret;
703 struct list_head temp_topology_device_list;
690 704
691 /* 705 /* topology_device_list - Master list of all topology devices
692 * Initialize the head for the topology device list 706 * temp_topology_device_list - temporary list created while parsing CRAT
707 * or VCRAT. Once parsing is complete the contents of list is moved to
708 * topology_device_list
693 */ 709 */
710
711 /* Initialize the head for the both the lists */
694 INIT_LIST_HEAD(&topology_device_list); 712 INIT_LIST_HEAD(&topology_device_list);
713 INIT_LIST_HEAD(&temp_topology_device_list);
695 init_rwsem(&topology_lock); 714 init_rwsem(&topology_lock);
696 715
697 memset(&sys_props, 0, sizeof(sys_props)); 716 memset(&sys_props, 0, sizeof(sys_props));
@@ -701,7 +720,8 @@ int kfd_topology_init(void)
701 */ 720 */
702 ret = kfd_create_crat_image_acpi(&crat_image, &image_size); 721 ret = kfd_create_crat_image_acpi(&crat_image, &image_size);
703 if (!ret) { 722 if (!ret) {
704 ret = kfd_parse_crat_table(crat_image); 723 ret = kfd_parse_crat_table(crat_image,
724 &temp_topology_device_list, 0);
705 if (ret) 725 if (ret)
706 goto err; 726 goto err;
707 } else if (ret == -ENODATA) { 727 } else if (ret == -ENODATA) {
@@ -714,12 +734,15 @@ int kfd_topology_init(void)
714 } 734 }
715 735
716 down_write(&topology_lock); 736 down_write(&topology_lock);
737 kfd_topology_update_device_list(&temp_topology_device_list,
738 &topology_device_list);
717 ret = kfd_topology_update_sysfs(); 739 ret = kfd_topology_update_sysfs();
718 up_write(&topology_lock); 740 up_write(&topology_lock);
719 741
720 if (!ret) 742 if (!ret) {
743 sys_props.generation_count++;
721 pr_info("Finished initializing topology\n"); 744 pr_info("Finished initializing topology\n");
722 else 745 } else
723 pr_err("Failed to update topology in sysfs ret=%d\n", ret); 746 pr_err("Failed to update topology in sysfs ret=%d\n", ret);
724 747
725err: 748err:
@@ -729,8 +752,10 @@ err:
729 752
730void kfd_topology_shutdown(void) 753void kfd_topology_shutdown(void)
731{ 754{
755 down_write(&topology_lock);
732 kfd_topology_release_sysfs(); 756 kfd_topology_release_sysfs();
733 kfd_release_live_view(); 757 kfd_release_live_view();
758 up_write(&topology_lock);
734} 759}
735 760
736static void kfd_debug_print_topology(void) 761static void kfd_debug_print_topology(void)
@@ -806,13 +831,15 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
806 uint32_t gpu_id; 831 uint32_t gpu_id;
807 struct kfd_topology_device *dev; 832 struct kfd_topology_device *dev;
808 struct kfd_cu_info cu_info; 833 struct kfd_cu_info cu_info;
809 int res; 834 int res = 0;
835 struct list_head temp_topology_device_list;
836
837 INIT_LIST_HEAD(&temp_topology_device_list);
810 838
811 gpu_id = kfd_generate_gpu_id(gpu); 839 gpu_id = kfd_generate_gpu_id(gpu);
812 840
813 pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id); 841 pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
814 842
815 down_write(&topology_lock);
816 /* 843 /*
817 * Try to assign the GPU to existing topology device (generated from 844 * Try to assign the GPU to existing topology device (generated from
818 * CRAT table 845 * CRAT table
@@ -821,11 +848,12 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
821 if (!dev) { 848 if (!dev) {
822 pr_info("GPU was not found in the current topology. Extending.\n"); 849 pr_info("GPU was not found in the current topology. Extending.\n");
823 kfd_debug_print_topology(); 850 kfd_debug_print_topology();
824 dev = kfd_create_topology_device(); 851 dev = kfd_create_topology_device(&temp_topology_device_list);
825 if (!dev) { 852 if (!dev) {
826 res = -ENOMEM; 853 res = -ENOMEM;
827 goto err; 854 goto err;
828 } 855 }
856
829 dev->gpu = gpu; 857 dev->gpu = gpu;
830 858
831 /* 859 /*
@@ -833,12 +861,18 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
833 * GPU vBIOS 861 * GPU vBIOS
834 */ 862 */
835 863
864 down_write(&topology_lock);
865 kfd_topology_update_device_list(&temp_topology_device_list,
866 &topology_device_list);
867
836 /* Update the SYSFS tree, since we added another topology 868 /* Update the SYSFS tree, since we added another topology
837 * device 869 * device
838 */ 870 */
839 if (kfd_topology_update_sysfs() < 0) 871 if (kfd_topology_update_sysfs() < 0)
840 kfd_topology_release_sysfs(); 872 kfd_topology_release_sysfs();
841 873
874 up_write(&topology_lock);
875
842 } 876 }
843 877
844 dev->gpu_id = gpu_id; 878 dev->gpu_id = gpu_id;
@@ -859,30 +893,26 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
859 pr_info("Adding doorbell packet type capability\n"); 893 pr_info("Adding doorbell packet type capability\n");
860 } 894 }
861 895
862 res = 0; 896 if (!res)
863
864err:
865 up_write(&topology_lock);
866
867 if (res == 0)
868 kfd_notify_gpu_change(gpu_id, 1); 897 kfd_notify_gpu_change(gpu_id, 1);
869 898err:
870 return res; 899 return res;
871} 900}
872 901
873int kfd_topology_remove_device(struct kfd_dev *gpu) 902int kfd_topology_remove_device(struct kfd_dev *gpu)
874{ 903{
875 struct kfd_topology_device *dev; 904 struct kfd_topology_device *dev, *tmp;
876 uint32_t gpu_id; 905 uint32_t gpu_id;
877 int res = -ENODEV; 906 int res = -ENODEV;
878 907
879 down_write(&topology_lock); 908 down_write(&topology_lock);
880 909
881 list_for_each_entry(dev, &topology_device_list, list) 910 list_for_each_entry_safe(dev, tmp, &topology_device_list, list)
882 if (dev->gpu == gpu) { 911 if (dev->gpu == gpu) {
883 gpu_id = dev->gpu_id; 912 gpu_id = dev->gpu_id;
884 kfd_remove_sysfs_node_entry(dev); 913 kfd_remove_sysfs_node_entry(dev);
885 kfd_release_topology_device(dev); 914 kfd_release_topology_device(dev);
915 sys_props.num_devices--;
886 res = 0; 916 res = 0;
887 if (kfd_topology_update_sysfs() < 0) 917 if (kfd_topology_update_sysfs() < 0)
888 kfd_topology_release_sysfs(); 918 kfd_topology_release_sysfs();
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
index 999645809028..0d98b61b3312 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
@@ -135,6 +135,7 @@ struct kfd_iolink_properties {
135struct kfd_topology_device { 135struct kfd_topology_device {
136 struct list_head list; 136 struct list_head list;
137 uint32_t gpu_id; 137 uint32_t gpu_id;
138 uint32_t proximity_domain;
138 struct kfd_node_properties node_props; 139 struct kfd_node_properties node_props;
139 uint32_t mem_bank_count; 140 uint32_t mem_bank_count;
140 struct list_head mem_props; 141 struct list_head mem_props;
@@ -164,7 +165,8 @@ struct kfd_system_properties {
164 struct attribute attr_props; 165 struct attribute attr_props;
165}; 166};
166 167
167struct kfd_topology_device *kfd_create_topology_device(void); 168struct kfd_topology_device *kfd_create_topology_device(
168void kfd_release_live_view(void); 169 struct list_head *device_list);
170void kfd_release_topology_device_list(struct list_head *device_list);
169 171
170#endif /* __KFD_TOPOLOGY_H__ */ 172#endif /* __KFD_TOPOLOGY_H__ */