Justus Winter, le Sat 24 May 2014 12:46:22 +0200, a écrit : > 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
Ack. > * 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 > -- Samuel X-Favorit-Cartoon: Calvin and Hobbes -+- Mail header of Wim van Dorst -+-