@@ -288,10 +288,23 @@ int get_topology_info(struct pal_topo_info* topo_info) {
288288 int ret = iterate_ranges_from_file ("/sys/devices/system/cpu/possible" , get_ranges_end , & threads_cnt );
289289 if (ret < 0 )
290290 return ret ;
291- size_t nodes_cnt = 0 ;
291+
292+ bool cpu_nodes_file_exists = false;
293+ size_t nodes_cnt = 1 ;
294+ /* Get the CPU node number. By default, the number is 1.
295+ * Some systems do not have the file, for example, Windows Subsystem for Linux, for which we
296+ * will ignore the -ENOENT error and synthesize later a corresponding (single) numa node
297+ * instead. */
292298 ret = iterate_ranges_from_file ("/sys/devices/system/node/possible" , get_ranges_end , & nodes_cnt );
293- if (ret < 0 )
294- return ret ;
299+ if (ret < 0 ) {
300+ if (ret != - ENOENT ) {
301+ return ret ;
302+ } else {
303+ cpu_nodes_file_exists = false;
304+ }
305+ } else {
306+ cpu_nodes_file_exists = true;
307+ }
295308
296309 struct pal_cpu_thread_info * threads = malloc (threads_cnt * sizeof (* threads ));
297310 size_t caches_cnt = 0 ;
@@ -322,10 +335,15 @@ int get_topology_info(struct pal_topo_info* topo_info) {
322335 ret = iterate_ranges_from_file ("/sys/devices/system/cpu/online" , set_thread_online , threads );
323336 if (ret < 0 )
324337 goto fail ;
325- ret = iterate_ranges_from_file ("/sys/devices/system/node/online" , set_numa_node_online ,
326- numa_nodes );
327- if (ret < 0 )
328- goto fail ;
338+
339+ if (cpu_nodes_file_exists ) {
340+ ret = iterate_ranges_from_file ("/sys/devices/system/node/online" , set_numa_node_online , numa_nodes );
341+ if (ret < 0 )
342+ goto fail ;
343+ } else {
344+ /* If there is no node information, the (only) node must be online. */
345+ numa_nodes [0 ].is_online = true;
346+ }
329347
330348 char path [128 ];
331349 for (size_t i = 0 ; i < threads_cnt ; i ++ ) {
@@ -367,23 +385,30 @@ int get_topology_info(struct pal_topo_info* topo_info) {
367385 }
368386 }
369387
370- for (size_t i = 0 ; i < nodes_cnt ; i ++ ) {
371- if (!numa_nodes [i ].is_online )
372- continue ;
388+ if (cpu_nodes_file_exists ) {
389+ for (size_t i = 0 ; i < nodes_cnt ; i ++ ) {
390+ if (!numa_nodes [i ].is_online )
391+ continue ;
373392
374- snprintf (path , sizeof (path ), "/sys/devices/system/node/node%zu/cpulist" , i );
375- ret = iterate_ranges_from_file (path , set_node_id , & (struct set_node_id_args ){
376- .threads = threads ,
377- .cores = cores ,
378- .id_to_set = i ,
379- });
380- if (ret < 0 )
381- goto fail ;
393+ snprintf (path , sizeof (path ), "/sys/devices/system/node/node%zu/cpulist" , i );
394+ ret = iterate_ranges_from_file (path , set_node_id , & (struct set_node_id_args ){
395+ .threads = threads ,
396+ .cores = cores ,
397+ .id_to_set = i ,
398+ });
399+ if (ret < 0 )
400+ goto fail ;
382401
383- /* Since our sysfs doesn't support writes, set persistent hugepages to their default value
384- * of zero */
385- numa_nodes [i ].nr_hugepages [HUGEPAGES_2M ] = 0 ;
386- numa_nodes [i ].nr_hugepages [HUGEPAGES_1G ] = 0 ;
402+ /* Since our sysfs doesn't support writes, set persistent hugepages to their default value
403+ * of zero */
404+ numa_nodes [i ].nr_hugepages [HUGEPAGES_2M ] = 0 ;
405+ numa_nodes [i ].nr_hugepages [HUGEPAGES_1G ] = 0 ;
406+ }
407+ } else {
408+ /* As node-id is by default zero we do not have to call set_node_id for synthesized mnode
409+ * and, as above, unsupported persistent huge pages to zero */
410+ numa_nodes [0 ].nr_hugepages [HUGEPAGES_2M ] = 0 ;
411+ numa_nodes [0 ].nr_hugepages [HUGEPAGES_1G ] = 0 ;
387412 }
388413
389414 /*
@@ -400,18 +425,23 @@ int get_topology_info(struct pal_topo_info* topo_info) {
400425 * 0 , 0 , 0
401426 * node 2 -> node 0, 0 , node 2 -> node 2 ]
402427 */
403- memset (distances , 0 , nodes_cnt * nodes_cnt * sizeof (* distances ));
404- for (size_t i = 0 ; i < nodes_cnt ; i ++ ) {
405- if (!numa_nodes [i ].is_online )
406- continue ;
407-
408- /* populate row i of `distances`, setting only online nodes */
409- ret = snprintf (path , sizeof (path ), "/sys/devices/system/node/node%zu/distance" , i );
410- if (ret < 0 )
411- goto fail ;
412- ret = read_distances_from_file (path , distances + i * nodes_cnt , numa_nodes , nodes_cnt );
413- if (ret < 0 )
414- goto fail ;
428+ if (cpu_nodes_file_exists ) {
429+ memset (distances , 0 , nodes_cnt * nodes_cnt * sizeof (* distances ));
430+ for (size_t i = 0 ; i < nodes_cnt ; i ++ ) {
431+ if (!numa_nodes [i ].is_online )
432+ continue ;
433+
434+ /* populate row i of `distances`, setting only online nodes */
435+ ret = snprintf (path , sizeof (path ), "/sys/devices/system/node/node%zu/distance" , i );
436+ if (ret < 0 )
437+ goto fail ;
438+ ret = read_distances_from_file (path , distances + i * nodes_cnt , numa_nodes , nodes_cnt );
439+ if (ret < 0 )
440+ goto fail ;
441+ }
442+ } else {
443+ /* Set the distance with default value Ubuntu 22.04 kernel 5.15 for syntheized numa node */
444+ distances [0 ] = 10 ;
415445 }
416446
417447 for (size_t i = 0 ; i < threads_cnt ; i ++ ) {
0 commit comments