diff options
author | Harish Kasiviswanathan <harish.kasiviswanathan@amd.com> | 2017-12-08 23:08:52 -0500 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@gmail.com> | 2017-12-08 23:08:52 -0500 |
commit | 4f449311e9aa177bd224e7b13cb0f6a55c524bcb (patch) | |
tree | fcacee39110db75947b4f5fc0917da8c4afa6944 /drivers | |
parent | 8e05247d4c23ff1c91682cf28d2ddb4210808e7d (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.c | 118 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_crat.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 84 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 6 |
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 | ||
26 | static int topology_crat_parsed; | ||
27 | extern struct list_head topology_device_list; | ||
28 | extern struct kfd_system_properties sys_props; | 26 | extern struct kfd_system_properties sys_props; |
29 | 27 | ||
30 | static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, | 28 | 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 | 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 |
61 | static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu) | 59 | * topology device present in the device_list |
60 | */ | ||
61 | static 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 | */ |
87 | static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem) | 85 | static 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 | */ |
131 | static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache) | 127 | static 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 | */ |
178 | static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink) | 174 | static 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 | ||
225 | static 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 | */ | ||
225 | static 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 | ||
270 | int 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 | */ | ||
281 | int 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++; | 335 | err: |
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 | ||
294 | int kfd_create_crat_image_acpi(void **crat_image, size_t *size); | 294 | int kfd_create_crat_image_acpi(void **crat_image, size_t *size); |
295 | void kfd_destroy_crat_image(void *crat_image); | 295 | void kfd_destroy_crat_image(void *crat_image); |
296 | int kfd_parse_crat_table(void *crat_image); | 296 | int 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 | ||
37 | struct list_head topology_device_list; | 37 | /* topology_device_list - Master list of all topology devices */ |
38 | static struct list_head topology_device_list; | ||
38 | struct kfd_system_properties sys_props; | 39 | struct kfd_system_properties sys_props; |
39 | 40 | ||
40 | static DECLARE_RWSEM(topology_lock); | 41 | static 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 | ||
112 | void kfd_release_live_view(void) | 111 | void 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 | ||
122 | static 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 | ||
125 | struct kfd_topology_device *kfd_create_topology_device(void) | 128 | struct 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 */ | ||
689 | static 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 | |||
685 | int kfd_topology_init(void) | 698 | int 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 | ||
725 | err: | 748 | err: |
@@ -729,8 +752,10 @@ err: | |||
729 | 752 | ||
730 | void kfd_topology_shutdown(void) | 753 | void 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 | ||
736 | static void kfd_debug_print_topology(void) | 761 | static 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 | |||
864 | err: | ||
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 | 898 | err: | |
870 | return res; | 899 | return res; |
871 | } | 900 | } |
872 | 901 | ||
873 | int kfd_topology_remove_device(struct kfd_dev *gpu) | 902 | int 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 { | |||
135 | struct kfd_topology_device { | 135 | struct 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 | ||
167 | struct kfd_topology_device *kfd_create_topology_device(void); | 168 | struct kfd_topology_device *kfd_create_topology_device( |
168 | void kfd_release_live_view(void); | 169 | struct list_head *device_list); |
170 | void kfd_release_topology_device_list(struct list_head *device_list); | ||
169 | 171 | ||
170 | #endif /* __KFD_TOPOLOGY_H__ */ | 172 | #endif /* __KFD_TOPOLOGY_H__ */ |