Blame view

tools/slub/slabinfo.c 33.7 KB
c09d87517   Christoph Lameter   slub: add slabinf...
1
2
3
  /*
   * Slabinfo: Tool to get reports about slabs
   *
cde535359   Christoph Lameter   Christoph has moved
4
   * (C) 2007 sgi, Christoph Lameter
9da4714a2   Christoph Lameter   slub: slabinfo up...
5
   * (C) 2011 Linux Foundation, Christoph Lameter
c09d87517   Christoph Lameter   slub: add slabinf...
6
   *
9da4714a2   Christoph Lameter   slub: slabinfo up...
7
   * Compile with:
c09d87517   Christoph Lameter   slub: add slabinf...
8
9
10
11
12
13
14
   *
   * gcc -o slabinfo slabinfo.c
   */
  #include <stdio.h>
  #include <stdlib.h>
  #include <sys/types.h>
  #include <dirent.h>
f32143a2f   WANG Cong   Documentation/vm/...
15
  #include <strings.h>
c09d87517   Christoph Lameter   slub: add slabinf...
16
17
18
19
20
  #include <string.h>
  #include <unistd.h>
  #include <stdarg.h>
  #include <getopt.h>
  #include <regex.h>
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
21
  #include <errno.h>
c09d87517   Christoph Lameter   slub: add slabinf...
22
23
24
25
26
27
28
29
30
31
32
33
34
  
  #define MAX_SLABS 500
  #define MAX_ALIASES 500
  #define MAX_NODES 1024
  
  struct slabinfo {
  	char *name;
  	int alias;
  	int refs;
  	int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
  	int hwcache_align, object_size, objs_per_slab;
  	int sanity_checks, slab_size, store_user, trace;
  	int order, poison, reclaim_account, red_zone;
205ab99dd   Christoph Lameter   slub: Update stat...
35
  	unsigned long partial, objects, slabs, objects_partial, objects_total;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
36
37
38
39
40
41
  	unsigned long alloc_fastpath, alloc_slowpath;
  	unsigned long free_fastpath, free_slowpath;
  	unsigned long free_frozen, free_add_partial, free_remove_partial;
  	unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill;
  	unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
  	unsigned long deactivate_to_head, deactivate_to_tail;
f715e6f15   Christoph Lameter   slabinfo: Support...
42
  	unsigned long deactivate_remote_frees, order_fallback;
9da4714a2   Christoph Lameter   slub: slabinfo up...
43
44
  	unsigned long cmpxchg_double_cpu_fail, cmpxchg_double_fail;
  	unsigned long alloc_node_mismatch, deactivate_bypass;
c09d87517   Christoph Lameter   slub: add slabinf...
45
46
47
48
49
50
51
52
53
54
55
  	int numa[MAX_NODES];
  	int numa_partial[MAX_NODES];
  } slabinfo[MAX_SLABS];
  
  struct aliasinfo {
  	char *name;
  	char *ref;
  	struct slabinfo *slab;
  } aliasinfo[MAX_ALIASES];
  
  int slabs = 0;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
56
  int actual_slabs = 0;
c09d87517   Christoph Lameter   slub: add slabinf...
57
58
59
60
61
  int aliases = 0;
  int alias_targets = 0;
  int highest_node = 0;
  
  char buffer[4096];
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
62
63
  int show_empty = 0;
  int show_report = 0;
c09d87517   Christoph Lameter   slub: add slabinf...
64
65
66
67
68
69
70
71
72
73
74
75
  int show_alias = 0;
  int show_slab = 0;
  int skip_zero = 1;
  int show_numa = 0;
  int show_track = 0;
  int show_first_alias = 0;
  int validate = 0;
  int shrink = 0;
  int show_inverted = 0;
  int show_single_ref = 0;
  int show_totals = 0;
  int sort_size = 0;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
76
  int sort_active = 0;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
77
78
  int set_debug = 0;
  int show_ops = 0;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
79
  int show_activity = 0;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
80
81
82
83
84
85
86
  
  /* Debug options */
  int sanity = 0;
  int redzone = 0;
  int poison = 0;
  int tracking = 0;
  int tracing = 0;
c09d87517   Christoph Lameter   slub: add slabinf...
87
88
89
90
  
  int page_size;
  
  regex_t pattern;
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
91
  static void fatal(const char *x, ...)
c09d87517   Christoph Lameter   slub: add slabinf...
92
93
94
95
96
97
  {
  	va_list ap;
  
  	va_start(ap, x);
  	vfprintf(stderr, x, ap);
  	va_end(ap);
f32143a2f   WANG Cong   Documentation/vm/...
98
  	exit(EXIT_FAILURE);
c09d87517   Christoph Lameter   slub: add slabinf...
99
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
100
  static void usage(void)
c09d87517   Christoph Lameter   slub: add slabinf...
101
  {
9da4714a2   Christoph Lameter   slub: slabinfo up...
102
103
104
  	printf("slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.
  
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
105
106
  		"slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]
  "
c09d87517   Christoph Lameter   slub: add slabinf...
107
108
  		"-a|--aliases           Show aliases
  "
8ff12cfc0   Christoph Lameter   SLUB: Support for...
109
110
  		"-A|--activity          Most active slabs first
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
111
112
  		"-d<options>|--debug=<options> Set/Clear Debug options
  "
8ff12cfc0   Christoph Lameter   SLUB: Support for...
113
114
115
116
  		"-D|--display-active    Switch line format to activity
  "
  		"-e|--empty             Show empty slabs
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
117
118
  		"-f|--first-alias       Show first alias
  "
c09d87517   Christoph Lameter   slub: add slabinf...
119
120
  		"-h|--help              Show usage information
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
121
122
123
124
  		"-i|--inverted          Inverted list
  "
  		"-l|--slabs             Show slabs
  "
c09d87517   Christoph Lameter   slub: add slabinf...
125
126
  		"-n|--numa              Show NUMA information
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
127
128
  		"-o|--ops		Show kmem_cache_ops
  "
c09d87517   Christoph Lameter   slub: add slabinf...
129
130
  		"-s|--shrink            Shrink slabs
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
131
132
133
134
  		"-r|--report		Detailed report on single slabs
  "
  		"-S|--Size              Sort by size
  "
c09d87517   Christoph Lameter   slub: add slabinf...
135
136
137
138
  		"-t|--tracking          Show alloc/free information
  "
  		"-T|--Totals            Show summary information
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
139
140
  		"-v|--validate          Validate slabs
  "
c09d87517   Christoph Lameter   slub: add slabinf...
141
142
  		"-z|--zero              Include empty slabs
  "
c09d87517   Christoph Lameter   slub: add slabinf...
143
144
  		"-1|--1ref              Single reference
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  		"
  Valid debug options (FZPUT may be combined)
  "
  		"a / A          Switch on all debug options (=FZUP)
  "
  		"-              Switch off all debug options
  "
  		"f / F          Sanity Checks (SLAB_DEBUG_FREE)
  "
  		"z / Z          Redzoning
  "
  		"p / P          Poisoning
  "
  		"u / U          Tracking
  "
  		"t / T          Tracing
  "
c09d87517   Christoph Lameter   slub: add slabinf...
162
163
  	);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
164
  static unsigned long read_obj(const char *name)
c09d87517   Christoph Lameter   slub: add slabinf...
165
166
167
168
169
170
  {
  	FILE *f = fopen(name, "r");
  
  	if (!f)
  		buffer[0] = 0;
  	else {
f32143a2f   WANG Cong   Documentation/vm/...
171
  		if (!fgets(buffer, sizeof(buffer), f))
c09d87517   Christoph Lameter   slub: add slabinf...
172
173
174
175
176
177
178
179
180
181
182
183
184
  			buffer[0] = 0;
  		fclose(f);
  		if (buffer[strlen(buffer)] == '
  ')
  			buffer[strlen(buffer)] = 0;
  	}
  	return strlen(buffer);
  }
  
  
  /*
   * Get the contents of an attribute
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
185
  static unsigned long get_obj(const char *name)
c09d87517   Christoph Lameter   slub: add slabinf...
186
187
188
189
190
191
  {
  	if (!read_obj(name))
  		return 0;
  
  	return atol(buffer);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
192
  static unsigned long get_obj_and_str(const char *name, char **x)
c09d87517   Christoph Lameter   slub: add slabinf...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  {
  	unsigned long result = 0;
  	char *p;
  
  	*x = NULL;
  
  	if (!read_obj(name)) {
  		x = NULL;
  		return 0;
  	}
  	result = strtoul(buffer, &p, 10);
  	while (*p == ' ')
  		p++;
  	if (*p)
  		*x = strdup(p);
  	return result;
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
210
  static void set_obj(struct slabinfo *s, const char *name, int n)
c09d87517   Christoph Lameter   slub: add slabinf...
211
212
  {
  	char x[100];
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
213
  	FILE *f;
c09d87517   Christoph Lameter   slub: add slabinf...
214

f32143a2f   WANG Cong   Documentation/vm/...
215
  	snprintf(x, 100, "%s/%s", s->name, name);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
216
  	f = fopen(x, "w");
c09d87517   Christoph Lameter   slub: add slabinf...
217
218
219
220
221
222
223
224
  	if (!f)
  		fatal("Cannot write to %s
  ", x);
  
  	fprintf(f, "%d
  ", n);
  	fclose(f);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
225
  static unsigned long read_slab_obj(struct slabinfo *s, const char *name)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
226
227
228
  {
  	char x[100];
  	FILE *f;
f32143a2f   WANG Cong   Documentation/vm/...
229
  	size_t l;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
230

f32143a2f   WANG Cong   Documentation/vm/...
231
  	snprintf(x, 100, "%s/%s", s->name, name);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
232
233
234
235
236
237
238
239
240
241
242
  	f = fopen(x, "r");
  	if (!f) {
  		buffer[0] = 0;
  		l = 0;
  	} else {
  		l = fread(buffer, 1, sizeof(buffer), f);
  		buffer[l] = 0;
  		fclose(f);
  	}
  	return l;
  }
c09d87517   Christoph Lameter   slub: add slabinf...
243
244
245
  /*
   * Put a size string together
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
246
  static int store_size(char *buffer, unsigned long value)
c09d87517   Christoph Lameter   slub: add slabinf...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  {
  	unsigned long divisor = 1;
  	char trailer = 0;
  	int n;
  
  	if (value > 1000000000UL) {
  		divisor = 100000000UL;
  		trailer = 'G';
  	} else if (value > 1000000UL) {
  		divisor = 100000UL;
  		trailer = 'M';
  	} else if (value > 1000UL) {
  		divisor = 100;
  		trailer = 'K';
  	}
  
  	value /= divisor;
  	n = sprintf(buffer, "%ld",value);
  	if (trailer) {
  		buffer[n] = trailer;
  		n++;
  		buffer[n] = 0;
  	}
  	if (divisor != 1) {
  		memmove(buffer + n - 2, buffer + n - 3, 4);
  		buffer[n-2] = '.';
  		n++;
  	}
  	return n;
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
277
  static void decode_numa_list(int *numa, char *t)
c09d87517   Christoph Lameter   slub: add slabinf...
278
279
280
281
282
  {
  	int node;
  	int nr;
  
  	memset(numa, 0, MAX_NODES * sizeof(int));
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
283
284
  	if (!t)
  		return;
c09d87517   Christoph Lameter   slub: add slabinf...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  	while (*t == 'N') {
  		t++;
  		node = strtoul(t, &t, 10);
  		if (*t == '=') {
  			t++;
  			nr = strtoul(t, &t, 10);
  			numa[node] = nr;
  			if (node > highest_node)
  				highest_node = node;
  		}
  		while (*t == ' ')
  			t++;
  	}
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
299
  static void slab_validate(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
300
  {
32f9306b1   Christoph Lameter   slub: another sla...
301
302
  	if (strcmp(s->name, "*") == 0)
  		return;
c09d87517   Christoph Lameter   slub: add slabinf...
303
304
  	set_obj(s, "validate", 1);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
305
  static void slab_shrink(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
306
  {
32f9306b1   Christoph Lameter   slub: another sla...
307
308
  	if (strcmp(s->name, "*") == 0)
  		return;
c09d87517   Christoph Lameter   slub: add slabinf...
309
310
311
312
  	set_obj(s, "shrink", 1);
  }
  
  int line = 0;
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
313
  static void first_line(void)
c09d87517   Christoph Lameter   slub: add slabinf...
314
  {
8ff12cfc0   Christoph Lameter   SLUB: Support for...
315
  	if (show_activity)
9da4714a2   Christoph Lameter   slub: slabinfo up...
316
317
  		printf("Name                   Objects      Alloc       Free   %%Fast Fallb O CmpX   UL
  ");
8ff12cfc0   Christoph Lameter   SLUB: Support for...
318
319
320
321
  	else
  		printf("Name                   Objects Objsize    Space "
  			"Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg
  ");
c09d87517   Christoph Lameter   slub: add slabinf...
322
323
324
325
326
  }
  
  /*
   * Find the shortest alias of a slab
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
327
  static struct aliasinfo *find_one_alias(struct slabinfo *find)
c09d87517   Christoph Lameter   slub: add slabinf...
328
329
330
331
332
333
334
335
336
337
338
339
  {
  	struct aliasinfo *a;
  	struct aliasinfo *best = NULL;
  
  	for(a = aliasinfo;a < aliasinfo + aliases; a++) {
  		if (a->slab == find &&
  			(!best || strlen(best->name) < strlen(a->name))) {
  				best = a;
  				if (strncmp(a->name,"kmall", 5) == 0)
  					return best;
  			}
  	}
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
340
  	return best;
c09d87517   Christoph Lameter   slub: add slabinf...
341
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
342
  static unsigned long slab_size(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
343
344
345
  {
  	return 	s->slabs * (page_size << s->order);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
346
  static unsigned long slab_activity(struct slabinfo *s)
8ff12cfc0   Christoph Lameter   SLUB: Support for...
347
348
349
350
  {
  	return 	s->alloc_fastpath + s->free_fastpath +
  		s->alloc_slowpath + s->free_slowpath;
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
351
  static void slab_numa(struct slabinfo *s, int mode)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
  {
  	int node;
  
  	if (strcmp(s->name, "*") == 0)
  		return;
  
  	if (!highest_node) {
  		printf("
  %s: No NUMA information available.
  ", s->name);
  		return;
  	}
  
  	if (skip_zero && !s->slabs)
  		return;
  
  	if (!line) {
  		printf("
  %-21s:", mode ? "NUMA nodes" : "Slab");
  		for(node = 0; node <= highest_node; node++)
  			printf(" %4d", node);
  		printf("
  ----------------------");
  		for(node = 0; node <= highest_node; node++)
  			printf("-----");
  		printf("
  ");
  	}
  	printf("%-21s ", mode ? "All slabs" : s->name);
  	for(node = 0; node <= highest_node; node++) {
  		char b[20];
  
  		store_size(b, s->numa[node]);
  		printf(" %4s", b);
  	}
  	printf("
  ");
  	if (mode) {
  		printf("%-21s ", "Partial slabs");
  		for(node = 0; node <= highest_node; node++) {
  			char b[20];
  
  			store_size(b, s->numa_partial[node]);
  			printf(" %4s", b);
  		}
  		printf("
  ");
  	}
  	line++;
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
402
  static void show_tracking(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
403
404
405
406
407
408
409
  {
  	printf("
  %s: Kernel object allocation
  ", s->name);
  	printf("-----------------------------------------------------------------------
  ");
  	if (read_slab_obj(s, "alloc_calls"))
9da4714a2   Christoph Lameter   slub: slabinfo up...
410
  		printf("%s", buffer);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
411
412
413
414
415
416
417
418
419
420
  	else
  		printf("No Data
  ");
  
  	printf("
  %s: Kernel object freeing
  ", s->name);
  	printf("------------------------------------------------------------------------
  ");
  	if (read_slab_obj(s, "free_calls"))
9da4714a2   Christoph Lameter   slub: slabinfo up...
421
  		printf("%s", buffer);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
422
423
424
425
426
  	else
  		printf("No Data
  ");
  
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
427
  static void ops(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
428
429
430
431
432
433
434
435
436
437
  {
  	if (strcmp(s->name, "*") == 0)
  		return;
  
  	if (read_slab_obj(s, "ops")) {
  		printf("
  %s: kmem_cache operations
  ", s->name);
  		printf("--------------------------------------------
  ");
9da4714a2   Christoph Lameter   slub: slabinfo up...
438
  		printf("%s", buffer);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
439
440
441
442
443
  	} else
  		printf("
  %s has no kmem_cache operations
  ", s->name);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
444
  static const char *onoff(int x)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
445
446
447
448
449
  {
  	if (x)
  		return "On ";
  	return "Off";
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
450
  static void slab_stats(struct slabinfo *s)
8ff12cfc0   Christoph Lameter   SLUB: Support for...
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  {
  	unsigned long total_alloc;
  	unsigned long total_free;
  	unsigned long total;
  
  	if (!s->alloc_slab)
  		return;
  
  	total_alloc = s->alloc_fastpath + s->alloc_slowpath;
  	total_free = s->free_fastpath + s->free_slowpath;
  
  	if (!total_alloc)
  		return;
  
  	printf("
  ");
  	printf("Slab Perf Counter       Alloc     Free %%Al %%Fr
  ");
  	printf("--------------------------------------------------
  ");
  	printf("Fastpath             %8lu %8lu %3lu %3lu
  ",
  		s->alloc_fastpath, s->free_fastpath,
  		s->alloc_fastpath * 100 / total_alloc,
  		s->free_fastpath * 100 / total_free);
  	printf("Slowpath             %8lu %8lu %3lu %3lu
  ",
  		total_alloc - s->alloc_fastpath, s->free_slowpath,
  		(total_alloc - s->alloc_fastpath) * 100 / total_alloc,
  		s->free_slowpath * 100 / total_free);
  	printf("Page Alloc           %8lu %8lu %3lu %3lu
  ",
  		s->alloc_slab, s->free_slab,
  		s->alloc_slab * 100 / total_alloc,
  		s->free_slab * 100 / total_free);
  	printf("Add partial          %8lu %8lu %3lu %3lu
  ",
  		s->deactivate_to_head + s->deactivate_to_tail,
  		s->free_add_partial,
  		(s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc,
  		s->free_add_partial * 100 / total_free);
  	printf("Remove partial       %8lu %8lu %3lu %3lu
  ",
  		s->alloc_from_partial, s->free_remove_partial,
  		s->alloc_from_partial * 100 / total_alloc,
  		s->free_remove_partial * 100 / total_free);
  
  	printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu
  ",
  		s->deactivate_remote_frees, s->free_frozen,
  		s->deactivate_remote_frees * 100 / total_alloc,
  		s->free_frozen * 100 / total_free);
  
  	printf("Total                %8lu %8lu
  
  ", total_alloc, total_free);
  
  	if (s->cpuslab_flush)
  		printf("Flushes %8lu
  ", s->cpuslab_flush);
8ff12cfc0   Christoph Lameter   SLUB: Support for...
511
  	total = s->deactivate_full + s->deactivate_empty +
9da4714a2   Christoph Lameter   slub: slabinfo up...
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  			s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass;
  
  	if (total) {
  		printf("
  Slab Deactivation             Ocurrences  %%
  ");
  		printf("-------------------------------------------------
  ");
  		printf("Slab full                     %7lu  %3lu%%
  ",
  			s->deactivate_full, (s->deactivate_full * 100) / total);
  		printf("Slab empty                    %7lu  %3lu%%
  ",
  			s->deactivate_empty, (s->deactivate_empty * 100) / total);
  		printf("Moved to head of partial list %7lu  %3lu%%
  ",
  			s->deactivate_to_head, (s->deactivate_to_head * 100) / total);
  		printf("Moved to tail of partial list %7lu  %3lu%%
  ",
8ff12cfc0   Christoph Lameter   SLUB: Support for...
531
  			s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
9da4714a2   Christoph Lameter   slub: slabinfo up...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
  		printf("Deactivation bypass           %7lu  %3lu%%
  ",
  			s->deactivate_bypass, (s->deactivate_bypass * 100) / total);
  		printf("Refilled from foreign frees   %7lu  %3lu%%
  ",
  			s->alloc_refill, (s->alloc_refill * 100) / total);
  		printf("Node mismatch                 %7lu  %3lu%%
  ",
  			s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total);
  	}
  
  	if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail)
  		printf("
  Cmpxchg_double Looping
  ------------------------
  ");
  		printf("Locked Cmpxchg Double redos   %lu
  Unlocked Cmpxchg Double redos %lu
  ",
  			s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail);
8ff12cfc0   Christoph Lameter   SLUB: Support for...
552
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
553
  static void report(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
554
555
556
  {
  	if (strcmp(s->name, "*") == 0)
  		return;
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
557

ac0786026   Jesper Juhl   SLUB: Fix format ...
558
559
560
  	printf("
  Slabcache: %-20s  Aliases: %2d Order : %2d Objects: %lu
  ",
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
561
  		s->name, s->aliases, s->order, s->objects);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  	if (s->hwcache_align)
  		printf("** Hardware cacheline aligned
  ");
  	if (s->cache_dma)
  		printf("** Memory is allocated in a special DMA zone
  ");
  	if (s->destroy_by_rcu)
  		printf("** Slabs are destroyed via RCU
  ");
  	if (s->reclaim_account)
  		printf("** Reclaim accounting active
  ");
  
  	printf("
  Sizes (bytes)     Slabs              Debug                Memory
  ");
  	printf("------------------------------------------------------------------------
  ");
  	printf("Object : %7d  Total  : %7ld   Sanity Checks : %s  Total: %7ld
  ",
  			s->object_size, s->slabs, onoff(s->sanity_checks),
  			s->slabs * (page_size << s->order));
  	printf("SlabObj: %7d  Full   : %7ld   Redzoning     : %s  Used : %7ld
  ",
  			s->slab_size, s->slabs - s->partial - s->cpu_slabs,
  			onoff(s->red_zone), s->objects * s->object_size);
  	printf("SlabSiz: %7d  Partial: %7ld   Poisoning     : %s  Loss : %7ld
  ",
  			page_size << s->order, s->partial, onoff(s->poison),
  			s->slabs * (page_size << s->order) - s->objects * s->object_size);
  	printf("Loss   : %7d  CpuSlab: %7d   Tracking      : %s  Lalig: %7ld
  ",
  			s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user),
  			(s->slab_size - s->object_size) * s->objects);
  	printf("Align  : %7d  Objects: %7d   Tracing       : %s  Lpadd: %7ld
  ",
  			s->align, s->objs_per_slab, onoff(s->trace),
  			((page_size << s->order) - s->objs_per_slab * s->slab_size) *
  			s->slabs);
  
  	ops(s);
  	show_tracking(s);
  	slab_numa(s, 1);
8ff12cfc0   Christoph Lameter   SLUB: Support for...
605
  	slab_stats(s);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
606
  }
c09d87517   Christoph Lameter   slub: add slabinf...
607

b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
608
  static void slabcache(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
609
610
611
612
613
  {
  	char size_str[20];
  	char dist_str[40];
  	char flags[20];
  	char *p = flags;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
614
615
616
617
618
619
620
621
622
623
624
625
  	if (strcmp(s->name, "*") == 0)
  		return;
  
  	if (actual_slabs == 1) {
  		report(s);
  		return;
  	}
  
  	if (skip_zero && !show_empty && !s->slabs)
  		return;
  
  	if (show_empty && s->slabs)
c09d87517   Christoph Lameter   slub: add slabinf...
626
627
628
  		return;
  
  	store_size(size_str, slab_size(s));
205ab99dd   Christoph Lameter   slub: Update stat...
629
630
  	snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
  						s->partial, s->cpu_slabs);
c09d87517   Christoph Lameter   slub: add slabinf...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
  
  	if (!line++)
  		first_line();
  
  	if (s->aliases)
  		*p++ = '*';
  	if (s->cache_dma)
  		*p++ = 'd';
  	if (s->hwcache_align)
  		*p++ = 'A';
  	if (s->poison)
  		*p++ = 'P';
  	if (s->reclaim_account)
  		*p++ = 'a';
  	if (s->red_zone)
  		*p++ = 'Z';
  	if (s->sanity_checks)
  		*p++ = 'F';
  	if (s->store_user)
  		*p++ = 'U';
  	if (s->trace)
  		*p++ = 'T';
  
  	*p = 0;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
655
656
657
658
659
660
  	if (show_activity) {
  		unsigned long total_alloc;
  		unsigned long total_free;
  
  		total_alloc = s->alloc_fastpath + s->alloc_slowpath;
  		total_free = s->free_fastpath + s->free_slowpath;
9da4714a2   Christoph Lameter   slub: slabinfo up...
661
662
  		printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d %4ld %4ld
  ",
8ff12cfc0   Christoph Lameter   SLUB: Support for...
663
664
665
  			s->name, s->objects,
  			total_alloc, total_free,
  			total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
f715e6f15   Christoph Lameter   slabinfo: Support...
666
  			total_free ? (s->free_fastpath * 100 / total_free) : 0,
9da4714a2   Christoph Lameter   slub: slabinfo up...
667
668
  			s->order_fallback, s->order, s->cmpxchg_double_fail,
  			s->cmpxchg_double_cpu_fail);
8ff12cfc0   Christoph Lameter   SLUB: Support for...
669
670
671
672
673
674
675
676
677
678
  	}
  	else
  		printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s
  ",
  			s->name, s->objects, s->object_size, size_str, dist_str,
  			s->objs_per_slab, s->order,
  			s->slabs ? (s->partial * 100) / s->slabs : 100,
  			s->slabs ? (s->objects * s->object_size * 100) /
  				(s->slabs * (page_size << s->order)) : 100,
  			flags);
c09d87517   Christoph Lameter   slub: add slabinf...
679
  }
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
680
681
682
  /*
   * Analyze debug options. Return false if something is amiss.
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
683
  static int debug_opt_scan(char *opt)
c09d87517   Christoph Lameter   slub: add slabinf...
684
  {
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
685
686
687
688
689
690
691
692
693
694
  	if (!opt || !opt[0] || strcmp(opt, "-") == 0)
  		return 1;
  
  	if (strcasecmp(opt, "a") == 0) {
  		sanity = 1;
  		poison = 1;
  		redzone = 1;
  		tracking = 1;
  		return 1;
  	}
c09d87517   Christoph Lameter   slub: add slabinf...
695

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
696
  	for ( ; *opt; opt++)
0d24db337   Christoph Lameter   slub: move slabin...
697
  		switch (*opt) {
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
698
699
700
701
702
703
704
705
706
707
  		case 'F' : case 'f':
  			if (sanity)
  				return 0;
  			sanity = 1;
  			break;
  		case 'P' : case 'p':
  			if (poison)
  				return 0;
  			poison = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
708

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
709
710
711
712
713
  		case 'Z' : case 'z':
  			if (redzone)
  				return 0;
  			redzone = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
714

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
715
716
717
718
719
  		case 'U' : case 'u':
  			if (tracking)
  				return 0;
  			tracking = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
720

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
721
722
723
724
725
726
727
728
729
  		case 'T' : case 't':
  			if (tracing)
  				return 0;
  			tracing = 1;
  			break;
  		default:
  			return 0;
  		}
  	return 1;
c09d87517   Christoph Lameter   slub: add slabinf...
730
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
731
  static int slab_empty(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
732
  {
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
733
734
  	if (s->objects > 0)
  		return 0;
c09d87517   Christoph Lameter   slub: add slabinf...
735

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
736
737
738
739
740
741
  	/*
  	 * We may still have slabs even if there are no objects. Shrinking will
  	 * remove them.
  	 */
  	if (s->slabs != 0)
  		set_obj(s, "shrink", 1);
c09d87517   Christoph Lameter   slub: add slabinf...
742

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
743
744
  	return 1;
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
745
  static void slab_debug(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
746
  {
32f9306b1   Christoph Lameter   slub: another sla...
747
748
  	if (strcmp(s->name, "*") == 0)
  		return;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
  	if (sanity && !s->sanity_checks) {
  		set_obj(s, "sanity", 1);
  	}
  	if (!sanity && s->sanity_checks) {
  		if (slab_empty(s))
  			set_obj(s, "sanity", 0);
  		else
  			fprintf(stderr, "%s not empty cannot disable sanity checks
  ", s->name);
  	}
  	if (redzone && !s->red_zone) {
  		if (slab_empty(s))
  			set_obj(s, "red_zone", 1);
  		else
  			fprintf(stderr, "%s not empty cannot enable redzoning
  ", s->name);
  	}
  	if (!redzone && s->red_zone) {
  		if (slab_empty(s))
  			set_obj(s, "red_zone", 0);
  		else
  			fprintf(stderr, "%s not empty cannot disable redzoning
  ", s->name);
  	}
  	if (poison && !s->poison) {
  		if (slab_empty(s))
  			set_obj(s, "poison", 1);
  		else
  			fprintf(stderr, "%s not empty cannot enable poisoning
  ", s->name);
  	}
  	if (!poison && s->poison) {
  		if (slab_empty(s))
  			set_obj(s, "poison", 0);
  		else
  			fprintf(stderr, "%s not empty cannot disable poisoning
  ", s->name);
  	}
  	if (tracking && !s->store_user) {
  		if (slab_empty(s))
  			set_obj(s, "store_user", 1);
  		else
  			fprintf(stderr, "%s not empty cannot enable tracking
  ", s->name);
  	}
  	if (!tracking && s->store_user) {
  		if (slab_empty(s))
  			set_obj(s, "store_user", 0);
  		else
  			fprintf(stderr, "%s not empty cannot disable tracking
  ", s->name);
  	}
  	if (tracing && !s->trace) {
  		if (slabs == 1)
  			set_obj(s, "trace", 1);
  		else
  			fprintf(stderr, "%s can only enable trace for one slab at a time
  ", s->name);
  	}
  	if (!tracing && s->trace)
  		set_obj(s, "trace", 1);
c09d87517   Christoph Lameter   slub: add slabinf...
810
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
811
  static void totals(void)
c09d87517   Christoph Lameter   slub: add slabinf...
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
  {
  	struct slabinfo *s;
  
  	int used_slabs = 0;
  	char b1[20], b2[20], b3[20], b4[20];
  	unsigned long long max = 1ULL << 63;
  
  	/* Object size */
  	unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
  
  	/* Number of partial slabs in a slabcache */
  	unsigned long long min_partial = max, max_partial = 0,
  				avg_partial, total_partial = 0;
  
  	/* Number of slabs in a slab cache */
  	unsigned long long min_slabs = max, max_slabs = 0,
  				avg_slabs, total_slabs = 0;
  
  	/* Size of the whole slab */
  	unsigned long long min_size = max, max_size = 0,
  				avg_size, total_size = 0;
  
  	/* Bytes used for object storage in a slab */
  	unsigned long long min_used = max, max_used = 0,
  				avg_used, total_used = 0;
  
  	/* Waste: Bytes used for alignment and padding */
  	unsigned long long min_waste = max, max_waste = 0,
  				avg_waste, total_waste = 0;
  	/* Number of objects in a slab */
  	unsigned long long min_objects = max, max_objects = 0,
  				avg_objects, total_objects = 0;
  	/* Waste per object */
  	unsigned long long min_objwaste = max,
  				max_objwaste = 0, avg_objwaste,
  				total_objwaste = 0;
  
  	/* Memory per object */
  	unsigned long long min_memobj = max,
  				max_memobj = 0, avg_memobj,
  				total_objsize = 0;
  
  	/* Percentage of partial slabs per slab */
  	unsigned long min_ppart = 100, max_ppart = 0,
  				avg_ppart, total_ppart = 0;
  
  	/* Number of objects in partial slabs */
  	unsigned long min_partobj = max, max_partobj = 0,
  				avg_partobj, total_partobj = 0;
  
  	/* Percentage of partial objects of all objects in a slab */
  	unsigned long min_ppartobj = 100, max_ppartobj = 0,
  				avg_ppartobj, total_ppartobj = 0;
  
  
  	for (s = slabinfo; s < slabinfo + slabs; s++) {
  		unsigned long long size;
  		unsigned long used;
  		unsigned long long wasted;
  		unsigned long long objwaste;
c09d87517   Christoph Lameter   slub: add slabinf...
872
873
874
875
876
877
878
879
880
881
882
883
  		unsigned long percentage_partial_slabs;
  		unsigned long percentage_partial_objs;
  
  		if (!s->slabs || !s->objects)
  			continue;
  
  		used_slabs++;
  
  		size = slab_size(s);
  		used = s->objects * s->object_size;
  		wasted = size - used;
  		objwaste = s->slab_size - s->object_size;
c09d87517   Christoph Lameter   slub: add slabinf...
884
885
886
  		percentage_partial_slabs = s->partial * 100 / s->slabs;
  		if (percentage_partial_slabs > 100)
  			percentage_partial_slabs = 100;
205ab99dd   Christoph Lameter   slub: Update stat...
887
  		percentage_partial_objs = s->objects_partial * 100
c09d87517   Christoph Lameter   slub: add slabinf...
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
  							/ s->objects;
  
  		if (percentage_partial_objs > 100)
  			percentage_partial_objs = 100;
  
  		if (s->object_size < min_objsize)
  			min_objsize = s->object_size;
  		if (s->partial < min_partial)
  			min_partial = s->partial;
  		if (s->slabs < min_slabs)
  			min_slabs = s->slabs;
  		if (size < min_size)
  			min_size = size;
  		if (wasted < min_waste)
  			min_waste = wasted;
  		if (objwaste < min_objwaste)
  			min_objwaste = objwaste;
  		if (s->objects < min_objects)
  			min_objects = s->objects;
  		if (used < min_used)
  			min_used = used;
205ab99dd   Christoph Lameter   slub: Update stat...
909
910
  		if (s->objects_partial < min_partobj)
  			min_partobj = s->objects_partial;
c09d87517   Christoph Lameter   slub: add slabinf...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
  		if (percentage_partial_slabs < min_ppart)
  			min_ppart = percentage_partial_slabs;
  		if (percentage_partial_objs < min_ppartobj)
  			min_ppartobj = percentage_partial_objs;
  		if (s->slab_size < min_memobj)
  			min_memobj = s->slab_size;
  
  		if (s->object_size > max_objsize)
  			max_objsize = s->object_size;
  		if (s->partial > max_partial)
  			max_partial = s->partial;
  		if (s->slabs > max_slabs)
  			max_slabs = s->slabs;
  		if (size > max_size)
  			max_size = size;
  		if (wasted > max_waste)
  			max_waste = wasted;
  		if (objwaste > max_objwaste)
  			max_objwaste = objwaste;
  		if (s->objects > max_objects)
  			max_objects = s->objects;
  		if (used > max_used)
  			max_used = used;
205ab99dd   Christoph Lameter   slub: Update stat...
934
935
  		if (s->objects_partial > max_partobj)
  			max_partobj = s->objects_partial;
c09d87517   Christoph Lameter   slub: add slabinf...
936
937
938
939
940
941
942
943
944
945
946
947
948
949
  		if (percentage_partial_slabs > max_ppart)
  			max_ppart = percentage_partial_slabs;
  		if (percentage_partial_objs > max_ppartobj)
  			max_ppartobj = percentage_partial_objs;
  		if (s->slab_size > max_memobj)
  			max_memobj = s->slab_size;
  
  		total_partial += s->partial;
  		total_slabs += s->slabs;
  		total_size += size;
  		total_waste += wasted;
  
  		total_objects += s->objects;
  		total_used += used;
205ab99dd   Christoph Lameter   slub: Update stat...
950
  		total_partobj += s->objects_partial;
c09d87517   Christoph Lameter   slub: add slabinf...
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
  		total_ppart += percentage_partial_slabs;
  		total_ppartobj += percentage_partial_objs;
  
  		total_objwaste += s->objects * objwaste;
  		total_objsize += s->objects * s->slab_size;
  	}
  
  	if (!total_objects) {
  		printf("No objects
  ");
  		return;
  	}
  	if (!used_slabs) {
  		printf("No slabs
  ");
  		return;
  	}
  
  	/* Per slab averages */
  	avg_partial = total_partial / used_slabs;
  	avg_slabs = total_slabs / used_slabs;
  	avg_size = total_size / used_slabs;
  	avg_waste = total_waste / used_slabs;
  
  	avg_objects = total_objects / used_slabs;
  	avg_used = total_used / used_slabs;
  	avg_partobj = total_partobj / used_slabs;
  	avg_ppart = total_ppart / used_slabs;
  	avg_ppartobj = total_ppartobj / used_slabs;
  
  	/* Per object object sizes */
  	avg_objsize = total_used / total_objects;
  	avg_objwaste = total_objwaste / total_objects;
  	avg_partobj = total_partobj * 100 / total_objects;
  	avg_memobj = total_objsize / total_objects;
  
  	printf("Slabcache Totals
  ");
  	printf("----------------
  ");
  	printf("Slabcaches : %3d      Aliases  : %3d->%-3d Active: %3d
  ",
  			slabs, aliases, alias_targets, used_slabs);
  
  	store_size(b1, total_size);store_size(b2, total_waste);
  	store_size(b3, total_waste * 100 / total_used);
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
997
998
  	printf("Memory used: %6s   # Loss   : %6s   MRatio:%6s%%
  ", b1, b2, b3);
c09d87517   Christoph Lameter   slub: add slabinf...
999
1000
1001
  
  	store_size(b1, total_objects);store_size(b2, total_partobj);
  	store_size(b3, total_partobj * 100 / total_objects);
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
1002
1003
  	printf("# Objects  : %6s   # PartObj: %6s   ORatio:%6s%%
  ", b1, b2, b3);
c09d87517   Christoph Lameter   slub: add slabinf...
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
  
  	printf("
  ");
  	printf("Per Cache    Average         Min         Max       Total
  ");
  	printf("---------------------------------------------------------
  ");
  
  	store_size(b1, avg_objects);store_size(b2, min_objects);
  	store_size(b3, max_objects);store_size(b4, total_objects);
  	printf("#Objects  %10s  %10s  %10s  %10s
  ",
  			b1,	b2,	b3,	b4);
  
  	store_size(b1, avg_slabs);store_size(b2, min_slabs);
  	store_size(b3, max_slabs);store_size(b4, total_slabs);
  	printf("#Slabs    %10s  %10s  %10s  %10s
  ",
  			b1,	b2,	b3,	b4);
  
  	store_size(b1, avg_partial);store_size(b2, min_partial);
  	store_size(b3, max_partial);store_size(b4, total_partial);
  	printf("#PartSlab %10s  %10s  %10s  %10s
  ",
  			b1,	b2,	b3,	b4);
  	store_size(b1, avg_ppart);store_size(b2, min_ppart);
  	store_size(b3, max_ppart);
  	store_size(b4, total_partial * 100  / total_slabs);
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
1032
1033
  	printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%
  ",
c09d87517   Christoph Lameter   slub: add slabinf...
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  			b1,	b2,	b3,	b4);
  
  	store_size(b1, avg_partobj);store_size(b2, min_partobj);
  	store_size(b3, max_partobj);
  	store_size(b4, total_partobj);
  	printf("PartObjs  %10s  %10s  %10s  %10s
  ",
  			b1,	b2,	b3,	b4);
  
  	store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
  	store_size(b3, max_ppartobj);
  	store_size(b4, total_partobj * 100 / total_objects);
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
1046
1047
  	printf("%% PartObj%10s%% %10s%% %10s%% %10s%%
  ",
c09d87517   Christoph Lameter   slub: add slabinf...
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
  			b1,	b2,	b3,	b4);
  
  	store_size(b1, avg_size);store_size(b2, min_size);
  	store_size(b3, max_size);store_size(b4, total_size);
  	printf("Memory    %10s  %10s  %10s  %10s
  ",
  			b1,	b2,	b3,	b4);
  
  	store_size(b1, avg_used);store_size(b2, min_used);
  	store_size(b3, max_used);store_size(b4, total_used);
  	printf("Used      %10s  %10s  %10s  %10s
  ",
  			b1,	b2,	b3,	b4);
  
  	store_size(b1, avg_waste);store_size(b2, min_waste);
  	store_size(b3, max_waste);store_size(b4, total_waste);
  	printf("Loss      %10s  %10s  %10s  %10s
  ",
  			b1,	b2,	b3,	b4);
  
  	printf("
  ");
  	printf("Per Object   Average         Min         Max
  ");
  	printf("---------------------------------------------
  ");
  
  	store_size(b1, avg_memobj);store_size(b2, min_memobj);
  	store_size(b3, max_memobj);
  	printf("Memory    %10s  %10s  %10s
  ",
  			b1,	b2,	b3);
  	store_size(b1, avg_objsize);store_size(b2, min_objsize);
  	store_size(b3, max_objsize);
  	printf("User      %10s  %10s  %10s
  ",
  			b1,	b2,	b3);
  
  	store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
  	store_size(b3, max_objwaste);
  	printf("Loss      %10s  %10s  %10s
  ",
  			b1,	b2,	b3);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1092
  static void sort_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1093
1094
1095
1096
1097
1098
1099
1100
1101
  {
  	struct slabinfo *s1,*s2;
  
  	for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
  		for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
  			int result;
  
  			if (sort_size)
  				result = slab_size(s1) < slab_size(s2);
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1102
1103
  			else if (sort_active)
  				result = slab_activity(s1) < slab_activity(s2);
c09d87517   Christoph Lameter   slub: add slabinf...
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
  			else
  				result = strcasecmp(s1->name, s2->name);
  
  			if (show_inverted)
  				result = -result;
  
  			if (result > 0) {
  				struct slabinfo t;
  
  				memcpy(&t, s1, sizeof(struct slabinfo));
  				memcpy(s1, s2, sizeof(struct slabinfo));
  				memcpy(s2, &t, sizeof(struct slabinfo));
  			}
  		}
  	}
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1120
  static void sort_aliases(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
  {
  	struct aliasinfo *a1,*a2;
  
  	for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) {
  		for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) {
  			char *n1, *n2;
  
  			n1 = a1->name;
  			n2 = a2->name;
  			if (show_alias && !show_inverted) {
  				n1 = a1->ref;
  				n2 = a2->ref;
  			}
  			if (strcasecmp(n1, n2) > 0) {
  				struct aliasinfo t;
  
  				memcpy(&t, a1, sizeof(struct aliasinfo));
  				memcpy(a1, a2, sizeof(struct aliasinfo));
  				memcpy(a2, &t, sizeof(struct aliasinfo));
  			}
  		}
  	}
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1144
  static void link_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1145
1146
1147
1148
1149
  {
  	struct aliasinfo *a;
  	struct slabinfo *s;
  
  	for (a = aliasinfo; a < aliasinfo + aliases; a++) {
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1150
  		for (s = slabinfo; s < slabinfo + slabs; s++)
c09d87517   Christoph Lameter   slub: add slabinf...
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
  			if (strcmp(a->ref, s->name) == 0) {
  				a->slab = s;
  				s->refs++;
  				break;
  			}
  		if (s == slabinfo + slabs)
  			fatal("Unresolved alias %s
  ", a->ref);
  	}
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1161
  static void alias(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
  {
  	struct aliasinfo *a;
  	char *active = NULL;
  
  	sort_aliases();
  	link_slabs();
  
  	for(a = aliasinfo; a < aliasinfo + aliases; a++) {
  
  		if (!show_single_ref && a->slab->refs == 1)
  			continue;
  
  		if (!show_inverted) {
  			if (active) {
  				if (strcmp(a->slab->name, active) == 0) {
  					printf(" %s", a->name);
  					continue;
  				}
  			}
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1181
1182
  			printf("
  %-12s <- %s", a->slab->name, a->name);
c09d87517   Christoph Lameter   slub: add slabinf...
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
  			active = a->slab->name;
  		}
  		else
  			printf("%-20s -> %s
  ", a->name, a->slab->name);
  	}
  	if (active)
  		printf("
  ");
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1193
  static void rename_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
  {
  	struct slabinfo *s;
  	struct aliasinfo *a;
  
  	for (s = slabinfo; s < slabinfo + slabs; s++) {
  		if (*s->name != ':')
  			continue;
  
  		if (s->refs > 1 && !show_first_alias)
  			continue;
  
  		a = find_one_alias(s);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1206
1207
1208
1209
1210
1211
  		if (a)
  			s->name = a->name;
  		else {
  			s->name = "*";
  			actual_slabs--;
  		}
c09d87517   Christoph Lameter   slub: add slabinf...
1212
1213
  	}
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1214
  static int slab_mismatch(char *slab)
c09d87517   Christoph Lameter   slub: add slabinf...
1215
1216
1217
  {
  	return regexec(&pattern, slab, 0, NULL, 0);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1218
  static void read_slab_dir(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1219
1220
1221
1222
1223
1224
1225
1226
  {
  	DIR *dir;
  	struct dirent *de;
  	struct slabinfo *slab = slabinfo;
  	struct aliasinfo *alias = aliasinfo;
  	char *p;
  	char *t;
  	int count;
b6c24de77   Christoph Lameter   slabinfo: fall ba...
1227
  	if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1228
1229
  		fatal("SYSFS support for SLUB not active
  ");
c09d87517   Christoph Lameter   slub: add slabinf...
1230
1231
1232
  	dir = opendir(".");
  	while ((de = readdir(dir))) {
  		if (de->d_name[0] == '.' ||
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1233
1234
  			(de->d_name[0] != ':' && slab_mismatch(de->d_name)))
  				continue;
c09d87517   Christoph Lameter   slub: add slabinf...
1235
1236
  		switch (de->d_type) {
  		   case DT_LNK:
0d24db337   Christoph Lameter   slub: move slabin...
1237
  			alias->name = strdup(de->d_name);
c09d87517   Christoph Lameter   slub: add slabinf...
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
  			count = readlink(de->d_name, buffer, sizeof(buffer));
  
  			if (count < 0)
  				fatal("Cannot read symlink %s
  ", de->d_name);
  
  			buffer[count] = 0;
  			p = buffer + count;
  			while (p > buffer && p[-1] != '/')
  				p--;
  			alias->ref = strdup(p);
  			alias++;
  			break;
  		   case DT_DIR:
  			if (chdir(de->d_name))
  				fatal("Unable to access slab %s
  ", slab->name);
0d24db337   Christoph Lameter   slub: move slabin...
1255
  			slab->name = strdup(de->d_name);
c09d87517   Christoph Lameter   slub: add slabinf...
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
  			slab->alias = 0;
  			slab->refs = 0;
  			slab->aliases = get_obj("aliases");
  			slab->align = get_obj("align");
  			slab->cache_dma = get_obj("cache_dma");
  			slab->cpu_slabs = get_obj("cpu_slabs");
  			slab->destroy_by_rcu = get_obj("destroy_by_rcu");
  			slab->hwcache_align = get_obj("hwcache_align");
  			slab->object_size = get_obj("object_size");
  			slab->objects = get_obj("objects");
205ab99dd   Christoph Lameter   slub: Update stat...
1266
1267
  			slab->objects_partial = get_obj("objects_partial");
  			slab->objects_total = get_obj("objects_total");
c09d87517   Christoph Lameter   slub: add slabinf...
1268
1269
1270
1271
1272
  			slab->objs_per_slab = get_obj("objs_per_slab");
  			slab->order = get_obj("order");
  			slab->partial = get_obj("partial");
  			slab->partial = get_obj_and_str("partial", &t);
  			decode_numa_list(slab->numa_partial, t);
f32143a2f   WANG Cong   Documentation/vm/...
1273
  			free(t);
c09d87517   Christoph Lameter   slub: add slabinf...
1274
1275
1276
1277
1278
1279
1280
  			slab->poison = get_obj("poison");
  			slab->reclaim_account = get_obj("reclaim_account");
  			slab->red_zone = get_obj("red_zone");
  			slab->sanity_checks = get_obj("sanity_checks");
  			slab->slab_size = get_obj("slab_size");
  			slab->slabs = get_obj_and_str("slabs", &t);
  			decode_numa_list(slab->numa, t);
f32143a2f   WANG Cong   Documentation/vm/...
1281
  			free(t);
c09d87517   Christoph Lameter   slub: add slabinf...
1282
1283
  			slab->store_user = get_obj("store_user");
  			slab->trace = get_obj("trace");
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
  			slab->alloc_fastpath = get_obj("alloc_fastpath");
  			slab->alloc_slowpath = get_obj("alloc_slowpath");
  			slab->free_fastpath = get_obj("free_fastpath");
  			slab->free_slowpath = get_obj("free_slowpath");
  			slab->free_frozen= get_obj("free_frozen");
  			slab->free_add_partial = get_obj("free_add_partial");
  			slab->free_remove_partial = get_obj("free_remove_partial");
  			slab->alloc_from_partial = get_obj("alloc_from_partial");
  			slab->alloc_slab = get_obj("alloc_slab");
  			slab->alloc_refill = get_obj("alloc_refill");
  			slab->free_slab = get_obj("free_slab");
  			slab->cpuslab_flush = get_obj("cpuslab_flush");
  			slab->deactivate_full = get_obj("deactivate_full");
  			slab->deactivate_empty = get_obj("deactivate_empty");
  			slab->deactivate_to_head = get_obj("deactivate_to_head");
  			slab->deactivate_to_tail = get_obj("deactivate_to_tail");
  			slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
f715e6f15   Christoph Lameter   slabinfo: Support...
1301
  			slab->order_fallback = get_obj("order_fallback");
9da4714a2   Christoph Lameter   slub: slabinfo up...
1302
1303
1304
1305
  			slab->cmpxchg_double_cpu_fail = get_obj("cmpxchg_double_cpu_fail");
  			slab->cmpxchg_double_fail = get_obj("cmpxchg_double_fail");
  			slab->alloc_node_mismatch = get_obj("alloc_node_mismatch");
  			slab->deactivate_bypass = get_obj("deactivate_bypass");
c09d87517   Christoph Lameter   slub: add slabinf...
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
  			chdir("..");
  			if (slab->name[0] == ':')
  				alias_targets++;
  			slab++;
  			break;
  		   default :
  			fatal("Unknown file type %lx
  ", de->d_type);
  		}
  	}
  	closedir(dir);
  	slabs = slab - slabinfo;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1318
  	actual_slabs = slabs;
c09d87517   Christoph Lameter   slub: add slabinf...
1319
1320
1321
1322
1323
1324
1325
1326
  	aliases = alias - aliasinfo;
  	if (slabs > MAX_SLABS)
  		fatal("Too many slabs
  ");
  	if (aliases > MAX_ALIASES)
  		fatal("Too many aliases
  ");
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1327
  static void output_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
  {
  	struct slabinfo *slab;
  
  	for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
  
  		if (slab->alias)
  			continue;
  
  
  		if (show_numa)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1338
1339
  			slab_numa(slab, 0);
  		else if (show_track)
c09d87517   Christoph Lameter   slub: add slabinf...
1340
  			show_tracking(slab);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1341
  		else if (validate)
c09d87517   Christoph Lameter   slub: add slabinf...
1342
  			slab_validate(slab);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1343
  		else if (shrink)
c09d87517   Christoph Lameter   slub: add slabinf...
1344
  			slab_shrink(slab);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1345
1346
1347
1348
1349
1350
  		else if (set_debug)
  			slab_debug(slab);
  		else if (show_ops)
  			ops(slab);
  		else if (show_slab)
  			slabcache(slab);
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
1351
1352
  		else if (show_report)
  			report(slab);
c09d87517   Christoph Lameter   slub: add slabinf...
1353
1354
1355
1356
1357
  	}
  }
  
  struct option opts[] = {
  	{ "aliases", 0, NULL, 'a' },
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1358
  	{ "activity", 0, NULL, 'A' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1359
  	{ "debug", 2, NULL, 'd' },
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1360
  	{ "display-activity", 0, NULL, 'D' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1361
  	{ "empty", 0, NULL, 'e' },
c09d87517   Christoph Lameter   slub: add slabinf...
1362
  	{ "first-alias", 0, NULL, 'f' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1363
1364
1365
1366
1367
  	{ "help", 0, NULL, 'h' },
  	{ "inverted", 0, NULL, 'i'},
  	{ "numa", 0, NULL, 'n' },
  	{ "ops", 0, NULL, 'o' },
  	{ "report", 0, NULL, 'r' },
c09d87517   Christoph Lameter   slub: add slabinf...
1368
  	{ "shrink", 0, NULL, 's' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1369
  	{ "slabs", 0, NULL, 'l' },
c09d87517   Christoph Lameter   slub: add slabinf...
1370
  	{ "track", 0, NULL, 't'},
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1371
1372
  	{ "validate", 0, NULL, 'v' },
  	{ "zero", 0, NULL, 'z' },
c09d87517   Christoph Lameter   slub: add slabinf...
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
  	{ "1ref", 0, NULL, '1'},
  	{ NULL, 0, NULL, 0 }
  };
  
  int main(int argc, char *argv[])
  {
  	int c;
  	int err;
  	char *pattern_source;
  
  	page_size = getpagesize();
c09d87517   Christoph Lameter   slub: add slabinf...
1384

8ff12cfc0   Christoph Lameter   SLUB: Support for...
1385
  	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1386
  						opts, NULL)) != -1)
f32143a2f   WANG Cong   Documentation/vm/...
1387
  		switch (c) {
c09d87517   Christoph Lameter   slub: add slabinf...
1388
1389
1390
1391
1392
1393
  		case '1':
  			show_single_ref = 1;
  			break;
  		case 'a':
  			show_alias = 1;
  			break;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1394
1395
1396
  		case 'A':
  			sort_active = 1;
  			break;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1397
1398
1399
1400
1401
1402
  		case 'd':
  			set_debug = 1;
  			if (!debug_opt_scan(optarg))
  				fatal("Invalid debug option '%s'
  ", optarg);
  			break;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1403
1404
1405
  		case 'D':
  			show_activity = 1;
  			break;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1406
1407
1408
  		case 'e':
  			show_empty = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
  		case 'f':
  			show_first_alias = 1;
  			break;
  		case 'h':
  			usage();
  			return 0;
  		case 'i':
  			show_inverted = 1;
  			break;
  		case 'n':
  			show_numa = 1;
  			break;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1421
1422
1423
1424
1425
1426
  		case 'o':
  			show_ops = 1;
  			break;
  		case 'r':
  			show_report = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
  		case 's':
  			shrink = 1;
  			break;
  		case 'l':
  			show_slab = 1;
  			break;
  		case 't':
  			show_track = 1;
  			break;
  		case 'v':
  			validate = 1;
  			break;
  		case 'z':
  			skip_zero = 0;
  			break;
  		case 'T':
  			show_totals = 1;
  			break;
  		case 'S':
  			sort_size = 1;
  			break;
  
  		default:
  			fatal("%s: Invalid option '%c'
  ", argv[0], optopt);
  
  	}
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1454
1455
  	if (!show_slab && !show_alias && !show_track && !show_report
  		&& !validate && !shrink && !set_debug && !show_ops)
c09d87517   Christoph Lameter   slub: add slabinf...
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
  			show_slab = 1;
  
  	if (argc > optind)
  		pattern_source = argv[optind];
  	else
  		pattern_source = ".*";
  
  	err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
  	if (err)
  		fatal("%s: Invalid pattern '%s' code %d
  ",
  			argv[0], pattern_source, err);
  	read_slab_dir();
  	if (show_alias)
  		alias();
  	else
  	if (show_totals)
  		totals();
  	else {
  		link_slabs();
  		rename_slabs();
  		sort_slabs();
  		output_slabs();
  	}
  	return 0;
  }