aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/blackfin/00-INDEX11
-rw-r--r--Documentation/blackfin/Filesystems169
-rw-r--r--Documentation/blackfin/cache-lock.txt48
-rw-r--r--Documentation/blackfin/cachefeatures.txt65
-rw-r--r--Documentation/filesystems/proc.txt31
-rw-r--r--Documentation/pcmcia/driver.txt30
-rw-r--r--Documentation/power/interface.txt8
-rw-r--r--Documentation/sysctl/vm.txt23
-rw-r--r--Documentation/vm/slabinfo.c943
-rw-r--r--Documentation/vm/slub.txt113
10 files changed, 1418 insertions, 23 deletions
diff --git a/Documentation/blackfin/00-INDEX b/Documentation/blackfin/00-INDEX
new file mode 100644
index 000000000000..7cb3b356b249
--- /dev/null
+++ b/Documentation/blackfin/00-INDEX
@@ -0,0 +1,11 @@
100-INDEX
2 - This file
3
4cache-lock.txt
5 - HOWTO for blackfin cache locking.
6
7cachefeatures.txt
8 - Supported cache features.
9
10Filesystems
11 - Requirements for mounting the root file system.
diff --git a/Documentation/blackfin/Filesystems b/Documentation/blackfin/Filesystems
new file mode 100644
index 000000000000..51260a1b8032
--- /dev/null
+++ b/Documentation/blackfin/Filesystems
@@ -0,0 +1,169 @@
1/*
2 * File: Documentation/blackfin/Filesystems
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Rev: $Id: Filesystems 2384 2006-11-01 04:12:43Z magicyang $
10 *
11 * Modified:
12 * Copyright 2004-2006 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 */
17
18 How to mount the root file system in uClinux/Blackfin
19 -----------------------------------------------------
20
211 Mounting EXT3 File system.
22 ------------------------
23
24 Creating an EXT3 File system for uClinux/Blackfin:
25
26
27Please follow the steps to form the EXT3 File system and mount the same as root
28file system.
29
30a Make an ext3 file system as large as you want the final root file
31 system.
32
33 mkfs.ext3 /dev/ram0 <your-rootfs-size-in-1k-blocks>
34
35b Mount this Empty file system on a free directory as:
36
37 mount -t ext3 /dev/ram0 ./test
38 where ./test is the empty directory.
39
40c Copy your root fs directory that you have so carefully made over.
41
42 cp -af /tmp/my_final_rootfs_files/* ./test
43
44 (For ex: cp -af uClinux-dist/romfs/* ./test)
45
46d If you have done everything right till now you should be able to see
47 the required "root" dir's (that's etc, root, bin, lib, sbin...)
48
49e Now unmount the file system
50
51 umount ./test
52
53f Create the root file system image.
54
55 dd if=/dev/ram0 bs=1k count=<your-rootfs-size-in-1k-blocks> \
56 > ext3fs.img
57
58
59Now you have to tell the kernel that will be mounting this file system as
60rootfs.
61So do a make menuconfig under kernel and select the Ext3 journaling file system
62support under File system --> submenu.
63
64
652. Mounting EXT2 File system.
66 -------------------------
67
68By default the ext2 file system image will be created if you invoke make from
69the top uClinux-dist directory.
70
71
723. Mounting CRAMFS File System
73 ----------------------------
74
75To create a CRAMFS file system image execute the command
76
77 mkfs.cramfs ./test cramfs.img
78
79 where ./test is the target directory.
80
81
824. Mounting ROMFS File System
83 --------------------------
84
85To create a ROMFS file system image execute the command
86
87 genromfs -v -V "ROMdisk" -f romfs.img -d ./test
88
89 where ./test is the target directory
90
91
925. Mounting the JFFS2 Filesystem
93 -----------------------------
94
95To create a compressed JFFS filesystem (JFFS2), please execute the command
96
97 mkfs.jffs2 -d ./test -o jffs2.img
98
99 where ./test is the target directory.
100
101However, please make sure the following is in your kernel config.
102
103/*
104 * RAM/ROM/Flash chip drivers
105 */
106#define CONFIG_MTD_CFI 1
107#define CONFIG_MTD_ROM 1
108/*
109 * Mapping drivers for chip access
110 */
111#define CONFIG_MTD_COMPLEX_MAPPINGS 1
112#define CONFIG_MTD_BF533 1
113#undef CONFIG_MTD_UCLINUX
114
115Through the u-boot boot loader, use the jffs2.img in the corresponding
116partition made in linux-2.6.x/drivers/mtd/maps/bf533_flash.c.
117
118NOTE - Currently the Flash driver is available only for EZKIT. Watch out for a
119 STAMP driver soon.
120
121
1226. Mounting the NFS File system
123 -----------------------------
124
125 For mounting the NFS please do the following in the kernel config.
126
127 In Networking Support --> Networking options --> TCP/IP networking -->
128 IP: kernel level autoconfiguration
129
130 Enable BOOTP Support.
131
132 In Kernel hacking --> Compiled-in kernel boot parameter add the following
133
134 root=/dev/nfs rw ip=bootp
135
136 In File system --> Network File system, Enable
137
138 NFS file system support --> NFSv3 client support
139 Root File system on NFS
140
141 in uClibc menuconfig, do the following
142 In Networking Support
143 enable Remote Procedure Call (RPC) support
144 Full RPC Support
145
146 On the Host side, ensure that /etc/dhcpd.conf looks something like this
147
148 ddns-update-style ad-hoc;
149 allow bootp;
150 subnet 10.100.4.0 netmask 255.255.255.0 {
151 default-lease-time 122209600;
152 max-lease-time 31557600;
153 group {
154 host bf533 {
155 hardware ethernet 00:CF:52:49:C3:01;
156 fixed-address 10.100.4.50;
157 option root-path "/home/nfsmount";
158 }
159 }
160
161 ensure that /etc/exports looks something like this
162 /home/nfsmount *(rw,no_root_squash,no_all_squash)
163
164 run the following commands as root (may differ depending on your
165 distribution) :
166 - service nfs start
167 - service portmap start
168 - service dhcpd start
169 - /usr/sbin/exportfs
diff --git a/Documentation/blackfin/cache-lock.txt b/Documentation/blackfin/cache-lock.txt
new file mode 100644
index 000000000000..88ba1e6c31c3
--- /dev/null
+++ b/Documentation/blackfin/cache-lock.txt
@@ -0,0 +1,48 @@
1/*
2 * File: Documentation/blackfin/cache-lock.txt
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Rev: $Id: cache-lock.txt 2384 2006-11-01 04:12:43Z magicyang $
10 *
11 * Modified:
12 * Copyright 2004-2006 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 */
17
18How to lock your code in cache in uClinux/blackfin
19--------------------------------------------------
20
21There are only a few steps required to lock your code into the cache.
22Currently you can lock the code by Way.
23
24Below are the interface provided for locking the cache.
25
26
271. cache_grab_lock(int Ways);
28
29This function grab the lock for locking your code into the cache specified
30by Ways.
31
32
332. cache_lock(int Ways);
34
35This function should be called after your critical code has been executed.
36Once the critical code exits, the code is now loaded into the cache. This
37function locks the code into the cache.
38
39
40So, the example sequence will be:
41
42 cache_grab_lock(WAY0_L); /* Grab the lock */
43
44 critical_code(); /* Execute the code of interest */
45
46 cache_lock(WAY0_L); /* Lock the cache */
47
48Where WAY0_L signifies WAY0 locking.
diff --git a/Documentation/blackfin/cachefeatures.txt b/Documentation/blackfin/cachefeatures.txt
new file mode 100644
index 000000000000..0fbec23becb5
--- /dev/null
+++ b/Documentation/blackfin/cachefeatures.txt
@@ -0,0 +1,65 @@
1/*
2 * File: Documentation/blackfin/cachefeatures.txt
3 * Based on:
4 * Author:
5 *
6 * Created:
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Rev: $Id: cachefeatures.txt 2384 2006-11-01 04:12:43Z magicyang $
10 *
11 * Modified:
12 * Copyright 2004-2006 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 */
17
18 - Instruction and Data cache initialization.
19 icache_init();
20 dcache_init();
21
22 - Instruction and Data cache Invalidation Routines, when flushing the
23 same is not required.
24 _icache_invalidate();
25 _dcache_invalidate();
26
27 Also, for invalidating the entire instruction and data cache, the below
28 routines are provided (another method for invalidation, refer page no 267 and 287 of
29 ADSP-BF533 Hardware Reference manual)
30
31 invalidate_entire_dcache();
32 invalidate_entire_icache();
33
34 -External Flushing of Instruction and data cache routines.
35
36 flush_instruction_cache();
37 flush_data_cache();
38
39 - Internal Flushing of Instruction and Data Cache.
40
41 icplb_flush();
42 dcplb_flush();
43
44 - Locking the cache.
45
46 cache_grab_lock();
47 cache_lock();
48
49 Please refer linux-2.6.x/Documentation/blackfin/cache-lock.txt for how to
50 lock the cache.
51
52 Locking the cache is optional feature.
53
54 - Miscellaneous cache functions.
55
56 flush_cache_all();
57 flush_cache_mm();
58 invalidate_dcache_range();
59 flush_dcache_range();
60 flush_dcache_page();
61 flush_cache_range();
62 flush_cache_page();
63 invalidate_dcache_range();
64 flush_page_to_ram();
65
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 7aaf09b86a55..3f4b226572e7 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -122,21 +122,22 @@ subdirectory has the entries listed in Table 1-1.
122 122
123Table 1-1: Process specific entries in /proc 123Table 1-1: Process specific entries in /proc
124.............................................................................. 124..............................................................................
125 File Content 125 File Content
126 cmdline Command line arguments 126 clear_refs Clears page referenced bits shown in smaps output
127 cpu Current and last cpu in which it was executed (2.4)(smp) 127 cmdline Command line arguments
128 cwd Link to the current working directory 128 cpu Current and last cpu in which it was executed (2.4)(smp)
129 environ Values of environment variables 129 cwd Link to the current working directory
130 exe Link to the executable of this process 130 environ Values of environment variables
131 fd Directory, which contains all file descriptors 131 exe Link to the executable of this process
132 maps Memory maps to executables and library files (2.4) 132 fd Directory, which contains all file descriptors
133 mem Memory held by this process 133 maps Memory maps to executables and library files (2.4)
134 root Link to the root directory of this process 134 mem Memory held by this process
135 stat Process status 135 root Link to the root directory of this process
136 statm Process memory status information 136 stat Process status
137 status Process status in human readable form 137 statm Process memory status information
138 wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan 138 status Process status in human readable form
139 smaps Extension based on maps, presenting the rss size for each mapped file 139 wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
140 smaps Extension based on maps, the rss size for each mapped file
140.............................................................................. 141..............................................................................
141 142
142For example, to get the status information of a process, all you have to do is 143For example, to get the status information of a process, all you have to do is
diff --git a/Documentation/pcmcia/driver.txt b/Documentation/pcmcia/driver.txt
new file mode 100644
index 000000000000..0ac167920778
--- /dev/null
+++ b/Documentation/pcmcia/driver.txt
@@ -0,0 +1,30 @@
1PCMCIA Driver
2-------------
3
4
5sysfs
6-----
7
8New PCMCIA IDs may be added to a device driver pcmcia_device_id table at
9runtime as shown below:
10
11echo "match_flags manf_id card_id func_id function device_no \
12prod_id_hash[0] prod_id_hash[1] prod_id_hash[2] prod_id_hash[3]" > \
13/sys/bus/pcmcia/drivers/{driver}/new_id
14
15All fields are passed in as hexadecimal values (no leading 0x).
16The meaning is described in the PCMCIA specification, the match_flags is
17a bitwise or-ed combination from PCMCIA_DEV_ID_MATCH_* constants
18defined in include/linux/mod_devicetable.h.
19
20Once added, the driver probe routine will be invoked for any unclaimed
21PCMCIA device listed in its (newly updated) pcmcia_device_id list.
22
23A common use-case is to add a new device according to the manufacturer ID
24and the card ID (form the manf_id and card_id file in the device tree).
25For this, just use:
26
27echo "0x3 manf_id card_id 0 0 0 0 0 0 0" > \
28 /sys/bus/pcmcia/drivers/{driver}/new_id
29
30after loading the driver.
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index 8c5b41bf3f36..fd5192a8fa8a 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -34,8 +34,12 @@ for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then,
34we are able to look in the log messages and work out, for example, which code 34we are able to look in the log messages and work out, for example, which code
35is being slow and which device drivers are misbehaving. 35is being slow and which device drivers are misbehaving.
36 36
37Reading from this file will display what the mode is currently set 37Reading from this file will display all supported modes and the currently
38to. Writing to this file will accept one of 38selected one in brackets, for example
39
40 [shutdown] reboot test testproc
41
42Writing to this file will accept one of
39 43
40 'platform' (only if the platform supports it) 44 'platform' (only if the platform supports it)
41 'shutdown' 45 'shutdown'
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index e96a341eb7e4..1d192565e182 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -197,11 +197,22 @@ and may not be fast.
197 197
198panic_on_oom 198panic_on_oom
199 199
200This enables or disables panic on out-of-memory feature. If this is set to 1, 200This enables or disables panic on out-of-memory feature.
201the kernel panics when out-of-memory happens. If this is set to 0, the kernel
202will kill some rogue process, called oom_killer. Usually, oom_killer can kill
203rogue processes and system will survive. If you want to panic the system
204rather than killing rogue processes, set this to 1.
205 201
206The default value is 0. 202If this is set to 0, the kernel will kill some rogue process,
203called oom_killer. Usually, oom_killer can kill rogue processes and
204system will survive.
205
206If this is set to 1, the kernel panics when out-of-memory happens.
207However, if a process limits using nodes by mempolicy/cpusets,
208and those nodes become memory exhaustion status, one process
209may be killed by oom-killer. No panic occurs in this case.
210Because other nodes' memory may be free. This means system total status
211may be not fatal yet.
207 212
213If this is set to 2, the kernel panics compulsorily even on the
214above-mentioned.
215
216The default value is 0.
2171 and 2 are for failover of clustering. Please select either
218according to your policy of failover.
diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c
new file mode 100644
index 000000000000..41710ccf3a29
--- /dev/null
+++ b/Documentation/vm/slabinfo.c
@@ -0,0 +1,943 @@
1/*
2 * Slabinfo: Tool to get reports about slabs
3 *
4 * (C) 2007 sgi, Christoph Lameter <clameter@sgi.com>
5 *
6 * Compile by:
7 *
8 * gcc -o slabinfo slabinfo.c
9 */
10#include <stdio.h>
11#include <stdlib.h>
12#include <sys/types.h>
13#include <dirent.h>
14#include <string.h>
15#include <unistd.h>
16#include <stdarg.h>
17#include <getopt.h>
18#include <regex.h>
19
20#define MAX_SLABS 500
21#define MAX_ALIASES 500
22#define MAX_NODES 1024
23
24struct slabinfo {
25 char *name;
26 int alias;
27 int refs;
28 int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
29 int hwcache_align, object_size, objs_per_slab;
30 int sanity_checks, slab_size, store_user, trace;
31 int order, poison, reclaim_account, red_zone;
32 unsigned long partial, objects, slabs;
33 int numa[MAX_NODES];
34 int numa_partial[MAX_NODES];
35} slabinfo[MAX_SLABS];
36
37struct aliasinfo {
38 char *name;
39 char *ref;
40 struct slabinfo *slab;
41} aliasinfo[MAX_ALIASES];
42
43int slabs = 0;
44int aliases = 0;
45int alias_targets = 0;
46int highest_node = 0;
47
48char buffer[4096];
49
50int show_alias = 0;
51int show_slab = 0;
52int skip_zero = 1;
53int show_numa = 0;
54int show_track = 0;
55int show_first_alias = 0;
56int validate = 0;
57int shrink = 0;
58int show_inverted = 0;
59int show_single_ref = 0;
60int show_totals = 0;
61int sort_size = 0;
62
63int page_size;
64
65regex_t pattern;
66
67void fatal(const char *x, ...)
68{
69 va_list ap;
70
71 va_start(ap, x);
72 vfprintf(stderr, x, ap);
73 va_end(ap);
74 exit(1);
75}
76
77void usage(void)
78{
79 printf("slabinfo [-ahnpvtsz] [slab-regexp]\n"
80 "-a|--aliases Show aliases\n"
81 "-h|--help Show usage information\n"
82 "-n|--numa Show NUMA information\n"
83 "-s|--shrink Shrink slabs\n"
84 "-v|--validate Validate slabs\n"
85 "-t|--tracking Show alloc/free information\n"
86 "-T|--Totals Show summary information\n"
87 "-l|--slabs Show slabs\n"
88 "-S|--Size Sort by size\n"
89 "-z|--zero Include empty slabs\n"
90 "-f|--first-alias Show first alias\n"
91 "-i|--inverted Inverted list\n"
92 "-1|--1ref Single reference\n"
93 );
94}
95
96unsigned long read_obj(char *name)
97{
98 FILE *f = fopen(name, "r");
99
100 if (!f)
101 buffer[0] = 0;
102 else {
103 if (!fgets(buffer,sizeof(buffer), f))
104 buffer[0] = 0;
105 fclose(f);
106 if (buffer[strlen(buffer)] == '\n')
107 buffer[strlen(buffer)] = 0;
108 }
109 return strlen(buffer);
110}
111
112
113/*
114 * Get the contents of an attribute
115 */
116unsigned long get_obj(char *name)
117{
118 if (!read_obj(name))
119 return 0;
120
121 return atol(buffer);
122}
123
124unsigned long get_obj_and_str(char *name, char **x)
125{
126 unsigned long result = 0;
127 char *p;
128
129 *x = NULL;
130
131 if (!read_obj(name)) {
132 x = NULL;
133 return 0;
134 }
135 result = strtoul(buffer, &p, 10);
136 while (*p == ' ')
137 p++;
138 if (*p)
139 *x = strdup(p);
140 return result;
141}
142
143void set_obj(struct slabinfo *s, char *name, int n)
144{
145 char x[100];
146
147 sprintf(x, "%s/%s", s->name, name);
148
149 FILE *f = fopen(x, "w");
150
151 if (!f)
152 fatal("Cannot write to %s\n", x);
153
154 fprintf(f, "%d\n", n);
155 fclose(f);
156}
157
158/*
159 * Put a size string together
160 */
161int store_size(char *buffer, unsigned long value)
162{
163 unsigned long divisor = 1;
164 char trailer = 0;
165 int n;
166
167 if (value > 1000000000UL) {
168 divisor = 100000000UL;
169 trailer = 'G';
170 } else if (value > 1000000UL) {
171 divisor = 100000UL;
172 trailer = 'M';
173 } else if (value > 1000UL) {
174 divisor = 100;
175 trailer = 'K';
176 }
177
178 value /= divisor;
179 n = sprintf(buffer, "%ld",value);
180 if (trailer) {
181 buffer[n] = trailer;
182 n++;
183 buffer[n] = 0;
184 }
185 if (divisor != 1) {
186 memmove(buffer + n - 2, buffer + n - 3, 4);
187 buffer[n-2] = '.';
188 n++;
189 }
190 return n;
191}
192
193void decode_numa_list(int *numa, char *t)
194{
195 int node;
196 int nr;
197
198 memset(numa, 0, MAX_NODES * sizeof(int));
199
200 while (*t == 'N') {
201 t++;
202 node = strtoul(t, &t, 10);
203 if (*t == '=') {
204 t++;
205 nr = strtoul(t, &t, 10);
206 numa[node] = nr;
207 if (node > highest_node)
208 highest_node = node;
209 }
210 while (*t == ' ')
211 t++;
212 }
213}
214
215void slab_validate(struct slabinfo *s)
216{
217 set_obj(s, "validate", 1);
218}
219
220void slab_shrink(struct slabinfo *s)
221{
222 set_obj(s, "shrink", 1);
223}
224
225int line = 0;
226
227void first_line(void)
228{
229 printf("Name Objects Objsize Space "
230 "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n");
231}
232
233/*
234 * Find the shortest alias of a slab
235 */
236struct aliasinfo *find_one_alias(struct slabinfo *find)
237{
238 struct aliasinfo *a;
239 struct aliasinfo *best = NULL;
240
241 for(a = aliasinfo;a < aliasinfo + aliases; a++) {
242 if (a->slab == find &&
243 (!best || strlen(best->name) < strlen(a->name))) {
244 best = a;
245 if (strncmp(a->name,"kmall", 5) == 0)
246 return best;
247 }
248 }
249 if (best)
250 return best;
251 fatal("Cannot find alias for %s\n", find->name);
252 return NULL;
253}
254
255unsigned long slab_size(struct slabinfo *s)
256{
257 return s->slabs * (page_size << s->order);
258}
259
260
261void slabcache(struct slabinfo *s)
262{
263 char size_str[20];
264 char dist_str[40];
265 char flags[20];
266 char *p = flags;
267
268 if (skip_zero && !s->slabs)
269 return;
270
271 store_size(size_str, slab_size(s));
272 sprintf(dist_str,"%lu/%lu/%d", s->slabs, s->partial, s->cpu_slabs);
273
274 if (!line++)
275 first_line();
276
277 if (s->aliases)
278 *p++ = '*';
279 if (s->cache_dma)
280 *p++ = 'd';
281 if (s->hwcache_align)
282 *p++ = 'A';
283 if (s->poison)
284 *p++ = 'P';
285 if (s->reclaim_account)
286 *p++ = 'a';
287 if (s->red_zone)
288 *p++ = 'Z';
289 if (s->sanity_checks)
290 *p++ = 'F';
291 if (s->store_user)
292 *p++ = 'U';
293 if (s->trace)
294 *p++ = 'T';
295
296 *p = 0;
297 printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
298 s->name, s->objects, s->object_size, size_str, dist_str,
299 s->objs_per_slab, s->order,
300 s->slabs ? (s->partial * 100) / s->slabs : 100,
301 s->slabs ? (s->objects * s->object_size * 100) /
302 (s->slabs * (page_size << s->order)) : 100,
303 flags);
304}
305
306void slab_numa(struct slabinfo *s)
307{
308 int node;
309
310 if (!highest_node)
311 fatal("No NUMA information available.\n");
312
313 if (skip_zero && !s->slabs)
314 return;
315
316 if (!line) {
317 printf("\nSlab Node ");
318 for(node = 0; node <= highest_node; node++)
319 printf(" %4d", node);
320 printf("\n----------------------");
321 for(node = 0; node <= highest_node; node++)
322 printf("-----");
323 printf("\n");
324 }
325 printf("%-21s ", s->name);
326 for(node = 0; node <= highest_node; node++) {
327 char b[20];
328
329 store_size(b, s->numa[node]);
330 printf(" %4s", b);
331 }
332 printf("\n");
333 line++;
334}
335
336void show_tracking(struct slabinfo *s)
337{
338 printf("\n%s: Calls to allocate a slab object\n", s->name);
339 printf("---------------------------------------------------\n");
340 if (read_obj("alloc_calls"))
341 printf(buffer);
342
343 printf("%s: Calls to free a slab object\n", s->name);
344 printf("-----------------------------------------------\n");
345 if (read_obj("free_calls"))
346 printf(buffer);
347
348}
349
350void totals(void)
351{
352 struct slabinfo *s;
353
354 int used_slabs = 0;
355 char b1[20], b2[20], b3[20], b4[20];
356 unsigned long long max = 1ULL << 63;
357
358 /* Object size */
359 unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
360
361 /* Number of partial slabs in a slabcache */
362 unsigned long long min_partial = max, max_partial = 0,
363 avg_partial, total_partial = 0;
364
365 /* Number of slabs in a slab cache */
366 unsigned long long min_slabs = max, max_slabs = 0,
367 avg_slabs, total_slabs = 0;
368
369 /* Size of the whole slab */
370 unsigned long long min_size = max, max_size = 0,
371 avg_size, total_size = 0;
372
373 /* Bytes used for object storage in a slab */
374 unsigned long long min_used = max, max_used = 0,
375 avg_used, total_used = 0;
376
377 /* Waste: Bytes used for alignment and padding */
378 unsigned long long min_waste = max, max_waste = 0,
379 avg_waste, total_waste = 0;
380 /* Number of objects in a slab */
381 unsigned long long min_objects = max, max_objects = 0,
382 avg_objects, total_objects = 0;
383 /* Waste per object */
384 unsigned long long min_objwaste = max,
385 max_objwaste = 0, avg_objwaste,
386 total_objwaste = 0;
387
388 /* Memory per object */
389 unsigned long long min_memobj = max,
390 max_memobj = 0, avg_memobj,
391 total_objsize = 0;
392
393 /* Percentage of partial slabs per slab */
394 unsigned long min_ppart = 100, max_ppart = 0,
395 avg_ppart, total_ppart = 0;
396
397 /* Number of objects in partial slabs */
398 unsigned long min_partobj = max, max_partobj = 0,
399 avg_partobj, total_partobj = 0;
400
401 /* Percentage of partial objects of all objects in a slab */
402 unsigned long min_ppartobj = 100, max_ppartobj = 0,
403 avg_ppartobj, total_ppartobj = 0;
404
405
406 for (s = slabinfo; s < slabinfo + slabs; s++) {
407 unsigned long long size;
408 unsigned long used;
409 unsigned long long wasted;
410 unsigned long long objwaste;
411 long long objects_in_partial_slabs;
412 unsigned long percentage_partial_slabs;
413 unsigned long percentage_partial_objs;
414
415 if (!s->slabs || !s->objects)
416 continue;
417
418 used_slabs++;
419
420 size = slab_size(s);
421 used = s->objects * s->object_size;
422 wasted = size - used;
423 objwaste = s->slab_size - s->object_size;
424
425 objects_in_partial_slabs = s->objects -
426 (s->slabs - s->partial - s ->cpu_slabs) *
427 s->objs_per_slab;
428
429 if (objects_in_partial_slabs < 0)
430 objects_in_partial_slabs = 0;
431
432 percentage_partial_slabs = s->partial * 100 / s->slabs;
433 if (percentage_partial_slabs > 100)
434 percentage_partial_slabs = 100;
435
436 percentage_partial_objs = objects_in_partial_slabs * 100
437 / s->objects;
438
439 if (percentage_partial_objs > 100)
440 percentage_partial_objs = 100;
441
442 if (s->object_size < min_objsize)
443 min_objsize = s->object_size;
444 if (s->partial < min_partial)
445 min_partial = s->partial;
446 if (s->slabs < min_slabs)
447 min_slabs = s->slabs;
448 if (size < min_size)
449 min_size = size;
450 if (wasted < min_waste)
451 min_waste = wasted;
452 if (objwaste < min_objwaste)
453 min_objwaste = objwaste;
454 if (s->objects < min_objects)
455 min_objects = s->objects;
456 if (used < min_used)
457 min_used = used;
458 if (objects_in_partial_slabs < min_partobj)
459 min_partobj = objects_in_partial_slabs;
460 if (percentage_partial_slabs < min_ppart)
461 min_ppart = percentage_partial_slabs;
462 if (percentage_partial_objs < min_ppartobj)
463 min_ppartobj = percentage_partial_objs;
464 if (s->slab_size < min_memobj)
465 min_memobj = s->slab_size;
466
467 if (s->object_size > max_objsize)
468 max_objsize = s->object_size;
469 if (s->partial > max_partial)
470 max_partial = s->partial;
471 if (s->slabs > max_slabs)
472 max_slabs = s->slabs;
473 if (size > max_size)
474 max_size = size;
475 if (wasted > max_waste)
476 max_waste = wasted;
477 if (objwaste > max_objwaste)
478 max_objwaste = objwaste;
479 if (s->objects > max_objects)
480 max_objects = s->objects;
481 if (used > max_used)
482 max_used = used;
483 if (objects_in_partial_slabs > max_partobj)
484 max_partobj = objects_in_partial_slabs;
485 if (percentage_partial_slabs > max_ppart)
486 max_ppart = percentage_partial_slabs;
487 if (percentage_partial_objs > max_ppartobj)
488 max_ppartobj = percentage_partial_objs;
489 if (s->slab_size > max_memobj)
490 max_memobj = s->slab_size;
491
492 total_partial += s->partial;
493 total_slabs += s->slabs;
494 total_size += size;
495 total_waste += wasted;
496
497 total_objects += s->objects;
498 total_used += used;
499 total_partobj += objects_in_partial_slabs;
500 total_ppart += percentage_partial_slabs;
501 total_ppartobj += percentage_partial_objs;
502
503 total_objwaste += s->objects * objwaste;
504 total_objsize += s->objects * s->slab_size;
505 }
506
507 if (!total_objects) {
508 printf("No objects\n");
509 return;
510 }
511 if (!used_slabs) {
512 printf("No slabs\n");
513 return;
514 }
515
516 /* Per slab averages */
517 avg_partial = total_partial / used_slabs;
518 avg_slabs = total_slabs / used_slabs;
519 avg_size = total_size / used_slabs;
520 avg_waste = total_waste / used_slabs;
521
522 avg_objects = total_objects / used_slabs;
523 avg_used = total_used / used_slabs;
524 avg_partobj = total_partobj / used_slabs;
525 avg_ppart = total_ppart / used_slabs;
526 avg_ppartobj = total_ppartobj / used_slabs;
527
528 /* Per object object sizes */
529 avg_objsize = total_used / total_objects;
530 avg_objwaste = total_objwaste / total_objects;
531 avg_partobj = total_partobj * 100 / total_objects;
532 avg_memobj = total_objsize / total_objects;
533
534 printf("Slabcache Totals\n");
535 printf("----------------\n");
536 printf("Slabcaches : %3d Aliases : %3d->%-3d Active: %3d\n",
537 slabs, aliases, alias_targets, used_slabs);
538
539 store_size(b1, total_size);store_size(b2, total_waste);
540 store_size(b3, total_waste * 100 / total_used);
541 printf("Memory used: %6s # Loss : %6s MRatio: %6s%%\n", b1, b2, b3);
542
543 store_size(b1, total_objects);store_size(b2, total_partobj);
544 store_size(b3, total_partobj * 100 / total_objects);
545 printf("# Objects : %6s # PartObj: %6s ORatio: %6s%%\n", b1, b2, b3);
546
547 printf("\n");
548 printf("Per Cache Average Min Max Total\n");
549 printf("---------------------------------------------------------\n");
550
551 store_size(b1, avg_objects);store_size(b2, min_objects);
552 store_size(b3, max_objects);store_size(b4, total_objects);
553 printf("#Objects %10s %10s %10s %10s\n",
554 b1, b2, b3, b4);
555
556 store_size(b1, avg_slabs);store_size(b2, min_slabs);
557 store_size(b3, max_slabs);store_size(b4, total_slabs);
558 printf("#Slabs %10s %10s %10s %10s\n",
559 b1, b2, b3, b4);
560
561 store_size(b1, avg_partial);store_size(b2, min_partial);
562 store_size(b3, max_partial);store_size(b4, total_partial);
563 printf("#PartSlab %10s %10s %10s %10s\n",
564 b1, b2, b3, b4);
565 store_size(b1, avg_ppart);store_size(b2, min_ppart);
566 store_size(b3, max_ppart);
567 store_size(b4, total_partial * 100 / total_slabs);
568 printf("%%PartSlab %10s%% %10s%% %10s%% %10s%%\n",
569 b1, b2, b3, b4);
570
571 store_size(b1, avg_partobj);store_size(b2, min_partobj);
572 store_size(b3, max_partobj);
573 store_size(b4, total_partobj);
574 printf("PartObjs %10s %10s %10s %10s\n",
575 b1, b2, b3, b4);
576
577 store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
578 store_size(b3, max_ppartobj);
579 store_size(b4, total_partobj * 100 / total_objects);
580 printf("%% PartObj %10s%% %10s%% %10s%% %10s%%\n",
581 b1, b2, b3, b4);
582
583 store_size(b1, avg_size);store_size(b2, min_size);
584 store_size(b3, max_size);store_size(b4, total_size);
585 printf("Memory %10s %10s %10s %10s\n",
586 b1, b2, b3, b4);
587
588 store_size(b1, avg_used);store_size(b2, min_used);
589 store_size(b3, max_used);store_size(b4, total_used);
590 printf("Used %10s %10s %10s %10s\n",
591 b1, b2, b3, b4);
592
593 store_size(b1, avg_waste);store_size(b2, min_waste);
594 store_size(b3, max_waste);store_size(b4, total_waste);
595 printf("Loss %10s %10s %10s %10s\n",
596 b1, b2, b3, b4);
597
598 printf("\n");
599 printf("Per Object Average Min Max\n");
600 printf("---------------------------------------------\n");
601
602 store_size(b1, avg_memobj);store_size(b2, min_memobj);
603 store_size(b3, max_memobj);
604 printf("Memory %10s %10s %10s\n",
605 b1, b2, b3);
606 store_size(b1, avg_objsize);store_size(b2, min_objsize);
607 store_size(b3, max_objsize);
608 printf("User %10s %10s %10s\n",
609 b1, b2, b3);
610
611 store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
612 store_size(b3, max_objwaste);
613 printf("Loss %10s %10s %10s\n",
614 b1, b2, b3);
615}
616
617void sort_slabs(void)
618{
619 struct slabinfo *s1,*s2;
620
621 for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
622 for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
623 int result;
624
625 if (sort_size)
626 result = slab_size(s1) < slab_size(s2);
627 else
628 result = strcasecmp(s1->name, s2->name);
629
630 if (show_inverted)
631 result = -result;
632
633 if (result > 0) {
634 struct slabinfo t;
635
636 memcpy(&t, s1, sizeof(struct slabinfo));
637 memcpy(s1, s2, sizeof(struct slabinfo));
638 memcpy(s2, &t, sizeof(struct slabinfo));
639 }
640 }
641 }
642}
643
644void sort_aliases(void)
645{
646 struct aliasinfo *a1,*a2;
647
648 for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) {
649 for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) {
650 char *n1, *n2;
651
652 n1 = a1->name;
653 n2 = a2->name;
654 if (show_alias && !show_inverted) {
655 n1 = a1->ref;
656 n2 = a2->ref;
657 }
658 if (strcasecmp(n1, n2) > 0) {
659 struct aliasinfo t;
660
661 memcpy(&t, a1, sizeof(struct aliasinfo));
662 memcpy(a1, a2, sizeof(struct aliasinfo));
663 memcpy(a2, &t, sizeof(struct aliasinfo));
664 }
665 }
666 }
667}
668
669void link_slabs(void)
670{
671 struct aliasinfo *a;
672 struct slabinfo *s;
673
674 for (a = aliasinfo; a < aliasinfo + aliases; a++) {
675
676 for(s = slabinfo; s < slabinfo + slabs; s++)
677 if (strcmp(a->ref, s->name) == 0) {
678 a->slab = s;
679 s->refs++;
680 break;
681 }
682 if (s == slabinfo + slabs)
683 fatal("Unresolved alias %s\n", a->ref);
684 }
685}
686
687void alias(void)
688{
689 struct aliasinfo *a;
690 char *active = NULL;
691
692 sort_aliases();
693 link_slabs();
694
695 for(a = aliasinfo; a < aliasinfo + aliases; a++) {
696
697 if (!show_single_ref && a->slab->refs == 1)
698 continue;
699
700 if (!show_inverted) {
701 if (active) {
702 if (strcmp(a->slab->name, active) == 0) {
703 printf(" %s", a->name);
704 continue;
705 }
706 }
707 printf("\n%-20s <- %s", a->slab->name, a->name);
708 active = a->slab->name;
709 }
710 else
711 printf("%-20s -> %s\n", a->name, a->slab->name);
712 }
713 if (active)
714 printf("\n");
715}
716
717
718void rename_slabs(void)
719{
720 struct slabinfo *s;
721 struct aliasinfo *a;
722
723 for (s = slabinfo; s < slabinfo + slabs; s++) {
724 if (*s->name != ':')
725 continue;
726
727 if (s->refs > 1 && !show_first_alias)
728 continue;
729
730 a = find_one_alias(s);
731
732 s->name = a->name;
733 }
734}
735
736int slab_mismatch(char *slab)
737{
738 return regexec(&pattern, slab, 0, NULL, 0);
739}
740
741void read_slab_dir(void)
742{
743 DIR *dir;
744 struct dirent *de;
745 struct slabinfo *slab = slabinfo;
746 struct aliasinfo *alias = aliasinfo;
747 char *p;
748 char *t;
749 int count;
750
751 dir = opendir(".");
752 while ((de = readdir(dir))) {
753 if (de->d_name[0] == '.' ||
754 slab_mismatch(de->d_name))
755 continue;
756 switch (de->d_type) {
757 case DT_LNK:
758 alias->name = strdup(de->d_name);
759 count = readlink(de->d_name, buffer, sizeof(buffer));
760
761 if (count < 0)
762 fatal("Cannot read symlink %s\n", de->d_name);
763
764 buffer[count] = 0;
765 p = buffer + count;
766 while (p > buffer && p[-1] != '/')
767 p--;
768 alias->ref = strdup(p);
769 alias++;
770 break;
771 case DT_DIR:
772 if (chdir(de->d_name))
773 fatal("Unable to access slab %s\n", slab->name);
774 slab->name = strdup(de->d_name);
775 slab->alias = 0;
776 slab->refs = 0;
777 slab->aliases = get_obj("aliases");
778 slab->align = get_obj("align");
779 slab->cache_dma = get_obj("cache_dma");
780 slab->cpu_slabs = get_obj("cpu_slabs");
781 slab->destroy_by_rcu = get_obj("destroy_by_rcu");
782 slab->hwcache_align = get_obj("hwcache_align");
783 slab->object_size = get_obj("object_size");
784 slab->objects = get_obj("objects");
785 slab->objs_per_slab = get_obj("objs_per_slab");
786 slab->order = get_obj("order");
787 slab->partial = get_obj("partial");
788 slab->partial = get_obj_and_str("partial", &t);
789 decode_numa_list(slab->numa_partial, t);
790 slab->poison = get_obj("poison");
791 slab->reclaim_account = get_obj("reclaim_account");
792 slab->red_zone = get_obj("red_zone");
793 slab->sanity_checks = get_obj("sanity_checks");
794 slab->slab_size = get_obj("slab_size");
795 slab->slabs = get_obj_and_str("slabs", &t);
796 decode_numa_list(slab->numa, t);
797 slab->store_user = get_obj("store_user");
798 slab->trace = get_obj("trace");
799 chdir("..");
800 if (slab->name[0] == ':')
801 alias_targets++;
802 slab++;
803 break;
804 default :
805 fatal("Unknown file type %lx\n", de->d_type);
806 }
807 }
808 closedir(dir);
809 slabs = slab - slabinfo;
810 aliases = alias - aliasinfo;
811 if (slabs > MAX_SLABS)
812 fatal("Too many slabs\n");
813 if (aliases > MAX_ALIASES)
814 fatal("Too many aliases\n");
815}
816
817void output_slabs(void)
818{
819 struct slabinfo *slab;
820
821 for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
822
823 if (slab->alias)
824 continue;
825
826
827 if (show_numa)
828 slab_numa(slab);
829 else
830 if (show_track)
831 show_tracking(slab);
832 else
833 if (validate)
834 slab_validate(slab);
835 else
836 if (shrink)
837 slab_shrink(slab);
838 else {
839 if (show_slab)
840 slabcache(slab);
841 }
842 }
843}
844
845struct option opts[] = {
846 { "aliases", 0, NULL, 'a' },
847 { "slabs", 0, NULL, 'l' },
848 { "numa", 0, NULL, 'n' },
849 { "zero", 0, NULL, 'z' },
850 { "help", 0, NULL, 'h' },
851 { "validate", 0, NULL, 'v' },
852 { "first-alias", 0, NULL, 'f' },
853 { "shrink", 0, NULL, 's' },
854 { "track", 0, NULL, 't'},
855 { "inverted", 0, NULL, 'i'},
856 { "1ref", 0, NULL, '1'},
857 { NULL, 0, NULL, 0 }
858};
859
860int main(int argc, char *argv[])
861{
862 int c;
863 int err;
864 char *pattern_source;
865
866 page_size = getpagesize();
867 if (chdir("/sys/slab"))
868 fatal("This kernel does not have SLUB support.\n");
869
870 while ((c = getopt_long(argc, argv, "afhil1npstvzTS", opts, NULL)) != -1)
871 switch(c) {
872 case '1':
873 show_single_ref = 1;
874 break;
875 case 'a':
876 show_alias = 1;
877 break;
878 case 'f':
879 show_first_alias = 1;
880 break;
881 case 'h':
882 usage();
883 return 0;
884 case 'i':
885 show_inverted = 1;
886 break;
887 case 'n':
888 show_numa = 1;
889 break;
890 case 's':
891 shrink = 1;
892 break;
893 case 'l':
894 show_slab = 1;
895 break;
896 case 't':
897 show_track = 1;
898 break;
899 case 'v':
900 validate = 1;
901 break;
902 case 'z':
903 skip_zero = 0;
904 break;
905 case 'T':
906 show_totals = 1;
907 break;
908 case 'S':
909 sort_size = 1;
910 break;
911
912 default:
913 fatal("%s: Invalid option '%c'\n", argv[0], optopt);
914
915 }
916
917 if (!show_slab && !show_alias && !show_track
918 && !validate && !shrink)
919 show_slab = 1;
920
921 if (argc > optind)
922 pattern_source = argv[optind];
923 else
924 pattern_source = ".*";
925
926 err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
927 if (err)
928 fatal("%s: Invalid pattern '%s' code %d\n",
929 argv[0], pattern_source, err);
930 read_slab_dir();
931 if (show_alias)
932 alias();
933 else
934 if (show_totals)
935 totals();
936 else {
937 link_slabs();
938 rename_slabs();
939 sort_slabs();
940 output_slabs();
941 }
942 return 0;
943}
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
new file mode 100644
index 000000000000..727c8d81aeaf
--- /dev/null
+++ b/Documentation/vm/slub.txt
@@ -0,0 +1,113 @@
1Short users guide for SLUB
2--------------------------
3
4First of all slub should transparently replace SLAB. If you enable
5SLUB then everything should work the same (Note the word "should".
6There is likely not much value in that word at this point).
7
8The basic philosophy of SLUB is very different from SLAB. SLAB
9requires rebuilding the kernel to activate debug options for all
10SLABS. SLUB always includes full debugging but its off by default.
11SLUB can enable debugging only for selected slabs in order to avoid
12an impact on overall system performance which may make a bug more
13difficult to find.
14
15In order to switch debugging on one can add a option "slub_debug"
16to the kernel command line. That will enable full debugging for
17all slabs.
18
19Typically one would then use the "slabinfo" command to get statistical
20data and perform operation on the slabs. By default slabinfo only lists
21slabs that have data in them. See "slabinfo -h" for more options when
22running the command. slabinfo can be compiled with
23
24gcc -o slabinfo Documentation/vm/slabinfo.c
25
26Some of the modes of operation of slabinfo require that slub debugging
27be enabled on the command line. F.e. no tracking information will be
28available without debugging on and validation can only partially
29be performed if debugging was not switched on.
30
31Some more sophisticated uses of slub_debug:
32-------------------------------------------
33
34Parameters may be given to slub_debug. If none is specified then full
35debugging is enabled. Format:
36
37slub_debug=<Debug-Options> Enable options for all slabs
38slub_debug=<Debug-Options>,<slab name>
39 Enable options only for select slabs
40
41Possible debug options are
42 F Sanity checks on (enables SLAB_DEBUG_FREE. Sorry
43 SLAB legacy issues)
44 Z Red zoning
45 P Poisoning (object and padding)
46 U User tracking (free and alloc)
47 T Trace (please only use on single slabs)
48
49F.e. in order to boot just with sanity checks and red zoning one would specify:
50
51 slub_debug=FZ
52
53Trying to find an issue in the dentry cache? Try
54
55 slub_debug=,dentry_cache
56
57to only enable debugging on the dentry cache.
58
59Red zoning and tracking may realign the slab. We can just apply sanity checks
60to the dentry cache with
61
62 slub_debug=F,dentry_cache
63
64In case you forgot to enable debugging on the kernel command line: It is
65possible to enable debugging manually when the kernel is up. Look at the
66contents of:
67
68/sys/slab/<slab name>/
69
70Look at the writable files. Writing 1 to them will enable the
71corresponding debug option. All options can be set on a slab that does
72not contain objects. If the slab already contains objects then sanity checks
73and tracing may only be enabled. The other options may cause the realignment
74of objects.
75
76Careful with tracing: It may spew out lots of information and never stop if
77used on the wrong slab.
78
79SLAB Merging
80------------
81
82If no debugging is specified then SLUB may merge similar slabs together
83in order to reduce overhead and increase cache hotness of objects.
84slabinfo -a displays which slabs were merged together.
85
86Getting more performance
87------------------------
88
89To some degree SLUB's performance is limited by the need to take the
90list_lock once in a while to deal with partial slabs. That overhead is
91governed by the order of the allocation for each slab. The allocations
92can be influenced by kernel parameters:
93
94slub_min_objects=x (default 8)
95slub_min_order=x (default 0)
96slub_max_order=x (default 4)
97
98slub_min_objects allows to specify how many objects must at least fit
99into one slab in order for the allocation order to be acceptable.
100In general slub will be able to perform this number of allocations
101on a slab without consulting centralized resources (list_lock) where
102contention may occur.
103
104slub_min_order specifies a minim order of slabs. A similar effect like
105slub_min_objects.
106
107slub_max_order specified the order at which slub_min_objects should no
108longer be checked. This is useful to avoid SLUB trying to generate
109super large order pages to fit slub_min_objects of a slab cache with
110large object sizes into one high order page.
111
112
113Christoph Lameter, <clameter@sgi.com>, April 10, 2007