Blame view

tools/slub/slabinfo.c 34.1 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;
aca726a07   Christoph Lameter   slub: update slab...
45
  	unsigned long cpu_partial_alloc, cpu_partial_free;
c09d87517   Christoph Lameter   slub: add slabinf...
46
47
48
49
50
51
52
53
54
55
56
  	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...
57
  int actual_slabs = 0;
c09d87517   Christoph Lameter   slub: add slabinf...
58
59
60
61
62
  int aliases = 0;
  int alias_targets = 0;
  int highest_node = 0;
  
  char buffer[4096];
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
63
64
  int show_empty = 0;
  int show_report = 0;
c09d87517   Christoph Lameter   slub: add slabinf...
65
66
67
68
69
70
71
72
73
74
75
76
  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...
77
  int sort_active = 0;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
78
79
  int set_debug = 0;
  int show_ops = 0;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
80
  int show_activity = 0;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
81
82
83
84
85
86
87
  
  /* Debug options */
  int sanity = 0;
  int redzone = 0;
  int poison = 0;
  int tracking = 0;
  int tracing = 0;
c09d87517   Christoph Lameter   slub: add slabinf...
88
89
90
91
  
  int page_size;
  
  regex_t pattern;
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
92
  static void fatal(const char *x, ...)
c09d87517   Christoph Lameter   slub: add slabinf...
93
94
95
96
97
98
  {
  	va_list ap;
  
  	va_start(ap, x);
  	vfprintf(stderr, x, ap);
  	va_end(ap);
f32143a2f   WANG Cong   Documentation/vm/...
99
  	exit(EXIT_FAILURE);
c09d87517   Christoph Lameter   slub: add slabinf...
100
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
101
  static void usage(void)
c09d87517   Christoph Lameter   slub: add slabinf...
102
  {
9da4714a2   Christoph Lameter   slub: slabinfo up...
103
104
105
  	printf("slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.
  
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
106
107
  		"slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]
  "
c09d87517   Christoph Lameter   slub: add slabinf...
108
109
  		"-a|--aliases           Show aliases
  "
8ff12cfc0   Christoph Lameter   SLUB: Support for...
110
111
  		"-A|--activity          Most active slabs first
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
112
113
  		"-d<options>|--debug=<options> Set/Clear Debug options
  "
8ff12cfc0   Christoph Lameter   SLUB: Support for...
114
115
116
117
  		"-D|--display-active    Switch line format to activity
  "
  		"-e|--empty             Show empty slabs
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
118
119
  		"-f|--first-alias       Show first alias
  "
c09d87517   Christoph Lameter   slub: add slabinf...
120
121
  		"-h|--help              Show usage information
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
122
123
124
125
  		"-i|--inverted          Inverted list
  "
  		"-l|--slabs             Show slabs
  "
c09d87517   Christoph Lameter   slub: add slabinf...
126
127
  		"-n|--numa              Show NUMA information
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
128
129
  		"-o|--ops		Show kmem_cache_ops
  "
c09d87517   Christoph Lameter   slub: add slabinf...
130
131
  		"-s|--shrink            Shrink slabs
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
132
133
134
135
  		"-r|--report		Detailed report on single slabs
  "
  		"-S|--Size              Sort by size
  "
c09d87517   Christoph Lameter   slub: add slabinf...
136
137
138
139
  		"-t|--tracking          Show alloc/free information
  "
  		"-T|--Totals            Show summary information
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
140
141
  		"-v|--validate          Validate slabs
  "
c09d87517   Christoph Lameter   slub: add slabinf...
142
143
  		"-z|--zero              Include empty slabs
  "
c09d87517   Christoph Lameter   slub: add slabinf...
144
145
  		"-1|--1ref              Single reference
  "
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  		"
  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...
163
164
  	);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
165
  static unsigned long read_obj(const char *name)
c09d87517   Christoph Lameter   slub: add slabinf...
166
167
168
169
170
171
  {
  	FILE *f = fopen(name, "r");
  
  	if (!f)
  		buffer[0] = 0;
  	else {
f32143a2f   WANG Cong   Documentation/vm/...
172
  		if (!fgets(buffer, sizeof(buffer), f))
c09d87517   Christoph Lameter   slub: add slabinf...
173
174
175
176
177
178
179
180
181
182
183
184
185
  			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...
186
  static unsigned long get_obj(const char *name)
c09d87517   Christoph Lameter   slub: add slabinf...
187
188
189
190
191
192
  {
  	if (!read_obj(name))
  		return 0;
  
  	return atol(buffer);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
193
  static unsigned long get_obj_and_str(const char *name, char **x)
c09d87517   Christoph Lameter   slub: add slabinf...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  {
  	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...
211
  static void set_obj(struct slabinfo *s, const char *name, int n)
c09d87517   Christoph Lameter   slub: add slabinf...
212
213
  {
  	char x[100];
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
214
  	FILE *f;
c09d87517   Christoph Lameter   slub: add slabinf...
215

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

f32143a2f   WANG Cong   Documentation/vm/...
232
  	snprintf(x, 100, "%s/%s", s->name, name);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
233
234
235
236
237
238
239
240
241
242
243
  	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...
244
245
246
  /*
   * Put a size string together
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
247
  static int store_size(char *buffer, unsigned long value)
c09d87517   Christoph Lameter   slub: add slabinf...
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
277
  {
  	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...
278
  static void decode_numa_list(int *numa, char *t)
c09d87517   Christoph Lameter   slub: add slabinf...
279
280
281
282
283
  {
  	int node;
  	int nr;
  
  	memset(numa, 0, MAX_NODES * sizeof(int));
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
284
285
  	if (!t)
  		return;
c09d87517   Christoph Lameter   slub: add slabinf...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  	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...
300
  static void slab_validate(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
301
  {
32f9306b1   Christoph Lameter   slub: another sla...
302
303
  	if (strcmp(s->name, "*") == 0)
  		return;
c09d87517   Christoph Lameter   slub: add slabinf...
304
305
  	set_obj(s, "validate", 1);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
306
  static void slab_shrink(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
307
  {
32f9306b1   Christoph Lameter   slub: another sla...
308
309
  	if (strcmp(s->name, "*") == 0)
  		return;
c09d87517   Christoph Lameter   slub: add slabinf...
310
311
312
313
  	set_obj(s, "shrink", 1);
  }
  
  int line = 0;
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
314
  static void first_line(void)
c09d87517   Christoph Lameter   slub: add slabinf...
315
  {
8ff12cfc0   Christoph Lameter   SLUB: Support for...
316
  	if (show_activity)
9da4714a2   Christoph Lameter   slub: slabinfo up...
317
318
  		printf("Name                   Objects      Alloc       Free   %%Fast Fallb O CmpX   UL
  ");
8ff12cfc0   Christoph Lameter   SLUB: Support for...
319
320
321
322
  	else
  		printf("Name                   Objects Objsize    Space "
  			"Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg
  ");
c09d87517   Christoph Lameter   slub: add slabinf...
323
324
325
326
327
  }
  
  /*
   * Find the shortest alias of a slab
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
328
  static struct aliasinfo *find_one_alias(struct slabinfo *find)
c09d87517   Christoph Lameter   slub: add slabinf...
329
330
331
332
333
334
335
336
337
338
339
340
  {
  	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...
341
  	return best;
c09d87517   Christoph Lameter   slub: add slabinf...
342
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
343
  static unsigned long slab_size(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
344
345
346
  {
  	return 	s->slabs * (page_size << s->order);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
347
  static unsigned long slab_activity(struct slabinfo *s)
8ff12cfc0   Christoph Lameter   SLUB: Support for...
348
349
350
351
  {
  	return 	s->alloc_fastpath + s->free_fastpath +
  		s->alloc_slowpath + s->free_slowpath;
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
352
  static void slab_numa(struct slabinfo *s, int mode)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
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
402
  {
  	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...
403
  static void show_tracking(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
404
405
406
407
408
409
410
  {
  	printf("
  %s: Kernel object allocation
  ", s->name);
  	printf("-----------------------------------------------------------------------
  ");
  	if (read_slab_obj(s, "alloc_calls"))
9da4714a2   Christoph Lameter   slub: slabinfo up...
411
  		printf("%s", buffer);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
412
413
414
415
416
417
418
419
420
421
  	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...
422
  		printf("%s", buffer);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
423
424
425
426
427
  	else
  		printf("No Data
  ");
  
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
428
  static void ops(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
429
430
431
432
433
434
435
436
437
438
  {
  	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...
439
  		printf("%s", buffer);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
440
441
442
443
444
  	} else
  		printf("
  %s has no kmem_cache operations
  ", s->name);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
445
  static const char *onoff(int x)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
446
447
448
449
450
  {
  	if (x)
  		return "On ";
  	return "Off";
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
451
  static void slab_stats(struct slabinfo *s)
8ff12cfc0   Christoph Lameter   SLUB: Support for...
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
  {
  	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);
aca726a07   Christoph Lameter   slub: update slab...
498
499
500
501
502
  	printf("Cpu partial list     %8lu %8lu %3lu %3lu
  ",
  		s->cpu_partial_alloc, s->cpu_partial_free,
  		s->cpu_partial_alloc * 100 / total_alloc,
  		s->cpu_partial_free * 100 / total_free);
8ff12cfc0   Christoph Lameter   SLUB: Support for...
503
504
505
506
507
508
509
510
511
512
513
514
515
  	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...
516
  	total = s->deactivate_full + s->deactivate_empty +
9da4714a2   Christoph Lameter   slub: slabinfo up...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
  			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...
536
  			s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
9da4714a2   Christoph Lameter   slub: slabinfo up...
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
  		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...
557
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
558
  static void report(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
559
560
561
  {
  	if (strcmp(s->name, "*") == 0)
  		return;
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
562

ac0786026   Jesper Juhl   SLUB: Fix format ...
563
564
565
  	printf("
  Slabcache: %-20s  Aliases: %2d Order : %2d Objects: %lu
  ",
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
566
  		s->name, s->aliases, s->order, s->objects);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
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
605
606
607
608
609
  	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...
610
  	slab_stats(s);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
611
  }
c09d87517   Christoph Lameter   slub: add slabinf...
612

b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
613
  static void slabcache(struct slabinfo *s)
c09d87517   Christoph Lameter   slub: add slabinf...
614
615
616
617
618
  {
  	char size_str[20];
  	char dist_str[40];
  	char flags[20];
  	char *p = flags;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
619
620
621
622
623
624
625
626
627
628
629
630
  	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...
631
632
633
  		return;
  
  	store_size(size_str, slab_size(s));
205ab99dd   Christoph Lameter   slub: Update stat...
634
635
  	snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
  						s->partial, s->cpu_slabs);
c09d87517   Christoph Lameter   slub: add slabinf...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
  
  	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...
660
661
662
663
664
665
  	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...
666
667
  		printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d %4ld %4ld
  ",
8ff12cfc0   Christoph Lameter   SLUB: Support for...
668
669
670
  			s->name, s->objects,
  			total_alloc, total_free,
  			total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
f715e6f15   Christoph Lameter   slabinfo: Support...
671
  			total_free ? (s->free_fastpath * 100 / total_free) : 0,
9da4714a2   Christoph Lameter   slub: slabinfo up...
672
673
  			s->order_fallback, s->order, s->cmpxchg_double_fail,
  			s->cmpxchg_double_cpu_fail);
8ff12cfc0   Christoph Lameter   SLUB: Support for...
674
675
676
677
678
679
680
681
682
683
  	}
  	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...
684
  }
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
685
686
687
  /*
   * Analyze debug options. Return false if something is amiss.
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
688
  static int debug_opt_scan(char *opt)
c09d87517   Christoph Lameter   slub: add slabinf...
689
  {
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
690
691
692
693
694
695
696
697
698
699
  	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...
700

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
701
  	for ( ; *opt; opt++)
0d24db337   Christoph Lameter   slub: move slabin...
702
  		switch (*opt) {
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
703
704
705
706
707
708
709
710
711
712
  		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...
713

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
714
715
716
717
718
  		case 'Z' : case 'z':
  			if (redzone)
  				return 0;
  			redzone = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
719

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
720
721
722
723
724
  		case 'U' : case 'u':
  			if (tracking)
  				return 0;
  			tracking = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
725

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

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
741
742
743
744
745
746
  	/*
  	 * 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...
747

a87615b8f   Christoph Lameter   SLUB: slabinfo up...
748
749
  	return 1;
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
750
  static void slab_debug(struct slabinfo *s)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
751
  {
32f9306b1   Christoph Lameter   slub: another sla...
752
753
  	if (strcmp(s->name, "*") == 0)
  		return;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
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
810
811
812
813
814
  	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...
815
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
816
  static void totals(void)
c09d87517   Christoph Lameter   slub: add slabinf...
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
872
873
874
875
876
  {
  	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...
877
878
879
880
881
882
883
884
885
886
887
888
  		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...
889
890
891
  		percentage_partial_slabs = s->partial * 100 / s->slabs;
  		if (percentage_partial_slabs > 100)
  			percentage_partial_slabs = 100;
205ab99dd   Christoph Lameter   slub: Update stat...
892
  		percentage_partial_objs = s->objects_partial * 100
c09d87517   Christoph Lameter   slub: add slabinf...
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
  							/ 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...
914
915
  		if (s->objects_partial < min_partobj)
  			min_partobj = s->objects_partial;
c09d87517   Christoph Lameter   slub: add slabinf...
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
  		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...
939
940
  		if (s->objects_partial > max_partobj)
  			max_partobj = s->objects_partial;
c09d87517   Christoph Lameter   slub: add slabinf...
941
942
943
944
945
946
947
948
949
950
951
952
953
954
  		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...
955
  		total_partobj += s->objects_partial;
c09d87517   Christoph Lameter   slub: add slabinf...
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
997
998
999
1000
1001
  		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
1002
1003
  	printf("Memory used: %6s   # Loss   : %6s   MRatio:%6s%%
  ", b1, b2, b3);
c09d87517   Christoph Lameter   slub: add slabinf...
1004
1005
1006
  
  	store_size(b1, total_objects);store_size(b2, total_partobj);
  	store_size(b3, total_partobj * 100 / total_objects);
eefaca9c3   Christoph Lameter   SLUB: slabinfo fixes
1007
1008
  	printf("# Objects  : %6s   # PartObj: %6s   ORatio:%6s%%
  ", b1, b2, b3);
c09d87517   Christoph Lameter   slub: add slabinf...
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
  
  	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
1037
1038
  	printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%
  ",
c09d87517   Christoph Lameter   slub: add slabinf...
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
  			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
1051
1052
  	printf("%% PartObj%10s%% %10s%% %10s%% %10s%%
  ",
c09d87517   Christoph Lameter   slub: add slabinf...
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
1092
1093
1094
1095
1096
  			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...
1097
  static void sort_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1098
1099
1100
1101
1102
1103
1104
1105
1106
  {
  	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...
1107
1108
  			else if (sort_active)
  				result = slab_activity(s1) < slab_activity(s2);
c09d87517   Christoph Lameter   slub: add slabinf...
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
  			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...
1125
  static void sort_aliases(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
  {
  	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...
1149
  static void link_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1150
1151
1152
1153
1154
  {
  	struct aliasinfo *a;
  	struct slabinfo *s;
  
  	for (a = aliasinfo; a < aliasinfo + aliases; a++) {
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1155
  		for (s = slabinfo; s < slabinfo + slabs; s++)
c09d87517   Christoph Lameter   slub: add slabinf...
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  			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...
1166
  static void alias(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
  {
  	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...
1186
1187
  			printf("
  %-12s <- %s", a->slab->name, a->name);
c09d87517   Christoph Lameter   slub: add slabinf...
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
  			active = a->slab->name;
  		}
  		else
  			printf("%-20s -> %s
  ", a->name, a->slab->name);
  	}
  	if (active)
  		printf("
  ");
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1198
  static void rename_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
  {
  	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...
1211
1212
1213
1214
1215
1216
  		if (a)
  			s->name = a->name;
  		else {
  			s->name = "*";
  			actual_slabs--;
  		}
c09d87517   Christoph Lameter   slub: add slabinf...
1217
1218
  	}
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1219
  static int slab_mismatch(char *slab)
c09d87517   Christoph Lameter   slub: add slabinf...
1220
1221
1222
  {
  	return regexec(&pattern, slab, 0, NULL, 0);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1223
  static void read_slab_dir(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1224
1225
1226
1227
1228
1229
1230
1231
  {
  	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...
1232
  	if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1233
1234
  		fatal("SYSFS support for SLUB not active
  ");
c09d87517   Christoph Lameter   slub: add slabinf...
1235
1236
1237
  	dir = opendir(".");
  	while ((de = readdir(dir))) {
  		if (de->d_name[0] == '.' ||
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1238
1239
  			(de->d_name[0] != ':' && slab_mismatch(de->d_name)))
  				continue;
c09d87517   Christoph Lameter   slub: add slabinf...
1240
1241
  		switch (de->d_type) {
  		   case DT_LNK:
0d24db337   Christoph Lameter   slub: move slabin...
1242
  			alias->name = strdup(de->d_name);
fe3531786   Thomas Jarosch   tools, slub: Fix ...
1243
  			count = readlink(de->d_name, buffer, sizeof(buffer)-1);
c09d87517   Christoph Lameter   slub: add slabinf...
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
  
  			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...
1260
  			slab->name = strdup(de->d_name);
c09d87517   Christoph Lameter   slub: add slabinf...
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
  			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...
1271
1272
  			slab->objects_partial = get_obj("objects_partial");
  			slab->objects_total = get_obj("objects_total");
c09d87517   Christoph Lameter   slub: add slabinf...
1273
1274
1275
1276
1277
  			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/...
1278
  			free(t);
c09d87517   Christoph Lameter   slub: add slabinf...
1279
1280
1281
1282
1283
1284
1285
  			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/...
1286
  			free(t);
c09d87517   Christoph Lameter   slub: add slabinf...
1287
1288
  			slab->store_user = get_obj("store_user");
  			slab->trace = get_obj("trace");
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
  			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...
1306
  			slab->order_fallback = get_obj("order_fallback");
9da4714a2   Christoph Lameter   slub: slabinfo up...
1307
1308
  			slab->cmpxchg_double_cpu_fail = get_obj("cmpxchg_double_cpu_fail");
  			slab->cmpxchg_double_fail = get_obj("cmpxchg_double_fail");
aca726a07   Christoph Lameter   slub: update slab...
1309
1310
  			slab->cpu_partial_alloc = get_obj("cpu_partial_alloc");
  			slab->cpu_partial_free = get_obj("cpu_partial_free");
9da4714a2   Christoph Lameter   slub: slabinfo up...
1311
1312
  			slab->alloc_node_mismatch = get_obj("alloc_node_mismatch");
  			slab->deactivate_bypass = get_obj("deactivate_bypass");
c09d87517   Christoph Lameter   slub: add slabinf...
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
  			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...
1325
  	actual_slabs = slabs;
c09d87517   Christoph Lameter   slub: add slabinf...
1326
1327
1328
1329
1330
1331
1332
1333
  	aliases = alias - aliasinfo;
  	if (slabs > MAX_SLABS)
  		fatal("Too many slabs
  ");
  	if (aliases > MAX_ALIASES)
  		fatal("Too many aliases
  ");
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
1334
  static void output_slabs(void)
c09d87517   Christoph Lameter   slub: add slabinf...
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  {
  	struct slabinfo *slab;
  
  	for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
  
  		if (slab->alias)
  			continue;
  
  
  		if (show_numa)
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1345
1346
  			slab_numa(slab, 0);
  		else if (show_track)
c09d87517   Christoph Lameter   slub: add slabinf...
1347
  			show_tracking(slab);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1348
  		else if (validate)
c09d87517   Christoph Lameter   slub: add slabinf...
1349
  			slab_validate(slab);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1350
  		else if (shrink)
c09d87517   Christoph Lameter   slub: add slabinf...
1351
  			slab_shrink(slab);
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1352
1353
1354
1355
1356
1357
  		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
1358
1359
  		else if (show_report)
  			report(slab);
c09d87517   Christoph Lameter   slub: add slabinf...
1360
1361
1362
1363
1364
  	}
  }
  
  struct option opts[] = {
  	{ "aliases", 0, NULL, 'a' },
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1365
  	{ "activity", 0, NULL, 'A' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1366
  	{ "debug", 2, NULL, 'd' },
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1367
  	{ "display-activity", 0, NULL, 'D' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1368
  	{ "empty", 0, NULL, 'e' },
c09d87517   Christoph Lameter   slub: add slabinf...
1369
  	{ "first-alias", 0, NULL, 'f' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1370
1371
1372
1373
1374
  	{ "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...
1375
  	{ "shrink", 0, NULL, 's' },
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1376
  	{ "slabs", 0, NULL, 'l' },
c09d87517   Christoph Lameter   slub: add slabinf...
1377
  	{ "track", 0, NULL, 't'},
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1378
1379
  	{ "validate", 0, NULL, 'v' },
  	{ "zero", 0, NULL, 'z' },
c09d87517   Christoph Lameter   slub: add slabinf...
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
  	{ "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...
1391

8ff12cfc0   Christoph Lameter   SLUB: Support for...
1392
  	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1393
  						opts, NULL)) != -1)
f32143a2f   WANG Cong   Documentation/vm/...
1394
  		switch (c) {
c09d87517   Christoph Lameter   slub: add slabinf...
1395
1396
1397
1398
1399
1400
  		case '1':
  			show_single_ref = 1;
  			break;
  		case 'a':
  			show_alias = 1;
  			break;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1401
1402
1403
  		case 'A':
  			sort_active = 1;
  			break;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1404
1405
1406
1407
1408
1409
  		case 'd':
  			set_debug = 1;
  			if (!debug_opt_scan(optarg))
  				fatal("Invalid debug option '%s'
  ", optarg);
  			break;
8ff12cfc0   Christoph Lameter   SLUB: Support for...
1410
1411
1412
  		case 'D':
  			show_activity = 1;
  			break;
a87615b8f   Christoph Lameter   SLUB: slabinfo up...
1413
1414
1415
  		case 'e':
  			show_empty = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
  		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...
1428
1429
1430
1431
1432
1433
  		case 'o':
  			show_ops = 1;
  			break;
  		case 'r':
  			show_report = 1;
  			break;
c09d87517   Christoph Lameter   slub: add slabinf...
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
  		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...
1461
1462
  	if (!show_slab && !show_alias && !show_track && !show_report
  		&& !validate && !shrink && !set_debug && !show_ops)
c09d87517   Christoph Lameter   slub: add slabinf...
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
  			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;
  }