aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 21:22:29 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 21:22:29 -0500
commitc00f08d705e149fbfaf7a252b4d4fbb7affdcc96 (patch)
tree8c916856376d0d400ddda239d5be386f9b9516d7 /Documentation
parentc8b6de16d9434405e5832b8772e4f986ddd5118e (diff)
parent3adbefee6fd58a061b2bf1df4f3769701860fc62 (diff)
Merge branch 'slub-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/christoph/vm
* 'slub-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/christoph/vm: SLUB: fix checkpatch warnings Use non atomic unlock SLUB: Support for performance statistics SLUB: Alternate fast paths using cmpxchg_local SLUB: Use unique end pointer for each slab page. SLUB: Deal with annoying gcc warning on kfree()
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/vm/slabinfo.c149
1 files changed, 138 insertions, 11 deletions
diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c
index 488c1f31b992..7123fee708ca 100644
--- a/Documentation/vm/slabinfo.c
+++ b/Documentation/vm/slabinfo.c
@@ -32,6 +32,13 @@ struct slabinfo {
32 int sanity_checks, slab_size, store_user, trace; 32 int sanity_checks, slab_size, store_user, trace;
33 int order, poison, reclaim_account, red_zone; 33 int order, poison, reclaim_account, red_zone;
34 unsigned long partial, objects, slabs; 34 unsigned long partial, objects, slabs;
35 unsigned long alloc_fastpath, alloc_slowpath;
36 unsigned long free_fastpath, free_slowpath;
37 unsigned long free_frozen, free_add_partial, free_remove_partial;
38 unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill;
39 unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
40 unsigned long deactivate_to_head, deactivate_to_tail;
41 unsigned long deactivate_remote_frees;
35 int numa[MAX_NODES]; 42 int numa[MAX_NODES];
36 int numa_partial[MAX_NODES]; 43 int numa_partial[MAX_NODES];
37} slabinfo[MAX_SLABS]; 44} slabinfo[MAX_SLABS];
@@ -64,8 +71,10 @@ int show_inverted = 0;
64int show_single_ref = 0; 71int show_single_ref = 0;
65int show_totals = 0; 72int show_totals = 0;
66int sort_size = 0; 73int sort_size = 0;
74int sort_active = 0;
67int set_debug = 0; 75int set_debug = 0;
68int show_ops = 0; 76int show_ops = 0;
77int show_activity = 0;
69 78
70/* Debug options */ 79/* Debug options */
71int sanity = 0; 80int sanity = 0;
@@ -93,8 +102,10 @@ void usage(void)
93 printf("slabinfo 5/7/2007. (c) 2007 sgi. clameter@sgi.com\n\n" 102 printf("slabinfo 5/7/2007. (c) 2007 sgi. clameter@sgi.com\n\n"
94 "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n" 103 "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
95 "-a|--aliases Show aliases\n" 104 "-a|--aliases Show aliases\n"
105 "-A|--activity Most active slabs first\n"
96 "-d<options>|--debug=<options> Set/Clear Debug options\n" 106 "-d<options>|--debug=<options> Set/Clear Debug options\n"
97 "-e|--empty Show empty slabs\n" 107 "-D|--display-active Switch line format to activity\n"
108 "-e|--empty Show empty slabs\n"
98 "-f|--first-alias Show first alias\n" 109 "-f|--first-alias Show first alias\n"
99 "-h|--help Show usage information\n" 110 "-h|--help Show usage information\n"
100 "-i|--inverted Inverted list\n" 111 "-i|--inverted Inverted list\n"
@@ -281,8 +292,11 @@ int line = 0;
281 292
282void first_line(void) 293void first_line(void)
283{ 294{
284 printf("Name Objects Objsize Space " 295 if (show_activity)
285 "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n"); 296 printf("Name Objects Alloc Free %%Fast\n");
297 else
298 printf("Name Objects Objsize Space "
299 "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n");
286} 300}
287 301
288/* 302/*
@@ -309,6 +323,12 @@ unsigned long slab_size(struct slabinfo *s)
309 return s->slabs * (page_size << s->order); 323 return s->slabs * (page_size << s->order);
310} 324}
311 325
326unsigned long slab_activity(struct slabinfo *s)
327{
328 return s->alloc_fastpath + s->free_fastpath +
329 s->alloc_slowpath + s->free_slowpath;
330}
331
312void slab_numa(struct slabinfo *s, int mode) 332void slab_numa(struct slabinfo *s, int mode)
313{ 333{
314 int node; 334 int node;
@@ -392,6 +412,71 @@ const char *onoff(int x)
392 return "Off"; 412 return "Off";
393} 413}
394 414
415void slab_stats(struct slabinfo *s)
416{
417 unsigned long total_alloc;
418 unsigned long total_free;
419 unsigned long total;
420
421 if (!s->alloc_slab)
422 return;
423
424 total_alloc = s->alloc_fastpath + s->alloc_slowpath;
425 total_free = s->free_fastpath + s->free_slowpath;
426
427 if (!total_alloc)
428 return;
429
430 printf("\n");
431 printf("Slab Perf Counter Alloc Free %%Al %%Fr\n");
432 printf("--------------------------------------------------\n");
433 printf("Fastpath %8lu %8lu %3lu %3lu\n",
434 s->alloc_fastpath, s->free_fastpath,
435 s->alloc_fastpath * 100 / total_alloc,
436 s->free_fastpath * 100 / total_free);
437 printf("Slowpath %8lu %8lu %3lu %3lu\n",
438 total_alloc - s->alloc_fastpath, s->free_slowpath,
439 (total_alloc - s->alloc_fastpath) * 100 / total_alloc,
440 s->free_slowpath * 100 / total_free);
441 printf("Page Alloc %8lu %8lu %3lu %3lu\n",
442 s->alloc_slab, s->free_slab,
443 s->alloc_slab * 100 / total_alloc,
444 s->free_slab * 100 / total_free);
445 printf("Add partial %8lu %8lu %3lu %3lu\n",
446 s->deactivate_to_head + s->deactivate_to_tail,
447 s->free_add_partial,
448 (s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc,
449 s->free_add_partial * 100 / total_free);
450 printf("Remove partial %8lu %8lu %3lu %3lu\n",
451 s->alloc_from_partial, s->free_remove_partial,
452 s->alloc_from_partial * 100 / total_alloc,
453 s->free_remove_partial * 100 / total_free);
454
455 printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n",
456 s->deactivate_remote_frees, s->free_frozen,
457 s->deactivate_remote_frees * 100 / total_alloc,
458 s->free_frozen * 100 / total_free);
459
460 printf("Total %8lu %8lu\n\n", total_alloc, total_free);
461
462 if (s->cpuslab_flush)
463 printf("Flushes %8lu\n", s->cpuslab_flush);
464
465 if (s->alloc_refill)
466 printf("Refill %8lu\n", s->alloc_refill);
467
468 total = s->deactivate_full + s->deactivate_empty +
469 s->deactivate_to_head + s->deactivate_to_tail;
470
471 if (total)
472 printf("Deactivate Full=%lu(%lu%%) Empty=%lu(%lu%%) "
473 "ToHead=%lu(%lu%%) ToTail=%lu(%lu%%)\n",
474 s->deactivate_full, (s->deactivate_full * 100) / total,
475 s->deactivate_empty, (s->deactivate_empty * 100) / total,
476 s->deactivate_to_head, (s->deactivate_to_head * 100) / total,
477 s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
478}
479
395void report(struct slabinfo *s) 480void report(struct slabinfo *s)
396{ 481{
397 if (strcmp(s->name, "*") == 0) 482 if (strcmp(s->name, "*") == 0)
@@ -430,6 +515,7 @@ void report(struct slabinfo *s)
430 ops(s); 515 ops(s);
431 show_tracking(s); 516 show_tracking(s);
432 slab_numa(s, 1); 517 slab_numa(s, 1);
518 slab_stats(s);
433} 519}
434 520
435void slabcache(struct slabinfo *s) 521void slabcache(struct slabinfo *s)
@@ -479,13 +565,27 @@ void slabcache(struct slabinfo *s)
479 *p++ = 'T'; 565 *p++ = 'T';
480 566
481 *p = 0; 567 *p = 0;
482 printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n", 568 if (show_activity) {
483 s->name, s->objects, s->object_size, size_str, dist_str, 569 unsigned long total_alloc;
484 s->objs_per_slab, s->order, 570 unsigned long total_free;
485 s->slabs ? (s->partial * 100) / s->slabs : 100, 571
486 s->slabs ? (s->objects * s->object_size * 100) / 572 total_alloc = s->alloc_fastpath + s->alloc_slowpath;
487 (s->slabs * (page_size << s->order)) : 100, 573 total_free = s->free_fastpath + s->free_slowpath;
488 flags); 574
575 printf("%-21s %8ld %8ld %8ld %3ld %3ld \n",
576 s->name, s->objects,
577 total_alloc, total_free,
578 total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
579 total_free ? (s->free_fastpath * 100 / total_free) : 0);
580 }
581 else
582 printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
583 s->name, s->objects, s->object_size, size_str, dist_str,
584 s->objs_per_slab, s->order,
585 s->slabs ? (s->partial * 100) / s->slabs : 100,
586 s->slabs ? (s->objects * s->object_size * 100) /
587 (s->slabs * (page_size << s->order)) : 100,
588 flags);
489} 589}
490 590
491/* 591/*
@@ -892,6 +992,8 @@ void sort_slabs(void)
892 992
893 if (sort_size) 993 if (sort_size)
894 result = slab_size(s1) < slab_size(s2); 994 result = slab_size(s1) < slab_size(s2);
995 else if (sort_active)
996 result = slab_activity(s1) < slab_activity(s2);
895 else 997 else
896 result = strcasecmp(s1->name, s2->name); 998 result = strcasecmp(s1->name, s2->name);
897 999
@@ -1074,6 +1176,23 @@ void read_slab_dir(void)
1074 free(t); 1176 free(t);
1075 slab->store_user = get_obj("store_user"); 1177 slab->store_user = get_obj("store_user");
1076 slab->trace = get_obj("trace"); 1178 slab->trace = get_obj("trace");
1179 slab->alloc_fastpath = get_obj("alloc_fastpath");
1180 slab->alloc_slowpath = get_obj("alloc_slowpath");
1181 slab->free_fastpath = get_obj("free_fastpath");
1182 slab->free_slowpath = get_obj("free_slowpath");
1183 slab->free_frozen= get_obj("free_frozen");
1184 slab->free_add_partial = get_obj("free_add_partial");
1185 slab->free_remove_partial = get_obj("free_remove_partial");
1186 slab->alloc_from_partial = get_obj("alloc_from_partial");
1187 slab->alloc_slab = get_obj("alloc_slab");
1188 slab->alloc_refill = get_obj("alloc_refill");
1189 slab->free_slab = get_obj("free_slab");
1190 slab->cpuslab_flush = get_obj("cpuslab_flush");
1191 slab->deactivate_full = get_obj("deactivate_full");
1192 slab->deactivate_empty = get_obj("deactivate_empty");
1193 slab->deactivate_to_head = get_obj("deactivate_to_head");
1194 slab->deactivate_to_tail = get_obj("deactivate_to_tail");
1195 slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
1077 chdir(".."); 1196 chdir("..");
1078 if (slab->name[0] == ':') 1197 if (slab->name[0] == ':')
1079 alias_targets++; 1198 alias_targets++;
@@ -1124,7 +1243,9 @@ void output_slabs(void)
1124 1243
1125struct option opts[] = { 1244struct option opts[] = {
1126 { "aliases", 0, NULL, 'a' }, 1245 { "aliases", 0, NULL, 'a' },
1246 { "activity", 0, NULL, 'A' },
1127 { "debug", 2, NULL, 'd' }, 1247 { "debug", 2, NULL, 'd' },
1248 { "display-activity", 0, NULL, 'D' },
1128 { "empty", 0, NULL, 'e' }, 1249 { "empty", 0, NULL, 'e' },
1129 { "first-alias", 0, NULL, 'f' }, 1250 { "first-alias", 0, NULL, 'f' },
1130 { "help", 0, NULL, 'h' }, 1251 { "help", 0, NULL, 'h' },
@@ -1149,7 +1270,7 @@ int main(int argc, char *argv[])
1149 1270
1150 page_size = getpagesize(); 1271 page_size = getpagesize();
1151 1272
1152 while ((c = getopt_long(argc, argv, "ad::efhil1noprstvzTS", 1273 while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
1153 opts, NULL)) != -1) 1274 opts, NULL)) != -1)
1154 switch (c) { 1275 switch (c) {
1155 case '1': 1276 case '1':
@@ -1158,11 +1279,17 @@ int main(int argc, char *argv[])
1158 case 'a': 1279 case 'a':
1159 show_alias = 1; 1280 show_alias = 1;
1160 break; 1281 break;
1282 case 'A':
1283 sort_active = 1;
1284 break;
1161 case 'd': 1285 case 'd':
1162 set_debug = 1; 1286 set_debug = 1;
1163 if (!debug_opt_scan(optarg)) 1287 if (!debug_opt_scan(optarg))
1164 fatal("Invalid debug option '%s'\n", optarg); 1288 fatal("Invalid debug option '%s'\n", optarg);
1165 break; 1289 break;
1290 case 'D':
1291 show_activity = 1;
1292 break;
1166 case 'e': 1293 case 'e':
1167 show_empty = 1; 1294 show_empty = 1;
1168 break; 1295 break;