MAP: Convert from DPO to input feature.
[vpp.git] / src / vppinfra / unix-formats.c
index eceea2d..c447329 100644 (file)
 
 #ifdef __KERNEL__
 
+#if __linux__
 # include <linux/unistd.h>
 # include <linux/signal.h>
+#endif
 
 #else /* ! __KERNEL__ */
 
+#ifdef __APPLE__
+#define _XOPEN_SOURCE
+#endif
+
 #define _GNU_SOURCE            /* to get REG_* in ucontext.h */
 #include <ucontext.h>
 #undef _GNU_SOURCE
 #include <math.h>
 
 #include <vppinfra/time.h>
+#if __linux__
+#include <vppinfra/linux/syscall.h>
 
 #ifdef AF_NETLINK
 #include <linux/types.h>
 #include <linux/netlink.h>
 #endif
+#endif
 
 #endif /* ! __KERNEL__ */
 
@@ -276,6 +285,7 @@ u8 * format_sockaddr (u8 * s, va_list * args)
   return s;
 }
 
+#ifndef __APPLE__
 u8 * format_tcp4_packet (u8 * s, va_list * args)
 {
   u8 * p = va_arg (*args, u8 *);
@@ -831,6 +841,7 @@ u8 * format_timeval (u8 * s, va_list * args)
 
   return s;
 }
+#endif
 
 u8 * format_time_float (u8 * s, va_list * args)
 {
@@ -953,4 +964,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__ */