@@ -2189,6 +2189,10 @@ void os::print_os_info(outputStream* st) {
21892189 st->cr ();
21902190 }
21912191
2192+ if (os::Linux::print_numa_info (st)) {
2193+ st->cr ();
2194+ }
2195+
21922196 VM_Version::print_platform_virtualization_info (st);
21932197
21942198 os::Linux::print_steal_info (st);
@@ -2592,6 +2596,97 @@ bool os::Linux::print_container_info(outputStream* st) {
25922596 return true ;
25932597}
25942598
2599+ #define SYS_DEVICES_NODE " /sys/devices/system/node"
2600+
2601+ static size_t read_sysfs_file (const char * path, char * buf, size_t sz) {
2602+ FILE * f = os::fopen (path, " r" );
2603+ if (f == nullptr ) return 0 ;
2604+ size_t n = fread (buf, 1 , sz - 1 , f);
2605+ fclose (f);
2606+ buf[n] = ' \0 ' ;
2607+ while (n > 0 && (buf[n-1 ] == ' \n ' || buf[n-1 ] == ' \r ' )) buf[--n] = ' \0 ' ;
2608+ return n;
2609+ }
2610+
2611+ static void print_numa_memory_info (outputStream* st, int node) {
2612+ char path[256 ];
2613+ char line[256 ];
2614+ long long mem_total = -1 ;
2615+ long long mem_free = -1 ;
2616+ os::snprintf_checked (path, sizeof (path), SYS_DEVICES_NODE " /node%d/meminfo" , node);
2617+ FILE * f = os::fopen (path, " r" );
2618+ if (f == nullptr ) {
2619+ return ;
2620+ }
2621+
2622+ while (fgets (line, sizeof (line), f) != nullptr ) {
2623+ long long mval;
2624+ if (sscanf (line, " Node %*d MemTotal: %lld kB" , &mval) == 1 ) mem_total = mval;
2625+ if (sscanf (line, " Node %*d MemFree: %lld kB" , &mval) == 1 ) mem_free = mval;
2626+ }
2627+ fclose (f);
2628+
2629+ if (mem_total >= 0 ) { st->print_cr (" mem size: %lld kB" , mem_total); }
2630+ if (mem_free >= 0 ) { st->print_cr (" mem free: %lld kB" , mem_free); }
2631+ }
2632+
2633+ static void print_numa_cpu_list (outputStream* st, int node) {
2634+ char path[256 ];
2635+ char buf[1024 ];
2636+ os::snprintf_checked (path, sizeof (path), SYS_DEVICES_NODE " /node%d/cpulist" , node);
2637+ if (read_sysfs_file (path, buf, sizeof (buf)) > 0 ) {
2638+ st->print_cr (" cpus: %s" , buf);
2639+ } else {
2640+ st->print_cr (" cpus: (unavailable)" );
2641+ }
2642+ }
2643+
2644+ bool os::Linux::print_numa_info (outputStream* st) {
2645+ if (!UseNUMA) {
2646+ // If NUMA optimizations are not enabled we don't print anything
2647+ return false ;
2648+ }
2649+
2650+ char buf[1024 ];
2651+ if (read_sysfs_file (" /sys/devices/system/node/online" , buf, sizeof (buf)) > 0 ) {
2652+ st->print_cr (" NUMA nodes online: %s" , buf);
2653+ } else {
2654+ return false ;
2655+ }
2656+
2657+ bool first = true ;
2658+ int node_count = 0 ;
2659+
2660+ if (nindex_to_node () == nullptr ) {
2661+ return false ;
2662+ }
2663+
2664+ for (int node: *nindex_to_node ()) {
2665+ char nodepath[256 ];
2666+ os::snprintf_checked (nodepath, sizeof (nodepath), SYS_DEVICES_NODE " /node%d" , node);
2667+ DIR * currd = os::opendir (nodepath);
2668+ if (currd == nullptr ) continue ;
2669+ if (first) {
2670+ st->cr ();
2671+ first = false ;
2672+ }
2673+ os::closedir (currd);
2674+
2675+ st->print_cr (" NUMA node %d" , node);
2676+ StreamIndentor si (st);
2677+ print_numa_cpu_list (st, node);
2678+ print_numa_memory_info (st, node);
2679+ node_count++;
2680+ }
2681+
2682+ if (node_count == 0 ) {
2683+ return false ;
2684+ }
2685+
2686+ st->print_cr (" Total NUMA node count: %d" , node_count);
2687+ return true ;
2688+ }
2689+
25952690void os::Linux::print_steal_info (outputStream* st) {
25962691 if (has_initial_tick_info) {
25972692 CPUPerfTicks pticks;
0 commit comments