diff options
-rw-r--r-- | src/vlib/cli.c | 9 | ||||
-rw-r--r-- | src/vppinfra/format.h | 1 | ||||
-rw-r--r-- | src/vppinfra/unix-formats.c | 63 |
3 files changed, 71 insertions, 2 deletions
diff --git a/src/vlib/cli.c b/src/vlib/cli.c index ca8d2abc999..1692ad82672 100644 --- a/src/vlib/cli.c +++ b/src/vlib/cli.c @@ -745,8 +745,13 @@ show_memory_usage (vlib_main_t * vm, /* *INDENT-OFF* */ foreach_vlib_main ( ({ - vlib_cli_output (vm, "Thread %d %v\n", index, vlib_worker_threads[index].name); - vlib_cli_output (vm, "%U\n", format_mheap, clib_per_cpu_mheaps[index], verbose); + mheap_t *h = mheap_header (clib_per_cpu_mheaps[index]); + vlib_cli_output (vm, "%sThread %d %v\n", index ? "\n":"", index, + vlib_worker_threads[index].name); + vlib_cli_output (vm, " %U\n", format_page_map, pointer_to_uword (h) - + h->vm_alloc_offset_from_header, + h->vm_alloc_size); + vlib_cli_output (vm, " %U\n", format_mheap, clib_per_cpu_mheaps[index], verbose); index++; })); /* *INDENT-ON* */ diff --git a/src/vppinfra/format.h b/src/vppinfra/format.h index a27fbb9d851..9a3a342076b 100644 --- a/src/vppinfra/format.h +++ b/src/vppinfra/format.h @@ -116,6 +116,7 @@ _(format_timeval); _(format_time_float); _(format_signal); _(format_ucontext_pc); +_(format_page_map); #endif #undef _ diff --git a/src/vppinfra/unix-formats.c b/src/vppinfra/unix-formats.c index eceea2d25be..b3b8c899d70 100644 --- a/src/vppinfra/unix-formats.c +++ b/src/vppinfra/unix-formats.c @@ -57,6 +57,7 @@ #include <math.h> #include <vppinfra/time.h> +#include <vppinfra/linux/syscall.h> #ifdef AF_NETLINK #include <linux/types.h> @@ -953,4 +954,66 @@ unformat_unix_gid (unformat_input_t * input, va_list * args) return 0; } +#define MAX_NUMNODES 16 +u8 * +format_page_map (u8 * s, va_list * args) +{ + uword va = va_arg (*args, uword); + uword size = va_arg (*args, uword); + uword page_size = clib_mem_get_page_size (); + u32 indent = format_get_indent (s); + uword n_pages = size / page_size; + uword pages_per_numa[MAX_NUMNODES] = { 0 }; + uword pages_not_mapped = 0; + uword pages_unknown = 0; + int *status = 0; + void **ptr = 0; + int i; + + s = format (s, "virtual memory start 0x%llx, size %lluk, %u pages, " + "page size %uk", va, size / 1024, n_pages, page_size / 1024); + + vec_validate (status, n_pages - 1); + vec_validate (ptr, n_pages - 1); + + for (i = 0; i < n_pages; i++) + ptr[i] = uword_to_pointer (va + i * page_size, void *); + + if (move_pages (0, n_pages, ptr, 0, status, 0) != 0) + { + s = format (s, "\n%Upage information not available (errno %u)", + format_white_space, indent + 2, errno); + goto done; + } + + for (i = 0; i < n_pages; i++) + { + if (status[i] >= 0 && status[i] < MAX_NUMNODES) + pages_per_numa[status[i]]++; + else if (status[i] == -EFAULT) + pages_not_mapped++; + else + pages_unknown++; + } + + for (i = 0; i < MAX_NUMNODES; i++) + if (pages_per_numa[i]) + s = format (s, "\n%Unuma %u: %d pages, %luk", format_white_space, + indent + 2, i, pages_per_numa[i], pages_per_numa[i] * + page_size / 1024); + + s = format (s, "\n%Unot mapped: %u pages, %luk", format_white_space, + indent + 2, pages_not_mapped, pages_not_mapped * + page_size / 1024); + + if (pages_unknown) + s = format (s, "\n%Uunknown: %u pages, %luk", format_white_space, + indent + 2, pages_unknown, pages_unknown * page_size / 1024); + +done: + vec_free (status); + vec_free (ptr); + return s; +} + #endif /* __KERNEL__ */ |