bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Implement /proc/slabinfo


From: Justus Winter
Subject: [PATCH] Implement /proc/slabinfo
Date: Sat, 24 May 2014 12:46:22 +0200

Add a node 'slabinfo' to the root directory that contains information
about the slab allocator used in GNU Mach.

The formatting code has been taken from Richard Braun's standalone
client available here:

git://darnassus.sceen.net/rbraun/slabinfo.git

* rootdir.c (rootdir_gc_slabinfo): New function.
(rootdir_entries): Add node 'slabinfo'.
* Makefile (OBJS): Add mach_debugUser.o.
(rootdir.o): Add an explicit dependency on mach_debug_U.h.
Furthermore, add rules to create both functions.
---
 Makefile  | 22 ++++++++++++++++++-
 rootdir.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 5c51c1d..2820596 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 TARGET = procfs
 OBJS = procfs.o netfs.o procfs_dir.o \
-       process.o proclist.o rootdir.o dircat.o main.o
+       process.o proclist.o rootdir.o dircat.o main.o mach_debugUser.o
 LIBS = -lnetfs -lps -lfshelp -lpthread
 
 CC = gcc
@@ -19,8 +19,28 @@ CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
 
 all: $(TARGET)
 
+rootdir.o: rootdir.c mach_debug_U.h
+
 $(TARGET): $(OBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
 
 clean:
        $(RM) $(TARGET) $(OBJS)
+
+# This is the gist of the MIG user stub handling from Hurd's build
+# system:
+
+# Where to find .defs files.
+vpath %.defs /usr/include/mach_debug
+
+MIG = mig
+MIGCOM = $(MIG) -cc cat - /dev/null
+MIGCOMFLAGS := -subrprefix __
+
+%.udefsi: %.defs
+       $(CPP) -x c $(CPPFLAGS) $(MIGUFLAGS) $($*-MIGUFLAGS) \
+         $< -o $*.udefsi
+
+%_U.h %User.c: %.udefsi
+       $(MIGCOM) $(MIGCOMFLAGS) $(MIGCOMUFLAGS) $($*-MIGCOMUFLAGS) < $< \
+                 -user $*User.c -server /dev/null -header $*_U.h
diff --git a/rootdir.c b/rootdir.c
index 94b0ddb..076885c 100644
--- a/rootdir.c
+++ b/rootdir.c
@@ -22,6 +22,7 @@
 #include <mach/vm_statistics.h>
 #include <mach/vm_cache_statistics.h>
 #include <mach/default_pager.h>
+#include <mach_debug/mach_debug_types.h>
 #include <hurd/paths.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -35,6 +36,8 @@
 #include "procfs_dir.h"
 #include "main.h"
 
+#include "mach_debug_U.h"
+
 /* This implements a directory node with the static files in /proc.
    NB: the libps functions for host information return static storage;
    using them would require locking and as a consequence it would be
@@ -470,6 +473,69 @@ rootdir_mounts_exists (void *dir_hook, const void 
*entry_hook)
     translator_exists = access (MTAB_TRANSLATOR, F_OK|X_OK) == 0;
   return translator_exists;
 }
+
+static error_t
+rootdir_gc_slabinfo (void *hook, char **contents, ssize_t *contents_len)
+{
+  error_t err;
+  FILE *m;
+  const char header[] =
+    "cache                          obj slab  bufs   objs   bufs"
+    "    total reclaimable\n"
+    "name                  flags   size size /slab  usage  count"
+    "   memory      memory\n";
+  cache_info_array_t cache_info;
+  size_t mem_usage, mem_reclaimable, mem_total, mem_total_reclaimable;
+  mach_msg_type_number_t cache_info_count;
+  int i;
+
+  cache_info = NULL;
+  cache_info_count = 0;
+
+  err = host_slab_info (mach_host_self(), &cache_info, &cache_info_count);
+  if (err)
+    return err;
+
+  m = open_memstream (contents, contents_len);
+  if (m == NULL)
+    {
+      err = ENOMEM;
+      goto out;
+    }
+
+  fprintf (m, "%s", header);
+
+  mem_total = 0;
+  mem_total_reclaimable = 0;
+
+  for (i = 0; i < cache_info_count; i++)
+    {
+      mem_usage = (cache_info[i].nr_slabs * cache_info[i].slab_size)
+       >> 10;
+      mem_total += mem_usage;
+      mem_reclaimable = (cache_info[i].flags & CACHE_FLAGS_NO_RECLAIM)
+       ? 0 : (cache_info[i].nr_free_slabs
+              * cache_info[i].slab_size) >> 10;
+      mem_total_reclaimable += mem_reclaimable;
+      fprintf (m,
+               "%-21s %04x %7zu %3zuk  %4lu %6lu %6lu %7zuk %10zuk\n",
+               cache_info[i].name, cache_info[i].flags,
+               cache_info[i].obj_size, cache_info[i].slab_size >> 10,
+               cache_info[i].bufs_per_slab, cache_info[i].nr_objs,
+               cache_info[i].nr_bufs, mem_usage, mem_reclaimable);
+    }
+
+  fprintf (m, "total: %zuk, reclaimable: %zuk\n",
+           mem_total, mem_total_reclaimable);
+
+  fclose (m);
+  *contents_len += 1;  /* For the terminating 0.  */
+
+ out:
+  vm_deallocate (mach_task_self (),
+                 cache_info, cache_info_count * sizeof *cache_info);
+  return err;
+}
 
 /* Glue logic and entries table */
 
@@ -563,6 +629,13 @@ static const struct procfs_dir_entry rootdir_entries[] = {
       .exists = rootdir_mounts_exists,
     }
   },
+  {
+    .name = "slabinfo",
+    .hook = & (struct procfs_node_ops) {
+      .get_contents = rootdir_gc_slabinfo,
+      .cleanup_contents = procfs_cleanup_contents_with_free,
+    },
+  },
 #ifdef PROFILE
   /* In order to get a usable gmon.out file, we must apparently use exit(). */
   {
-- 
2.0.0.rc2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]