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