diff options
Diffstat (limited to 'src/vlib')
-rw-r--r-- | src/vlib/cli.c | 68 | ||||
-rw-r--r-- | src/vlib/threads.c | 35 | ||||
-rw-r--r-- | src/vlib/threads.h | 9 | ||||
-rw-r--r-- | src/vlib/threads_cli.c | 4 |
4 files changed, 100 insertions, 16 deletions
diff --git a/src/vlib/cli.c b/src/vlib/cli.c index bb6c5746537..85049884db6 100644 --- a/src/vlib/cli.c +++ b/src/vlib/cli.c @@ -733,9 +733,10 @@ show_memory_usage (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { int verbose __attribute__ ((unused)) = 0; - int api_segment = 0, stats_segment = 0, main_heap = 0; + int api_segment = 0, stats_segment = 0, main_heap = 0, numa_heaps = 0; clib_error_t *error; u32 index = 0; + int i; uword clib_mem_trace_enable_disable (uword enable); uword was_enabled; @@ -750,6 +751,8 @@ show_memory_usage (vlib_main_t * vm, stats_segment = 1; else if (unformat (input, "main-heap")) main_heap = 1; + else if (unformat (input, "numa-heaps")) + numa_heaps = 1; else { error = clib_error_return (0, "unknown input `%U'", @@ -758,9 +761,9 @@ show_memory_usage (vlib_main_t * vm, } } - if ((api_segment + stats_segment + main_heap) == 0) + if ((api_segment + stats_segment + main_heap + numa_heaps) == 0) return clib_error_return - (0, "Please supply one of api-segment, stats-segment or main-heap"); + (0, "Need one of api-segment, stats-segment, main-heap or numa-heaps"); if (api_segment) { @@ -801,6 +804,7 @@ show_memory_usage (vlib_main_t * vm, vec_free (s); } + #if USE_DLMALLOC == 0 /* *INDENT-OFF* */ foreach_vlib_main ( @@ -849,6 +853,32 @@ show_memory_usage (vlib_main_t * vm, /* Restore the trace flag */ clib_mem_trace_enable_disable (was_enabled); } + if (numa_heaps) + { + struct dlmallinfo mi; + void *mspace; + + for (i = 0; i < ARRAY_LEN (clib_per_numa_mheaps); i++) + { + if (clib_per_numa_mheaps[i] == 0) + continue; + if (clib_per_numa_mheaps[i] == clib_per_cpu_mheaps[i]) + { + vlib_cli_output (vm, "Numa %d uses the main heap...", i); + continue; + } + was_enabled = clib_mem_trace_enable_disable (0); + mspace = clib_per_numa_mheaps[i]; + + mi = mspace_mallinfo (mspace); + vlib_cli_output (vm, "Numa %d:", i); + vlib_cli_output (vm, " %U\n", format_page_map, + pointer_to_uword (mspace_least_addr (mspace)), + mi.arena); + vlib_cli_output (vm, " %U\n", format_mheap, + clib_per_numa_mheaps[index], verbose); + } + } } #endif /* USE_DLMALLOC */ return 0; @@ -857,7 +887,8 @@ show_memory_usage (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_memory_usage_command, static) = { .path = "show memory", - .short_help = "show memory [api-segment][stats-segment][verbose]", + .short_help = "show memory [api-segment][stats-segment][verbose]\n" + " [numa-heaps]", .function = show_memory_usage, }; /* *INDENT-ON* */ @@ -905,6 +936,7 @@ enable_disable_memory_trace (vlib_main_t * vm, int api_segment = 0; int stats_segment = 0; int main_heap = 0; + u32 numa_id = ~0; void *oldheap; if (!unformat_user (input, unformat_line_input, line_input)) @@ -920,6 +952,8 @@ enable_disable_memory_trace (vlib_main_t * vm, stats_segment = 1; else if (unformat (line_input, "main-heap")) main_heap = 1; + else if (unformat (line_input, "numa-heap %d", &numa_id)) + ; else { unformat_free (line_input); @@ -928,10 +962,12 @@ enable_disable_memory_trace (vlib_main_t * vm, } unformat_free (line_input); - if ((api_segment + stats_segment + main_heap + (enable == 0)) == 0) + if ((api_segment + stats_segment + main_heap + (enable == 0) + + (numa_id != ~0)) == 0) { return clib_error_return - (0, "Need one of main-heap, stats-segment or api-segment"); + (0, "Need one of main-heap, stats-segment, api-segment,\n" + "numa-heap <nn> or disable"); } /* Turn off current trace, if any */ @@ -975,13 +1011,31 @@ enable_disable_memory_trace (vlib_main_t * vm, clib_mem_trace (main_heap); } + if (numa_id != ~0) + { + if (numa_id >= ARRAY_LEN (clib_per_numa_mheaps)) + return clib_error_return (0, "Numa %d out of range", numa_id); + if (clib_per_numa_mheaps[numa_id] == 0) + return clib_error_return (0, "Numa %d heap not active", numa_id); + + if (clib_per_numa_mheaps[numa_id] == clib_mem_get_heap ()) + return clib_error_return (0, "Numa %d uses the main heap...", + numa_id); + current_traced_heap = clib_per_numa_mheaps[numa_id]; + oldheap = clib_mem_set_heap (current_traced_heap); + clib_mem_trace (1); + clib_mem_set_heap (oldheap); + } + + return 0; } /* *INDENT-OFF* */ VLIB_CLI_COMMAND (enable_disable_memory_trace_command, static) = { .path = "memory-trace", - .short_help = "memory-trace on|off [api-segment][stats-segment][main-heap]\n", + .short_help = "memory-trace on|off [api-segment][stats-segment][main-heap]\n" + " [numa-heap <numa-id>]\n", .function = enable_disable_memory_trace, }; /* *INDENT-ON* */ diff --git a/src/vlib/threads.c b/src/vlib/threads.c index e6733d55b6f..a827e3594e8 100644 --- a/src/vlib/threads.c +++ b/src/vlib/threads.c @@ -577,12 +577,12 @@ vlib_worker_thread_bootstrap_fn (void *arg) return rv; } -static void -vlib_get_thread_core_socket (vlib_worker_thread_t * w, unsigned cpu_id) +void +vlib_get_thread_core_numa (vlib_worker_thread_t * w, unsigned cpu_id) { const char *sys_cpu_path = "/sys/devices/system/cpu/cpu"; u8 *p = 0; - int core_id = -1, socket_id = -1; + int core_id = -1, numa_id = -1; p = format (p, "%s%u/topology/core_id%c", sys_cpu_path, cpu_id, 0); clib_sysfs_read ((char *) p, "%d", &core_id); @@ -590,11 +590,11 @@ vlib_get_thread_core_socket (vlib_worker_thread_t * w, unsigned cpu_id) p = format (p, "%s%u/topology/physical_package_id%c", sys_cpu_path, cpu_id, 0); - clib_sysfs_read ((char *) p, "%d", &socket_id); + clib_sysfs_read ((char *) p, "%d", &numa_id); vec_free (p); w->core_id = core_id; - w->socket_id = socket_id; + w->numa_id = numa_id; } static clib_error_t * @@ -602,9 +602,29 @@ vlib_launch_thread_int (void *fp, vlib_worker_thread_t * w, unsigned cpu_id) { vlib_thread_main_t *tm = &vlib_thread_main; void *(*fp_arg) (void *) = fp; + void *numa_heap; w->cpu_id = cpu_id; - vlib_get_thread_core_socket (w, cpu_id); + vlib_get_thread_core_numa (w, cpu_id); + os_set_numa_index (w->numa_id); + + /* Set up NUMA-bound heap if indicated */ + if (clib_per_numa_mheaps[w->numa_id] == 0) + { + /* If the user requested a NUMA heap, create it... */ + if (tm->numa_heap_size) + { + numa_heap = clib_mem_init_thread_safe_numa + (0 /* DIY */ , tm->numa_heap_size); + clib_per_numa_mheaps[w->numa_id] = numa_heap; + } + else + { + /* Or, use the main heap */ + clib_per_numa_mheaps[w->numa_id] = w->thread_mheap; + } + } + if (tm->cb.vlib_launch_thread_cb && !w->registration->use_pthreads) return tm->cb.vlib_launch_thread_cb (fp, (void *) w, cpu_id); else @@ -1242,6 +1262,9 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input) ; else if (unformat (input, "skip-cores %u", &tm->skip_cores)) ; + else if (unformat (input, "numa-heap-size %U", + unformat_memory_size, &tm->numa_heap_size)) + ; else if (unformat (input, "coremask-%s %U", &name, unformat_bitmap_mask, &bitmap) || unformat (input, "corelist-%s %U", &name, diff --git a/src/vlib/threads.h b/src/vlib/threads.h index 312323c096d..c1188cea933 100644 --- a/src/vlib/threads.h +++ b/src/vlib/threads.h @@ -110,7 +110,7 @@ typedef struct long lwp; int cpu_id; int core_id; - int socket_id; + int numa_id; pthread_t thread_id; } vlib_worker_thread_t; @@ -338,6 +338,10 @@ typedef struct /* callbacks */ vlib_thread_callbacks_t cb; int extern_thread_mgmt; + + /* NUMA-bound heap size */ + uword numa_heap_size; + } vlib_thread_main_t; extern vlib_thread_main_t vlib_thread_main; @@ -613,6 +617,9 @@ void vlib_process_signal_event_mt_helper (vlib_process_signal_event_mt_args_t * args); void vlib_rpc_call_main_thread (void *function, u8 * args, u32 size); +void vlib_get_thread_core_numa (vlib_worker_thread_t * w, unsigned cpu_id); + + #endif /* included_vlib_threads_h */ /* diff --git a/src/vlib/threads_cli.c b/src/vlib/threads_cli.c index 65b3e2a5496..bcb85ec69fb 100644 --- a/src/vlib/threads_cli.c +++ b/src/vlib/threads_cli.c @@ -67,8 +67,8 @@ show_threads_fn (vlib_main_t * vm, if (cpu_id > -1) { int core_id = w->core_id; - int socket_id = w->socket_id; - line = format (line, "%-7u%-7u%-7u%", cpu_id, core_id, socket_id); + int numa_id = w->numa_id; + line = format (line, "%-7u%-7u%-7u%", cpu_id, core_id, numa_id); } else { |