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