The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/tools/slub/slabinfo.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Slabinfo: Tool to get reports about slabs
    3  *
    4  * (C) 2007 sgi, Christoph Lameter
    5  * (C) 2011 Linux Foundation, Christoph Lameter
    6  *
    7  * Compile with:
    8  *
    9  * gcc -o slabinfo slabinfo.c
   10  */
   11 #include <stdio.h>
   12 #include <stdlib.h>
   13 #include <sys/types.h>
   14 #include <dirent.h>
   15 #include <strings.h>
   16 #include <string.h>
   17 #include <unistd.h>
   18 #include <stdarg.h>
   19 #include <getopt.h>
   20 #include <regex.h>
   21 #include <errno.h>
   22 
   23 #define MAX_SLABS 500
   24 #define MAX_ALIASES 500
   25 #define MAX_NODES 1024
   26 
   27 struct slabinfo {
   28         char *name;
   29         int alias;
   30         int refs;
   31         int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
   32         int hwcache_align, object_size, objs_per_slab;
   33         int sanity_checks, slab_size, store_user, trace;
   34         int order, poison, reclaim_account, red_zone;
   35         unsigned long partial, objects, slabs, objects_partial, objects_total;
   36         unsigned long alloc_fastpath, alloc_slowpath;
   37         unsigned long free_fastpath, free_slowpath;
   38         unsigned long free_frozen, free_add_partial, free_remove_partial;
   39         unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill;
   40         unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
   41         unsigned long deactivate_to_head, deactivate_to_tail;
   42         unsigned long deactivate_remote_frees, order_fallback;
   43         unsigned long cmpxchg_double_cpu_fail, cmpxchg_double_fail;
   44         unsigned long alloc_node_mismatch, deactivate_bypass;
   45         int numa[MAX_NODES];
   46         int numa_partial[MAX_NODES];
   47 } slabinfo[MAX_SLABS];
   48 
   49 struct aliasinfo {
   50         char *name;
   51         char *ref;
   52         struct slabinfo *slab;
   53 } aliasinfo[MAX_ALIASES];
   54 
   55 int slabs = 0;
   56 int actual_slabs = 0;
   57 int aliases = 0;
   58 int alias_targets = 0;
   59 int highest_node = 0;
   60 
   61 char buffer[4096];
   62 
   63 int show_empty = 0;
   64 int show_report = 0;
   65 int show_alias = 0;
   66 int show_slab = 0;
   67 int skip_zero = 1;
   68 int show_numa = 0;
   69 int show_track = 0;
   70 int show_first_alias = 0;
   71 int validate = 0;
   72 int shrink = 0;
   73 int show_inverted = 0;
   74 int show_single_ref = 0;
   75 int show_totals = 0;
   76 int sort_size = 0;
   77 int sort_active = 0;
   78 int set_debug = 0;
   79 int show_ops = 0;
   80 int show_activity = 0;
   81 
   82 /* Debug options */
   83 int sanity = 0;
   84 int redzone = 0;
   85 int poison = 0;
   86 int tracking = 0;
   87 int tracing = 0;
   88 
   89 int page_size;
   90 
   91 regex_t pattern;
   92 
   93 static void fatal(const char *x, ...)
   94 {
   95         va_list ap;
   96 
   97         va_start(ap, x);
   98         vfprintf(stderr, x, ap);
   99         va_end(ap);
  100         exit(EXIT_FAILURE);
  101 }
  102 
  103 static void usage(void)
  104 {
  105         printf("slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.\n\n"
  106                 "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
  107                 "-a|--aliases           Show aliases\n"
  108                 "-A|--activity          Most active slabs first\n"
  109                 "-d<options>|--debug=<options> Set/Clear Debug options\n"
  110                 "-D|--display-active    Switch line format to activity\n"
  111                 "-e|--empty             Show empty slabs\n"
  112                 "-f|--first-alias       Show first alias\n"
  113                 "-h|--help              Show usage information\n"
  114                 "-i|--inverted          Inverted list\n"
  115                 "-l|--slabs             Show slabs\n"
  116                 "-n|--numa              Show NUMA information\n"
  117                 "-o|--ops               Show kmem_cache_ops\n"
  118                 "-s|--shrink            Shrink slabs\n"
  119                 "-r|--report            Detailed report on single slabs\n"
  120                 "-S|--Size              Sort by size\n"
  121                 "-t|--tracking          Show alloc/free information\n"
  122                 "-T|--Totals            Show summary information\n"
  123                 "-v|--validate          Validate slabs\n"
  124                 "-z|--zero              Include empty slabs\n"
  125                 "-1|--1ref              Single reference\n"
  126                 "\nValid debug options (FZPUT may be combined)\n"
  127                 "a / A          Switch on all debug options (=FZUP)\n"
  128                 "-              Switch off all debug options\n"
  129                 "f / F          Sanity Checks (SLAB_DEBUG_FREE)\n"
  130                 "z / Z          Redzoning\n"
  131                 "p / P          Poisoning\n"
  132                 "u / U          Tracking\n"
  133                 "t / T          Tracing\n"
  134         );
  135 }
  136 
  137 static unsigned long read_obj(const char *name)
  138 {
  139         FILE *f = fopen(name, "r");
  140 
  141         if (!f)
  142                 buffer[0] = 0;
  143         else {
  144                 if (!fgets(buffer, sizeof(buffer), f))
  145                         buffer[0] = 0;
  146                 fclose(f);
  147                 if (buffer[strlen(buffer)] == '\n')
  148                         buffer[strlen(buffer)] = 0;
  149         }
  150         return strlen(buffer);
  151 }
  152 
  153 
  154 /*
  155  * Get the contents of an attribute
  156  */
  157 static unsigned long get_obj(const char *name)
  158 {
  159         if (!read_obj(name))
  160                 return 0;
  161 
  162         return atol(buffer);
  163 }
  164 
  165 static unsigned long get_obj_and_str(const char *name, char **x)
  166 {
  167         unsigned long result = 0;
  168         char *p;
  169 
  170         *x = NULL;
  171 
  172         if (!read_obj(name)) {
  173                 x = NULL;
  174                 return 0;
  175         }
  176         result = strtoul(buffer, &p, 10);
  177         while (*p == ' ')
  178                 p++;
  179         if (*p)
  180                 *x = strdup(p);
  181         return result;
  182 }
  183 
  184 static void set_obj(struct slabinfo *s, const char *name, int n)
  185 {
  186         char x[100];
  187         FILE *f;
  188 
  189         snprintf(x, 100, "%s/%s", s->name, name);
  190         f = fopen(x, "w");
  191         if (!f)
  192                 fatal("Cannot write to %s\n", x);
  193 
  194         fprintf(f, "%d\n", n);
  195         fclose(f);
  196 }
  197 
  198 static unsigned long read_slab_obj(struct slabinfo *s, const char *name)
  199 {
  200         char x[100];
  201         FILE *f;
  202         size_t l;
  203 
  204         snprintf(x, 100, "%s/%s", s->name, name);
  205         f = fopen(x, "r");
  206         if (!f) {
  207                 buffer[0] = 0;
  208                 l = 0;
  209         } else {
  210                 l = fread(buffer, 1, sizeof(buffer), f);
  211                 buffer[l] = 0;
  212                 fclose(f);
  213         }
  214         return l;
  215 }
  216 
  217 
  218 /*
  219  * Put a size string together
  220  */
  221 static int store_size(char *buffer, unsigned long value)
  222 {
  223         unsigned long divisor = 1;
  224         char trailer = 0;
  225         int n;
  226 
  227         if (value > 1000000000UL) {
  228                 divisor = 100000000UL;
  229                 trailer = 'G';
  230         } else if (value > 1000000UL) {
  231                 divisor = 100000UL;
  232                 trailer = 'M';
  233         } else if (value > 1000UL) {
  234                 divisor = 100;
  235                 trailer = 'K';
  236         }
  237 
  238         value /= divisor;
  239         n = sprintf(buffer, "%ld",value);
  240         if (trailer) {
  241                 buffer[n] = trailer;
  242                 n++;
  243                 buffer[n] = 0;
  244         }
  245         if (divisor != 1) {
  246                 memmove(buffer + n - 2, buffer + n - 3, 4);
  247                 buffer[n-2] = '.';
  248                 n++;
  249         }
  250         return n;
  251 }
  252 
  253 static void decode_numa_list(int *numa, char *t)
  254 {
  255         int node;
  256         int nr;
  257 
  258         memset(numa, 0, MAX_NODES * sizeof(int));
  259 
  260         if (!t)
  261                 return;
  262 
  263         while (*t == 'N') {
  264                 t++;
  265                 node = strtoul(t, &t, 10);
  266                 if (*t == '=') {
  267                         t++;
  268                         nr = strtoul(t, &t, 10);
  269                         numa[node] = nr;
  270                         if (node > highest_node)
  271                                 highest_node = node;
  272                 }
  273                 while (*t == ' ')
  274                         t++;
  275         }
  276 }
  277 
  278 static void slab_validate(struct slabinfo *s)
  279 {
  280         if (strcmp(s->name, "*") == 0)
  281                 return;
  282 
  283         set_obj(s, "validate", 1);
  284 }
  285 
  286 static void slab_shrink(struct slabinfo *s)
  287 {
  288         if (strcmp(s->name, "*") == 0)
  289                 return;
  290 
  291         set_obj(s, "shrink", 1);
  292 }
  293 
  294 int line = 0;
  295 
  296 static void first_line(void)
  297 {
  298         if (show_activity)
  299                 printf("Name                   Objects      Alloc       Free   %%Fast Fallb O CmpX   UL\n");
  300         else
  301                 printf("Name                   Objects Objsize    Space "
  302                         "Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg\n");
  303 }
  304 
  305 /*
  306  * Find the shortest alias of a slab
  307  */
  308 static struct aliasinfo *find_one_alias(struct slabinfo *find)
  309 {
  310         struct aliasinfo *a;
  311         struct aliasinfo *best = NULL;
  312 
  313         for(a = aliasinfo;a < aliasinfo + aliases; a++) {
  314                 if (a->slab == find &&
  315                         (!best || strlen(best->name) < strlen(a->name))) {
  316                                 best = a;
  317                                 if (strncmp(a->name,"kmall", 5) == 0)
  318                                         return best;
  319                         }
  320         }
  321         return best;
  322 }
  323 
  324 static unsigned long slab_size(struct slabinfo *s)
  325 {
  326         return  s->slabs * (page_size << s->order);
  327 }
  328 
  329 static unsigned long slab_activity(struct slabinfo *s)
  330 {
  331         return  s->alloc_fastpath + s->free_fastpath +
  332                 s->alloc_slowpath + s->free_slowpath;
  333 }
  334 
  335 static void slab_numa(struct slabinfo *s, int mode)
  336 {
  337         int node;
  338 
  339         if (strcmp(s->name, "*") == 0)
  340                 return;
  341 
  342         if (!highest_node) {
  343                 printf("\n%s: No NUMA information available.\n", s->name);
  344                 return;
  345         }
  346 
  347         if (skip_zero && !s->slabs)
  348                 return;
  349 
  350         if (!line) {
  351                 printf("\n%-21s:", mode ? "NUMA nodes" : "Slab");
  352                 for(node = 0; node <= highest_node; node++)
  353                         printf(" %4d", node);
  354                 printf("\n----------------------");
  355                 for(node = 0; node <= highest_node; node++)
  356                         printf("-----");
  357                 printf("\n");
  358         }
  359         printf("%-21s ", mode ? "All slabs" : s->name);
  360         for(node = 0; node <= highest_node; node++) {
  361                 char b[20];
  362 
  363                 store_size(b, s->numa[node]);
  364                 printf(" %4s", b);
  365         }
  366         printf("\n");
  367         if (mode) {
  368                 printf("%-21s ", "Partial slabs");
  369                 for(node = 0; node <= highest_node; node++) {
  370                         char b[20];
  371 
  372                         store_size(b, s->numa_partial[node]);
  373                         printf(" %4s", b);
  374                 }
  375                 printf("\n");
  376         }
  377         line++;
  378 }
  379 
  380 static void show_tracking(struct slabinfo *s)
  381 {
  382         printf("\n%s: Kernel object allocation\n", s->name);
  383         printf("-----------------------------------------------------------------------\n");
  384         if (read_slab_obj(s, "alloc_calls"))
  385                 printf("%s", buffer);
  386         else
  387                 printf("No Data\n");
  388 
  389         printf("\n%s: Kernel object freeing\n", s->name);
  390         printf("------------------------------------------------------------------------\n");
  391         if (read_slab_obj(s, "free_calls"))
  392                 printf("%s", buffer);
  393         else
  394                 printf("No Data\n");
  395 
  396 }
  397 
  398 static void ops(struct slabinfo *s)
  399 {
  400         if (strcmp(s->name, "*") == 0)
  401                 return;
  402 
  403         if (read_slab_obj(s, "ops")) {
  404                 printf("\n%s: kmem_cache operations\n", s->name);
  405                 printf("--------------------------------------------\n");
  406                 printf("%s", buffer);
  407         } else
  408                 printf("\n%s has no kmem_cache operations\n", s->name);
  409 }
  410 
  411 static const char *onoff(int x)
  412 {
  413         if (x)
  414                 return "On ";
  415         return "Off";
  416 }
  417 
  418 static void slab_stats(struct slabinfo *s)
  419 {
  420         unsigned long total_alloc;
  421         unsigned long total_free;
  422         unsigned long total;
  423 
  424         if (!s->alloc_slab)
  425                 return;
  426 
  427         total_alloc = s->alloc_fastpath + s->alloc_slowpath;
  428         total_free = s->free_fastpath + s->free_slowpath;
  429 
  430         if (!total_alloc)
  431                 return;
  432 
  433         printf("\n");
  434         printf("Slab Perf Counter       Alloc     Free %%Al %%Fr\n");
  435         printf("--------------------------------------------------\n");
  436         printf("Fastpath             %8lu %8lu %3lu %3lu\n",
  437                 s->alloc_fastpath, s->free_fastpath,
  438                 s->alloc_fastpath * 100 / total_alloc,
  439                 s->free_fastpath * 100 / total_free);
  440         printf("Slowpath             %8lu %8lu %3lu %3lu\n",
  441                 total_alloc - s->alloc_fastpath, s->free_slowpath,
  442                 (total_alloc - s->alloc_fastpath) * 100 / total_alloc,
  443                 s->free_slowpath * 100 / total_free);
  444         printf("Page Alloc           %8lu %8lu %3lu %3lu\n",
  445                 s->alloc_slab, s->free_slab,
  446                 s->alloc_slab * 100 / total_alloc,
  447                 s->free_slab * 100 / total_free);
  448         printf("Add partial          %8lu %8lu %3lu %3lu\n",
  449                 s->deactivate_to_head + s->deactivate_to_tail,
  450                 s->free_add_partial,
  451                 (s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc,
  452                 s->free_add_partial * 100 / total_free);
  453         printf("Remove partial       %8lu %8lu %3lu %3lu\n",
  454                 s->alloc_from_partial, s->free_remove_partial,
  455                 s->alloc_from_partial * 100 / total_alloc,
  456                 s->free_remove_partial * 100 / total_free);
  457 
  458         printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n",
  459                 s->deactivate_remote_frees, s->free_frozen,
  460                 s->deactivate_remote_frees * 100 / total_alloc,
  461                 s->free_frozen * 100 / total_free);
  462 
  463         printf("Total                %8lu %8lu\n\n", total_alloc, total_free);
  464 
  465         if (s->cpuslab_flush)
  466                 printf("Flushes %8lu\n", s->cpuslab_flush);
  467 
  468         total = s->deactivate_full + s->deactivate_empty +
  469                         s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass;
  470 
  471         if (total) {
  472                 printf("\nSlab Deactivation             Ocurrences  %%\n");
  473                 printf("-------------------------------------------------\n");
  474                 printf("Slab full                     %7lu  %3lu%%\n",
  475                         s->deactivate_full, (s->deactivate_full * 100) / total);
  476                 printf("Slab empty                    %7lu  %3lu%%\n",
  477                         s->deactivate_empty, (s->deactivate_empty * 100) / total);
  478                 printf("Moved to head of partial list %7lu  %3lu%%\n",
  479                         s->deactivate_to_head, (s->deactivate_to_head * 100) / total);
  480                 printf("Moved to tail of partial list %7lu  %3lu%%\n",
  481                         s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
  482                 printf("Deactivation bypass           %7lu  %3lu%%\n",
  483                         s->deactivate_bypass, (s->deactivate_bypass * 100) / total);
  484                 printf("Refilled from foreign frees   %7lu  %3lu%%\n",
  485                         s->alloc_refill, (s->alloc_refill * 100) / total);
  486                 printf("Node mismatch                 %7lu  %3lu%%\n",
  487                         s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total);
  488         }
  489 
  490         if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail)
  491                 printf("\nCmpxchg_double Looping\n------------------------\n");
  492                 printf("Locked Cmpxchg Double redos   %lu\nUnlocked Cmpxchg Double redos %lu\n",
  493                         s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail);
  494 }
  495 
  496 static void report(struct slabinfo *s)
  497 {
  498         if (strcmp(s->name, "*") == 0)
  499                 return;
  500 
  501         printf("\nSlabcache: %-20s  Aliases: %2d Order : %2d Objects: %lu\n",
  502                 s->name, s->aliases, s->order, s->objects);
  503         if (s->hwcache_align)
  504                 printf("** Hardware cacheline aligned\n");
  505         if (s->cache_dma)
  506                 printf("** Memory is allocated in a special DMA zone\n");
  507         if (s->destroy_by_rcu)
  508                 printf("** Slabs are destroyed via RCU\n");
  509         if (s->reclaim_account)
  510                 printf("** Reclaim accounting active\n");
  511 
  512         printf("\nSizes (bytes)     Slabs              Debug                Memory\n");
  513         printf("------------------------------------------------------------------------\n");
  514         printf("Object : %7d  Total  : %7ld   Sanity Checks : %s  Total: %7ld\n",
  515                         s->object_size, s->slabs, onoff(s->sanity_checks),
  516                         s->slabs * (page_size << s->order));
  517         printf("SlabObj: %7d  Full   : %7ld   Redzoning     : %s  Used : %7ld\n",
  518                         s->slab_size, s->slabs - s->partial - s->cpu_slabs,
  519                         onoff(s->red_zone), s->objects * s->object_size);
  520         printf("SlabSiz: %7d  Partial: %7ld   Poisoning     : %s  Loss : %7ld\n",
  521                         page_size << s->order, s->partial, onoff(s->poison),
  522                         s->slabs * (page_size << s->order) - s->objects * s->object_size);
  523         printf("Loss   : %7d  CpuSlab: %7d   Tracking      : %s  Lalig: %7ld\n",
  524                         s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user),
  525                         (s->slab_size - s->object_size) * s->objects);
  526         printf("Align  : %7d  Objects: %7d   Tracing       : %s  Lpadd: %7ld\n",
  527                         s->align, s->objs_per_slab, onoff(s->trace),
  528                         ((page_size << s->order) - s->objs_per_slab * s->slab_size) *
  529                         s->slabs);
  530 
  531         ops(s);
  532         show_tracking(s);
  533         slab_numa(s, 1);
  534         slab_stats(s);
  535 }
  536 
  537 static void slabcache(struct slabinfo *s)
  538 {
  539         char size_str[20];
  540         char dist_str[40];
  541         char flags[20];
  542         char *p = flags;
  543 
  544         if (strcmp(s->name, "*") == 0)
  545                 return;
  546 
  547         if (actual_slabs == 1) {
  548                 report(s);
  549                 return;
  550         }
  551 
  552         if (skip_zero && !show_empty && !s->slabs)
  553                 return;
  554 
  555         if (show_empty && s->slabs)
  556                 return;
  557 
  558         store_size(size_str, slab_size(s));
  559         snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
  560                                                 s->partial, s->cpu_slabs);
  561 
  562         if (!line++)
  563                 first_line();
  564 
  565         if (s->aliases)
  566                 *p++ = '*';
  567         if (s->cache_dma)
  568                 *p++ = 'd';
  569         if (s->hwcache_align)
  570                 *p++ = 'A';
  571         if (s->poison)
  572                 *p++ = 'P';
  573         if (s->reclaim_account)
  574                 *p++ = 'a';
  575         if (s->red_zone)
  576                 *p++ = 'Z';
  577         if (s->sanity_checks)
  578                 *p++ = 'F';
  579         if (s->store_user)
  580                 *p++ = 'U';
  581         if (s->trace)
  582                 *p++ = 'T';
  583 
  584         *p = 0;
  585         if (show_activity) {
  586                 unsigned long total_alloc;
  587                 unsigned long total_free;
  588 
  589                 total_alloc = s->alloc_fastpath + s->alloc_slowpath;
  590                 total_free = s->free_fastpath + s->free_slowpath;
  591 
  592                 printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d %4ld %4ld\n",
  593                         s->name, s->objects,
  594                         total_alloc, total_free,
  595                         total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
  596                         total_free ? (s->free_fastpath * 100 / total_free) : 0,
  597                         s->order_fallback, s->order, s->cmpxchg_double_fail,
  598                         s->cmpxchg_double_cpu_fail);
  599         }
  600         else
  601                 printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
  602                         s->name, s->objects, s->object_size, size_str, dist_str,
  603                         s->objs_per_slab, s->order,
  604                         s->slabs ? (s->partial * 100) / s->slabs : 100,
  605                         s->slabs ? (s->objects * s->object_size * 100) /
  606                                 (s->slabs * (page_size << s->order)) : 100,
  607                         flags);
  608 }
  609 
  610 /*
  611  * Analyze debug options. Return false if something is amiss.
  612  */
  613 static int debug_opt_scan(char *opt)
  614 {
  615         if (!opt || !opt[0] || strcmp(opt, "-") == 0)
  616                 return 1;
  617 
  618         if (strcasecmp(opt, "a") == 0) {
  619                 sanity = 1;
  620                 poison = 1;
  621                 redzone = 1;
  622                 tracking = 1;
  623                 return 1;
  624         }
  625 
  626         for ( ; *opt; opt++)
  627                 switch (*opt) {
  628                 case 'F' : case 'f':
  629                         if (sanity)
  630                                 return 0;
  631                         sanity = 1;
  632                         break;
  633                 case 'P' : case 'p':
  634                         if (poison)
  635                                 return 0;
  636                         poison = 1;
  637                         break;
  638 
  639                 case 'Z' : case 'z':
  640                         if (redzone)
  641                                 return 0;
  642                         redzone = 1;
  643                         break;
  644 
  645                 case 'U' : case 'u':
  646                         if (tracking)
  647                                 return 0;
  648                         tracking = 1;
  649                         break;
  650 
  651                 case 'T' : case 't':
  652                         if (tracing)
  653                                 return 0;
  654                         tracing = 1;
  655                         break;
  656                 default:
  657                         return 0;
  658                 }
  659         return 1;
  660 }
  661 
  662 static int slab_empty(struct slabinfo *s)
  663 {
  664         if (s->objects > 0)
  665                 return 0;
  666 
  667         /*
  668          * We may still have slabs even if there are no objects. Shrinking will
  669          * remove them.
  670          */
  671         if (s->slabs != 0)
  672                 set_obj(s, "shrink", 1);
  673 
  674         return 1;
  675 }
  676 
  677 static void slab_debug(struct slabinfo *s)
  678 {
  679         if (strcmp(s->name, "*") == 0)
  680                 return;
  681 
  682         if (sanity && !s->sanity_checks) {
  683                 set_obj(s, "sanity", 1);
  684         }
  685         if (!sanity && s->sanity_checks) {
  686                 if (slab_empty(s))
  687                         set_obj(s, "sanity", 0);
  688                 else
  689                         fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name);
  690         }
  691         if (redzone && !s->red_zone) {
  692                 if (slab_empty(s))
  693                         set_obj(s, "red_zone", 1);
  694                 else
  695                         fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name);
  696         }
  697         if (!redzone && s->red_zone) {
  698                 if (slab_empty(s))
  699                         set_obj(s, "red_zone", 0);
  700                 else
  701                         fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name);
  702         }
  703         if (poison && !s->poison) {
  704                 if (slab_empty(s))
  705                         set_obj(s, "poison", 1);
  706                 else
  707                         fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name);
  708         }
  709         if (!poison && s->poison) {
  710                 if (slab_empty(s))
  711                         set_obj(s, "poison", 0);
  712                 else
  713                         fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name);
  714         }
  715         if (tracking && !s->store_user) {
  716                 if (slab_empty(s))
  717                         set_obj(s, "store_user", 1);
  718                 else
  719                         fprintf(stderr, "%s not empty cannot enable tracking\n", s->name);
  720         }
  721         if (!tracking && s->store_user) {
  722                 if (slab_empty(s))
  723                         set_obj(s, "store_user", 0);
  724                 else
  725                         fprintf(stderr, "%s not empty cannot disable tracking\n", s->name);
  726         }
  727         if (tracing && !s->trace) {
  728                 if (slabs == 1)
  729                         set_obj(s, "trace", 1);
  730                 else
  731                         fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name);
  732         }
  733         if (!tracing && s->trace)
  734                 set_obj(s, "trace", 1);
  735 }
  736 
  737 static void totals(void)
  738 {
  739         struct slabinfo *s;
  740 
  741         int used_slabs = 0;
  742         char b1[20], b2[20], b3[20], b4[20];
  743         unsigned long long max = 1ULL << 63;
  744 
  745         /* Object size */
  746         unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
  747 
  748         /* Number of partial slabs in a slabcache */
  749         unsigned long long min_partial = max, max_partial = 0,
  750                                 avg_partial, total_partial = 0;
  751 
  752         /* Number of slabs in a slab cache */
  753         unsigned long long min_slabs = max, max_slabs = 0,
  754                                 avg_slabs, total_slabs = 0;
  755 
  756         /* Size of the whole slab */
  757         unsigned long long min_size = max, max_size = 0,
  758                                 avg_size, total_size = 0;
  759 
  760         /* Bytes used for object storage in a slab */
  761         unsigned long long min_used = max, max_used = 0,
  762                                 avg_used, total_used = 0;
  763 
  764         /* Waste: Bytes used for alignment and padding */
  765         unsigned long long min_waste = max, max_waste = 0,
  766                                 avg_waste, total_waste = 0;
  767         /* Number of objects in a slab */
  768         unsigned long long min_objects = max, max_objects = 0,
  769                                 avg_objects, total_objects = 0;
  770         /* Waste per object */
  771         unsigned long long min_objwaste = max,
  772                                 max_objwaste = 0, avg_objwaste,
  773                                 total_objwaste = 0;
  774 
  775         /* Memory per object */
  776         unsigned long long min_memobj = max,
  777                                 max_memobj = 0, avg_memobj,
  778                                 total_objsize = 0;
  779 
  780         /* Percentage of partial slabs per slab */
  781         unsigned long min_ppart = 100, max_ppart = 0,
  782                                 avg_ppart, total_ppart = 0;
  783 
  784         /* Number of objects in partial slabs */
  785         unsigned long min_partobj = max, max_partobj = 0,
  786                                 avg_partobj, total_partobj = 0;
  787 
  788         /* Percentage of partial objects of all objects in a slab */
  789         unsigned long min_ppartobj = 100, max_ppartobj = 0,
  790                                 avg_ppartobj, total_ppartobj = 0;
  791 
  792 
  793         for (s = slabinfo; s < slabinfo + slabs; s++) {
  794                 unsigned long long size;
  795                 unsigned long used;
  796                 unsigned long long wasted;
  797                 unsigned long long objwaste;
  798                 unsigned long percentage_partial_slabs;
  799                 unsigned long percentage_partial_objs;
  800 
  801                 if (!s->slabs || !s->objects)
  802                         continue;
  803 
  804                 used_slabs++;
  805 
  806                 size = slab_size(s);
  807                 used = s->objects * s->object_size;
  808                 wasted = size - used;
  809                 objwaste = s->slab_size - s->object_size;
  810 
  811                 percentage_partial_slabs = s->partial * 100 / s->slabs;
  812                 if (percentage_partial_slabs > 100)
  813                         percentage_partial_slabs = 100;
  814 
  815                 percentage_partial_objs = s->objects_partial * 100
  816                                                         / s->objects;
  817 
  818                 if (percentage_partial_objs > 100)
  819                         percentage_partial_objs = 100;
  820 
  821                 if (s->object_size < min_objsize)
  822                         min_objsize = s->object_size;
  823                 if (s->partial < min_partial)
  824                         min_partial = s->partial;
  825                 if (s->slabs < min_slabs)
  826                         min_slabs = s->slabs;
  827                 if (size < min_size)
  828                         min_size = size;
  829                 if (wasted < min_waste)
  830                         min_waste = wasted;
  831                 if (objwaste < min_objwaste)
  832                         min_objwaste = objwaste;
  833                 if (s->objects < min_objects)
  834                         min_objects = s->objects;
  835                 if (used < min_used)
  836                         min_used = used;
  837                 if (s->objects_partial < min_partobj)
  838                         min_partobj = s->objects_partial;
  839                 if (percentage_partial_slabs < min_ppart)
  840                         min_ppart = percentage_partial_slabs;
  841                 if (percentage_partial_objs < min_ppartobj)
  842                         min_ppartobj = percentage_partial_objs;
  843                 if (s->slab_size < min_memobj)
  844                         min_memobj = s->slab_size;
  845 
  846                 if (s->object_size > max_objsize)
  847                         max_objsize = s->object_size;
  848                 if (s->partial > max_partial)
  849                         max_partial = s->partial;
  850                 if (s->slabs > max_slabs)
  851                         max_slabs = s->slabs;
  852                 if (size > max_size)
  853                         max_size = size;
  854                 if (wasted > max_waste)
  855                         max_waste = wasted;
  856                 if (objwaste > max_objwaste)
  857                         max_objwaste = objwaste;
  858                 if (s->objects > max_objects)
  859                         max_objects = s->objects;
  860                 if (used > max_used)
  861                         max_used = used;
  862                 if (s->objects_partial > max_partobj)
  863                         max_partobj = s->objects_partial;
  864                 if (percentage_partial_slabs > max_ppart)
  865                         max_ppart = percentage_partial_slabs;
  866                 if (percentage_partial_objs > max_ppartobj)
  867                         max_ppartobj = percentage_partial_objs;
  868                 if (s->slab_size > max_memobj)
  869                         max_memobj = s->slab_size;
  870 
  871                 total_partial += s->partial;
  872                 total_slabs += s->slabs;
  873                 total_size += size;
  874                 total_waste += wasted;
  875 
  876                 total_objects += s->objects;
  877                 total_used += used;
  878                 total_partobj += s->objects_partial;
  879                 total_ppart += percentage_partial_slabs;
  880                 total_ppartobj += percentage_partial_objs;
  881 
  882                 total_objwaste += s->objects * objwaste;
  883                 total_objsize += s->objects * s->slab_size;
  884         }
  885 
  886         if (!total_objects) {
  887                 printf("No objects\n");
  888                 return;
  889         }
  890         if (!used_slabs) {
  891                 printf("No slabs\n");
  892                 return;
  893         }
  894 
  895         /* Per slab averages */
  896         avg_partial = total_partial / used_slabs;
  897         avg_slabs = total_slabs / used_slabs;
  898         avg_size = total_size / used_slabs;
  899         avg_waste = total_waste / used_slabs;
  900 
  901         avg_objects = total_objects / used_slabs;
  902         avg_used = total_used / used_slabs;
  903         avg_partobj = total_partobj / used_slabs;
  904         avg_ppart = total_ppart / used_slabs;
  905         avg_ppartobj = total_ppartobj / used_slabs;
  906 
  907         /* Per object object sizes */
  908         avg_objsize = total_used / total_objects;
  909         avg_objwaste = total_objwaste / total_objects;
  910         avg_partobj = total_partobj * 100 / total_objects;
  911         avg_memobj = total_objsize / total_objects;
  912 
  913         printf("Slabcache Totals\n");
  914         printf("----------------\n");
  915         printf("Slabcaches : %3d      Aliases  : %3d->%-3d Active: %3d\n",
  916                         slabs, aliases, alias_targets, used_slabs);
  917 
  918         store_size(b1, total_size);store_size(b2, total_waste);
  919         store_size(b3, total_waste * 100 / total_used);
  920         printf("Memory used: %6s   # Loss   : %6s   MRatio:%6s%%\n", b1, b2, b3);
  921 
  922         store_size(b1, total_objects);store_size(b2, total_partobj);
  923         store_size(b3, total_partobj * 100 / total_objects);
  924         printf("# Objects  : %6s   # PartObj: %6s   ORatio:%6s%%\n", b1, b2, b3);
  925 
  926         printf("\n");
  927         printf("Per Cache    Average         Min         Max       Total\n");
  928         printf("---------------------------------------------------------\n");
  929 
  930         store_size(b1, avg_objects);store_size(b2, min_objects);
  931         store_size(b3, max_objects);store_size(b4, total_objects);
  932         printf("#Objects  %10s  %10s  %10s  %10s\n",
  933                         b1,     b2,     b3,     b4);
  934 
  935         store_size(b1, avg_slabs);store_size(b2, min_slabs);
  936         store_size(b3, max_slabs);store_size(b4, total_slabs);
  937         printf("#Slabs    %10s  %10s  %10s  %10s\n",
  938                         b1,     b2,     b3,     b4);
  939 
  940         store_size(b1, avg_partial);store_size(b2, min_partial);
  941         store_size(b3, max_partial);store_size(b4, total_partial);
  942         printf("#PartSlab %10s  %10s  %10s  %10s\n",
  943                         b1,     b2,     b3,     b4);
  944         store_size(b1, avg_ppart);store_size(b2, min_ppart);
  945         store_size(b3, max_ppart);
  946         store_size(b4, total_partial * 100  / total_slabs);
  947         printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%\n",
  948                         b1,     b2,     b3,     b4);
  949 
  950         store_size(b1, avg_partobj);store_size(b2, min_partobj);
  951         store_size(b3, max_partobj);
  952         store_size(b4, total_partobj);
  953         printf("PartObjs  %10s  %10s  %10s  %10s\n",
  954                         b1,     b2,     b3,     b4);
  955 
  956         store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
  957         store_size(b3, max_ppartobj);
  958         store_size(b4, total_partobj * 100 / total_objects);
  959         printf("%% PartObj%10s%% %10s%% %10s%% %10s%%\n",
  960                         b1,     b2,     b3,     b4);
  961 
  962         store_size(b1, avg_size);store_size(b2, min_size);
  963         store_size(b3, max_size);store_size(b4, total_size);
  964         printf("Memory    %10s  %10s  %10s  %10s\n",
  965                         b1,     b2,     b3,     b4);
  966 
  967         store_size(b1, avg_used);store_size(b2, min_used);
  968         store_size(b3, max_used);store_size(b4, total_used);
  969         printf("Used      %10s  %10s  %10s  %10s\n",
  970                         b1,     b2,     b3,     b4);
  971 
  972         store_size(b1, avg_waste);store_size(b2, min_waste);
  973         store_size(b3, max_waste);store_size(b4, total_waste);
  974         printf("Loss      %10s  %10s  %10s  %10s\n",
  975                         b1,     b2,     b3,     b4);
  976 
  977         printf("\n");
  978         printf("Per Object   Average         Min         Max\n");
  979         printf("---------------------------------------------\n");
  980 
  981         store_size(b1, avg_memobj);store_size(b2, min_memobj);
  982         store_size(b3, max_memobj);
  983         printf("Memory    %10s  %10s  %10s\n",
  984                         b1,     b2,     b3);
  985         store_size(b1, avg_objsize);store_size(b2, min_objsize);
  986         store_size(b3, max_objsize);
  987         printf("User      %10s  %10s  %10s\n",
  988                         b1,     b2,     b3);
  989 
  990         store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
  991         store_size(b3, max_objwaste);
  992         printf("Loss      %10s  %10s  %10s\n",
  993                         b1,     b2,     b3);
  994 }
  995 
  996 static void sort_slabs(void)
  997 {
  998         struct slabinfo *s1,*s2;
  999 
 1000         for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
 1001                 for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
 1002                         int result;
 1003 
 1004                         if (sort_size)
 1005                                 result = slab_size(s1) < slab_size(s2);
 1006                         else if (sort_active)
 1007                                 result = slab_activity(s1) < slab_activity(s2);
 1008                         else
 1009                                 result = strcasecmp(s1->name, s2->name);
 1010 
 1011                         if (show_inverted)
 1012                                 result = -result;
 1013 
 1014                         if (result > 0) {
 1015                                 struct slabinfo t;
 1016 
 1017                                 memcpy(&t, s1, sizeof(struct slabinfo));
 1018                                 memcpy(s1, s2, sizeof(struct slabinfo));
 1019                                 memcpy(s2, &t, sizeof(struct slabinfo));
 1020                         }
 1021                 }
 1022         }
 1023 }
 1024 
 1025 static void sort_aliases(void)
 1026 {
 1027         struct aliasinfo *a1,*a2;
 1028 
 1029         for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) {
 1030                 for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) {
 1031                         char *n1, *n2;
 1032 
 1033                         n1 = a1->name;
 1034                         n2 = a2->name;
 1035                         if (show_alias && !show_inverted) {
 1036                                 n1 = a1->ref;
 1037                                 n2 = a2->ref;
 1038                         }
 1039                         if (strcasecmp(n1, n2) > 0) {
 1040                                 struct aliasinfo t;
 1041 
 1042                                 memcpy(&t, a1, sizeof(struct aliasinfo));
 1043                                 memcpy(a1, a2, sizeof(struct aliasinfo));
 1044                                 memcpy(a2, &t, sizeof(struct aliasinfo));
 1045                         }
 1046                 }
 1047         }
 1048 }
 1049 
 1050 static void link_slabs(void)
 1051 {
 1052         struct aliasinfo *a;
 1053         struct slabinfo *s;
 1054 
 1055         for (a = aliasinfo; a < aliasinfo + aliases; a++) {
 1056 
 1057                 for (s = slabinfo; s < slabinfo + slabs; s++)
 1058                         if (strcmp(a->ref, s->name) == 0) {
 1059                                 a->slab = s;
 1060                                 s->refs++;
 1061                                 break;
 1062                         }
 1063                 if (s == slabinfo + slabs)
 1064                         fatal("Unresolved alias %s\n", a->ref);
 1065         }
 1066 }
 1067 
 1068 static void alias(void)
 1069 {
 1070         struct aliasinfo *a;
 1071         char *active = NULL;
 1072 
 1073         sort_aliases();
 1074         link_slabs();
 1075 
 1076         for(a = aliasinfo; a < aliasinfo + aliases; a++) {
 1077 
 1078                 if (!show_single_ref && a->slab->refs == 1)
 1079                         continue;
 1080 
 1081                 if (!show_inverted) {
 1082                         if (active) {
 1083                                 if (strcmp(a->slab->name, active) == 0) {
 1084                                         printf(" %s", a->name);
 1085                                         continue;
 1086                                 }
 1087                         }
 1088                         printf("\n%-12s <- %s", a->slab->name, a->name);
 1089                         active = a->slab->name;
 1090                 }
 1091                 else
 1092                         printf("%-20s -> %s\n", a->name, a->slab->name);
 1093         }
 1094         if (active)
 1095                 printf("\n");
 1096 }
 1097 
 1098 
 1099 static void rename_slabs(void)
 1100 {
 1101         struct slabinfo *s;
 1102         struct aliasinfo *a;
 1103 
 1104         for (s = slabinfo; s < slabinfo + slabs; s++) {
 1105                 if (*s->name != ':')
 1106                         continue;
 1107 
 1108                 if (s->refs > 1 && !show_first_alias)
 1109                         continue;
 1110 
 1111                 a = find_one_alias(s);
 1112 
 1113                 if (a)
 1114                         s->name = a->name;
 1115                 else {
 1116                         s->name = "*";
 1117                         actual_slabs--;
 1118                 }
 1119         }
 1120 }
 1121 
 1122 static int slab_mismatch(char *slab)
 1123 {
 1124         return regexec(&pattern, slab, 0, NULL, 0);
 1125 }
 1126 
 1127 static void read_slab_dir(void)
 1128 {
 1129         DIR *dir;
 1130         struct dirent *de;
 1131         struct slabinfo *slab = slabinfo;
 1132         struct aliasinfo *alias = aliasinfo;
 1133         char *p;
 1134         char *t;
 1135         int count;
 1136 
 1137         if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
 1138                 fatal("SYSFS support for SLUB not active\n");
 1139 
 1140         dir = opendir(".");
 1141         while ((de = readdir(dir))) {
 1142                 if (de->d_name[0] == '.' ||
 1143                         (de->d_name[0] != ':' && slab_mismatch(de->d_name)))
 1144                                 continue;
 1145                 switch (de->d_type) {
 1146                    case DT_LNK:
 1147                         alias->name = strdup(de->d_name);
 1148                         count = readlink(de->d_name, buffer, sizeof(buffer));
 1149 
 1150                         if (count < 0)
 1151                                 fatal("Cannot read symlink %s\n", de->d_name);
 1152 
 1153                         buffer[count] = 0;
 1154                         p = buffer + count;
 1155                         while (p > buffer && p[-1] != '/')
 1156                                 p--;
 1157                         alias->ref = strdup(p);
 1158                         alias++;
 1159                         break;
 1160                    case DT_DIR:
 1161                         if (chdir(de->d_name))
 1162                                 fatal("Unable to access slab %s\n", slab->name);
 1163                         slab->name = strdup(de->d_name);
 1164                         slab->alias = 0;
 1165                         slab->refs = 0;
 1166                         slab->aliases = get_obj("aliases");
 1167                         slab->align = get_obj("align");
 1168                         slab->cache_dma = get_obj("cache_dma");
 1169                         slab->cpu_slabs = get_obj("cpu_slabs");
 1170                         slab->destroy_by_rcu = get_obj("destroy_by_rcu");
 1171                         slab->hwcache_align = get_obj("hwcache_align");
 1172                         slab->object_size = get_obj("object_size");
 1173                         slab->objects = get_obj("objects");
 1174                         slab->objects_partial = get_obj("objects_partial");
 1175                         slab->objects_total = get_obj("objects_total");
 1176                         slab->objs_per_slab = get_obj("objs_per_slab");
 1177                         slab->order = get_obj("order");
 1178                         slab->partial = get_obj("partial");
 1179                         slab->partial = get_obj_and_str("partial", &t);
 1180                         decode_numa_list(slab->numa_partial, t);
 1181                         free(t);
 1182                         slab->poison = get_obj("poison");
 1183                         slab->reclaim_account = get_obj("reclaim_account");
 1184                         slab->red_zone = get_obj("red_zone");
 1185                         slab->sanity_checks = get_obj("sanity_checks");
 1186                         slab->slab_size = get_obj("slab_size");
 1187                         slab->slabs = get_obj_and_str("slabs", &t);
 1188                         decode_numa_list(slab->numa, t);
 1189                         free(t);
 1190                         slab->store_user = get_obj("store_user");
 1191                         slab->trace = get_obj("trace");
 1192                         slab->alloc_fastpath = get_obj("alloc_fastpath");
 1193                         slab->alloc_slowpath = get_obj("alloc_slowpath");
 1194                         slab->free_fastpath = get_obj("free_fastpath");
 1195                         slab->free_slowpath = get_obj("free_slowpath");
 1196                         slab->free_frozen= get_obj("free_frozen");
 1197                         slab->free_add_partial = get_obj("free_add_partial");
 1198                         slab->free_remove_partial = get_obj("free_remove_partial");
 1199                         slab->alloc_from_partial = get_obj("alloc_from_partial");
 1200                         slab->alloc_slab = get_obj("alloc_slab");
 1201                         slab->alloc_refill = get_obj("alloc_refill");
 1202                         slab->free_slab = get_obj("free_slab");
 1203                         slab->cpuslab_flush = get_obj("cpuslab_flush");
 1204                         slab->deactivate_full = get_obj("deactivate_full");
 1205                         slab->deactivate_empty = get_obj("deactivate_empty");
 1206                         slab->deactivate_to_head = get_obj("deactivate_to_head");
 1207                         slab->deactivate_to_tail = get_obj("deactivate_to_tail");
 1208                         slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
 1209                         slab->order_fallback = get_obj("order_fallback");
 1210                         slab->cmpxchg_double_cpu_fail = get_obj("cmpxchg_double_cpu_fail");
 1211                         slab->cmpxchg_double_fail = get_obj("cmpxchg_double_fail");
 1212                         slab->alloc_node_mismatch = get_obj("alloc_node_mismatch");
 1213                         slab->deactivate_bypass = get_obj("deactivate_bypass");
 1214                         chdir("..");
 1215                         if (slab->name[0] == ':')
 1216                                 alias_targets++;
 1217                         slab++;
 1218                         break;
 1219                    default :
 1220                         fatal("Unknown file type %lx\n", de->d_type);
 1221                 }
 1222         }
 1223         closedir(dir);
 1224         slabs = slab - slabinfo;
 1225         actual_slabs = slabs;
 1226         aliases = alias - aliasinfo;
 1227         if (slabs > MAX_SLABS)
 1228                 fatal("Too many slabs\n");
 1229         if (aliases > MAX_ALIASES)
 1230                 fatal("Too many aliases\n");
 1231 }
 1232 
 1233 static void output_slabs(void)
 1234 {
 1235         struct slabinfo *slab;
 1236 
 1237         for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
 1238 
 1239                 if (slab->alias)
 1240                         continue;
 1241 
 1242 
 1243                 if (show_numa)
 1244                         slab_numa(slab, 0);
 1245                 else if (show_track)
 1246                         show_tracking(slab);
 1247                 else if (validate)
 1248                         slab_validate(slab);
 1249                 else if (shrink)
 1250                         slab_shrink(slab);
 1251                 else if (set_debug)
 1252                         slab_debug(slab);
 1253                 else if (show_ops)
 1254                         ops(slab);
 1255                 else if (show_slab)
 1256                         slabcache(slab);
 1257                 else if (show_report)
 1258                         report(slab);
 1259         }
 1260 }
 1261 
 1262 struct option opts[] = {
 1263         { "aliases", 0, NULL, 'a' },
 1264         { "activity", 0, NULL, 'A' },
 1265         { "debug", 2, NULL, 'd' },
 1266         { "display-activity", 0, NULL, 'D' },
 1267         { "empty", 0, NULL, 'e' },
 1268         { "first-alias", 0, NULL, 'f' },
 1269         { "help", 0, NULL, 'h' },
 1270         { "inverted", 0, NULL, 'i'},
 1271         { "numa", 0, NULL, 'n' },
 1272         { "ops", 0, NULL, 'o' },
 1273         { "report", 0, NULL, 'r' },
 1274         { "shrink", 0, NULL, 's' },
 1275         { "slabs", 0, NULL, 'l' },
 1276         { "track", 0, NULL, 't'},
 1277         { "validate", 0, NULL, 'v' },
 1278         { "zero", 0, NULL, 'z' },
 1279         { "1ref", 0, NULL, '1'},
 1280         { NULL, 0, NULL, 0 }
 1281 };
 1282 
 1283 int main(int argc, char *argv[])
 1284 {
 1285         int c;
 1286         int err;
 1287         char *pattern_source;
 1288 
 1289         page_size = getpagesize();
 1290 
 1291         while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
 1292                                                 opts, NULL)) != -1)
 1293                 switch (c) {
 1294                 case '1':
 1295                         show_single_ref = 1;
 1296                         break;
 1297                 case 'a':
 1298                         show_alias = 1;
 1299                         break;
 1300                 case 'A':
 1301                         sort_active = 1;
 1302                         break;
 1303                 case 'd':
 1304                         set_debug = 1;
 1305                         if (!debug_opt_scan(optarg))
 1306                                 fatal("Invalid debug option '%s'\n", optarg);
 1307                         break;
 1308                 case 'D':
 1309                         show_activity = 1;
 1310                         break;
 1311                 case 'e':
 1312                         show_empty = 1;
 1313                         break;
 1314                 case 'f':
 1315                         show_first_alias = 1;
 1316                         break;
 1317                 case 'h':
 1318                         usage();
 1319                         return 0;
 1320                 case 'i':
 1321                         show_inverted = 1;
 1322                         break;
 1323                 case 'n':
 1324                         show_numa = 1;
 1325                         break;
 1326                 case 'o':
 1327                         show_ops = 1;
 1328                         break;
 1329                 case 'r':
 1330                         show_report = 1;
 1331                         break;
 1332                 case 's':
 1333                         shrink = 1;
 1334                         break;
 1335                 case 'l':
 1336                         show_slab = 1;
 1337                         break;
 1338                 case 't':
 1339                         show_track = 1;
 1340                         break;
 1341                 case 'v':
 1342                         validate = 1;
 1343                         break;
 1344                 case 'z':
 1345                         skip_zero = 0;
 1346                         break;
 1347                 case 'T':
 1348                         show_totals = 1;
 1349                         break;
 1350                 case 'S':
 1351                         sort_size = 1;
 1352                         break;
 1353 
 1354                 default:
 1355                         fatal("%s: Invalid option '%c'\n", argv[0], optopt);
 1356 
 1357         }
 1358 
 1359         if (!show_slab && !show_alias && !show_track && !show_report
 1360                 && !validate && !shrink && !set_debug && !show_ops)
 1361                         show_slab = 1;
 1362 
 1363         if (argc > optind)
 1364                 pattern_source = argv[optind];
 1365         else
 1366                 pattern_source = ".*";
 1367 
 1368         err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
 1369         if (err)
 1370                 fatal("%s: Invalid pattern '%s' code %d\n",
 1371                         argv[0], pattern_source, err);
 1372         read_slab_dir();
 1373         if (show_alias)
 1374                 alias();
 1375         else
 1376         if (show_totals)
 1377                 totals();
 1378         else {
 1379                 link_slabs();
 1380                 rename_slabs();
 1381                 sort_slabs();
 1382                 output_slabs();
 1383         }
 1384         return 0;
 1385 }

Cache object: 5c6fb3df26b7c840fc8cc9c807d04341


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.