Fix hugepage detection issue 67/3167/2
authorDamjan Marion <damarion@cisco.com>
Tue, 27 Sep 2016 15:51:13 +0000 (17:51 +0200)
committerFlorin Coras <florin.coras@gmail.com>
Tue, 27 Sep 2016 19:39:46 +0000 (19:39 +0000)
Per-numa free hugepages number was not read correctly due
to wrong sysfs path.

Change-Id: I889111027d7f93c42e2e4673d8d4e8f75ae065b6
Signed-off-by: Damjan Marion <damarion@cisco.com>
vlib/vlib/unix/unix.h
vlib/vlib/unix/util.c
vnet/vnet/devices/dpdk/init.c

index 510e3f1..69688a6 100644 (file)
@@ -213,6 +213,8 @@ clib_error_t *vlib_sysfs_read (char *file_name, char *fmt, ...);
 
 u8 *vlib_sysfs_link_to_name (char *link);
 
+int vlib_sysfs_get_free_hugepages (unsigned int numa_node, int page_size);
+
 clib_error_t *foreach_directory_file (char *dir_name,
                                      clib_error_t * (*f) (void *arg,
                                                           u8 * path_name,
index fc243e4..edc3e59 100644 (file)
@@ -189,6 +189,39 @@ vlib_sysfs_link_to_name (char *link)
   return s;
 }
 
+int
+vlib_sysfs_get_free_hugepages (unsigned int numa_node, int page_size)
+{
+  struct stat sb;
+  u8 *p = 0;
+  int r = -1;
+
+  p = format (p, "/sys/devices/system/node/node%u%c", numa_node, 0);
+
+  if (stat ((char *) p, &sb) == 0)
+    {
+      if (S_ISDIR (sb.st_mode) == 0)
+       goto done;
+    }
+  else if (numa_node == 0)
+    {
+      vec_reset_length (p);
+      p = format (p, "/sys/kernel/mm%c", 0);
+      if (stat ((char *) p, &sb) < 0 || S_ISDIR (sb.st_mode) == 0)
+       goto done;
+    }
+  else
+    goto done;
+
+  _vec_len (p) -= 1;
+  p = format (p, "/hugepages/hugepages-%ukB/free_hugepages%c", page_size, 0);
+  vlib_sysfs_read ((char *) p, "%d", &r);
+
+done:
+  vec_free (p);
+  return r;
+}
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
index 44b4dc3..433d1d5 100644 (file)
@@ -1199,57 +1199,22 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
       /* *INDENT-OFF* */
       clib_bitmap_foreach (c, tm->cpu_socket_bitmap, (
         {
-         u32 pages_avail, page_size, mem;
-         u8 *s = 0;
-          u8 *p = 0;
-         char * numa_path = "/sys/devices/system/node/node%u/";
-          char * nonnuma_path = "/sys/kernel/mm/";
-          char * suffix = "hugepages/hugepages-%ukB/free_hugepages%c";
-          char * path = NULL;
-          struct stat sb_numa, sb_nonnuma;
-
-          p = format(p, numa_path, c);
-          if (stat(numa_path, &sb_numa) < 0)
-            sb_numa.st_mode = 0;
-
-          if (stat(nonnuma_path, &sb_nonnuma) < 0)
-            sb_nonnuma.st_mode = 0;
-
-          if (S_ISDIR(sb_numa.st_mode)) {
-            path = (char*)format((u8*)path, "%s%s", p, suffix);
-          } else if (S_ISDIR(sb_nonnuma.st_mode)) {
-            path = (char*)format((u8*)path, "%s%s", nonnuma_path, suffix);
-          } else {
-            use_1g = 0;
-            use_2m = 0;
-            vec_free(p);
-            break;
-          }
+         int pages_avail, page_size, mem;
 
          vec_validate(mem_by_socket, c);
          mem = mem_by_socket[c];
 
          page_size = 1024;
-         pages_avail = 0;
-         s = format (s, path, page_size * 1024, 0);
-         vlib_sysfs_read ((char *) s, "%u", &pages_avail);
-         vec_reset_length (s);
+         pages_avail = vlib_sysfs_get_free_hugepages(c, page_size * 1024);
 
-         if (page_size * pages_avail < mem)
+         if (pages_avail < 0 || page_size * pages_avail < mem)
            use_1g = 0;
 
          page_size = 2;
-         pages_avail = 0;
-         s = format (s, path, page_size * 1024, 0);
-         vlib_sysfs_read ((char *) s, "%u", &pages_avail);
-         vec_reset_length (s);
+         pages_avail = vlib_sysfs_get_free_hugepages(c, page_size * 1024);
 
-         if (page_size * pages_avail < mem)
+         if (pages_avail < 0 || page_size * pages_avail < mem)
            use_2m = 0;
-
-         vec_free(s);
-         vec_free(p);
-         vec_free(path);
       }));
       /* *INDENT-ON* */