@@ -2459,6 +2459,7 @@ static void
2459
2459
hwloc_parse_hugepages_info (struct hwloc_linux_backend_data_s * data ,
2460
2460
const char * dirpath ,
2461
2461
struct hwloc_numanode_attr_s * memory ,
2462
+ unsigned allocated_page_types ,
2462
2463
uint64_t * remaining_local_memory )
2463
2464
{
2464
2465
DIR * dir ;
@@ -2473,6 +2474,14 @@ hwloc_parse_hugepages_info(struct hwloc_linux_backend_data_s *data,
2473
2474
int err ;
2474
2475
if (strncmp (dirent -> d_name , "hugepages-" , 10 ))
2475
2476
continue ;
2477
+ if (index_ >= allocated_page_types ) {
2478
+ /* we must increase the page_types array */
2479
+ struct hwloc_memory_page_type_s * tmp = realloc (memory -> page_types , allocated_page_types * 2 * sizeof (* tmp ));
2480
+ if (!tmp )
2481
+ break ;
2482
+ memory -> page_types = tmp ;
2483
+ allocated_page_types *= 2 ;
2484
+ }
2476
2485
memory -> page_types [index_ ].size = strtoul (dirent -> d_name + 10 , NULL , 0 ) * 1024ULL ;
2477
2486
err = snprintf (path , sizeof (path ), "%s/%s/nr_hugepages" , dirpath , dirent -> d_name );
2478
2487
if ((size_t ) err < sizeof (path )
@@ -2500,7 +2509,14 @@ hwloc_get_machine_meminfo(struct hwloc_linux_backend_data_s *data,
2500
2509
2501
2510
err = hwloc_stat ("/sys/kernel/mm/hugepages" , & st , data -> root_fd );
2502
2511
if (!err ) {
2503
- types = 1 + st .st_nlink - 2 ;
2512
+ types = 1 /* normal non-huge size */ + st .st_nlink - 2 /* ignore . and .. */ ;
2513
+ if (types < 3 )
2514
+ /* some buggy filesystems (e.g. btrfs when reading from fsroot)
2515
+ * return wrong st_nlink for directories (always 1 for btrfs).
2516
+ * use 3 as a sane default (default page + 2 huge sizes).
2517
+ * hwloc_parse_hugepages_info() will extend it if needed.
2518
+ */
2519
+ types = 3 ;
2504
2520
has_sysfs_hugepages = 1 ;
2505
2521
}
2506
2522
@@ -2518,7 +2534,8 @@ hwloc_get_machine_meminfo(struct hwloc_linux_backend_data_s *data,
2518
2534
2519
2535
if (has_sysfs_hugepages ) {
2520
2536
/* read from node%d/hugepages/hugepages-%skB/nr_hugepages */
2521
- hwloc_parse_hugepages_info (data , "/sys/kernel/mm/hugepages" , memory , & remaining_local_memory );
2537
+ hwloc_parse_hugepages_info (data , "/sys/kernel/mm/hugepages" , memory , types , & remaining_local_memory );
2538
+ /* memory->page_types_len may have changed */
2522
2539
}
2523
2540
2524
2541
/* use remaining memory as normal pages */
@@ -2542,7 +2559,14 @@ hwloc_get_sysfs_node_meminfo(struct hwloc_linux_backend_data_s *data,
2542
2559
sprintf (path , "%s/node%d/hugepages" , syspath , node );
2543
2560
err = hwloc_stat (path , & st , data -> root_fd );
2544
2561
if (!err ) {
2545
- types = 1 + st .st_nlink - 2 ;
2562
+ types = 1 /* normal non-huge size */ + st .st_nlink - 2 /* ignore . and .. */ ;
2563
+ if (types < 3 )
2564
+ /* some buggy filesystems (e.g. btrfs when reading from fsroot)
2565
+ * return wrong st_nlink for directories (always 1 for btrfs).
2566
+ * use 3 as a sane default (default page + 2 huge sizes).
2567
+ * hwloc_parse_hugepages_info() will extend it if needed.
2568
+ */
2569
+ types = 3 ;
2546
2570
has_sysfs_hugepages = 1 ;
2547
2571
}
2548
2572
@@ -2561,7 +2585,8 @@ hwloc_get_sysfs_node_meminfo(struct hwloc_linux_backend_data_s *data,
2561
2585
2562
2586
if (has_sysfs_hugepages ) {
2563
2587
/* read from node%d/hugepages/hugepages-%skB/nr_hugepages */
2564
- hwloc_parse_hugepages_info (data , path , memory , & remaining_local_memory );
2588
+ hwloc_parse_hugepages_info (data , path , memory , types , & remaining_local_memory );
2589
+ /* memory->page_types_len may have changed */
2565
2590
}
2566
2591
2567
2592
/* use remaining memory as normal pages */
0 commit comments