Slab allocator

Here is some information on the slab allocator in Linux.

(As I write this (8/2007), a new allocator "slub" has been submitted for inclusion in mainline. It remains to be seen if this means that the slab allocator will be removed.)

You can get a lot of information about the status of the slab allocator by examining the data in /proc/slabinfo.

The slab allocator is a system of allocating memory that is optimized for the allocation and freeing of same-sized memory objects. The slab allocator organizes the memory into caches, slabs and objects. A cache consists of multiple slabs, and each slab is a contiguous region of memory containing objects of all the same size.

When a cache is created, the creator specifies the object size and a name for the cache, as well as some flags. When an object is allocated, if there are no free objects in any slabs, a new slab is allocated. For small objects, a slab is a single page of memory. For example, on a system with 4096-byte pages, a cache of objects that are 160 bytes each would consist of slabs containing 24 objects per slab. Subsequent calls to allocate objects of the same size are quick, because the page has already been allocated for the object. Calls to free an object are also quick. If the system gets into a low memory condition, slabs with no allocated objects can be freed. Fragmentation is reduced (hopefully) because similar sized objects are grouped together.

sample of /proc/slabinfo
/proc # cat /proc/slabinfo slabinfo - version: 2.1 >  rpc_buffers          10     10   2048    2    1 : tunables   24   12    0 : slabdata      5      5      0 rpc_tasks            24     24    160   24    1 : tunables  120   60    0 : slabdata      1      1      0 rpc_inode_cache      10     18    416    9    1 : tunables   54   27    0 : slabdata      2      2      0 UNIX                  2     10    384   10    1 : tunables   54   27    0 : slabdata      1      1      0 flow_cache            0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0 cfq_io_context        0      0     88   44    1 : tunables  120   60    0 : slabdata      0      0      0 cfq_queue             0      0     88   44    1 : tunables  120   60    0 : slabdata      0      0      0 nfs_write_data       36     40    480    8    1 : tunables   54   27    0 : slabdata      5      5      0 nfs_read_data        32     36    448    9    1 : tunables   54   27    0 : slabdata      4      4      0 nfs_inode_cache      76     78    608    6    1 : tunables   54   27    0 : slabdata     13     13      0 nfs_page              0      0     64   59    1 : tunables  120   60    0 : slabdata      0      0      0 squashfs_inode_cache     0      0    384   10    1 : tunables   54   27    0 : slabdata      0      0      0 ext2_inode_cache      0      0    432    9    1 : tunables   54   27    0 : slabdata      0      0      0 journal_handle        0      0     20  169    1 : tunables  120   60    0 : slabdata      0      0      0 journal_head          0      0     52   72    1 : tunables  120   60    0 : slabdata      0      0      0 revoke_table          0      0     12  254    1 : tunables  120   60    0 : slabdata      0      0      0 revoke_record         0      0     16  203    1 : tunables  120   60    0 : slabdata      0      0      0 ext3_inode_cache      0      0    472    8    1 : tunables   54   27    0 : slabdata      0      0      0 ext3_xattr            0      0     44   84    1 : tunables  120   60    0 : slabdata      0      0      0 dnotify_cache         0      0     20  169    1 : tunables  120   60    0 : slabdata      0      0      0 inotify_event_cache     0      0     28  127    1 : tunables  120   60    0 : slabdata      0      0      0 inotify_watch_cache     0      0     40   92    1 : tunables  120   60    0 : slabdata      0      0      0 kioctx                0      0    160   24    1 : tunables  120   60    0 : slabdata      0      0      0 kiocb                 0      0    160   24    1 : tunables  120   60    0 : slabdata      0      0      0 fasync_cache          0      0     16  203    1 : tunables  120   60    0 : slabdata      0      0      0 shmem_inode_cache     1      9    416    9    1 : tunables   54   27    0 : slabdata      1      1      0 posix_timers_cache     0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0 uid_cache             0      0     64   59    1 : tunables  120   60    0 : slabdata      0      0      0 UDP-Lite              0      0    480    8    1 : tunables   54   27    0 : slabdata      0      0      0 tcp_bind_bucket       1    203     16  203    1 : tunables  120   60    0 : slabdata      1      1      0 inet_peer_cache       0      0     64   59    1 : tunables  120   60    0 : slabdata      0      0      0 secpath_cache         0      0     32  113    1 : tunables  120   60    0 : slabdata      0      0      0 xfrm_dst_cache        0      0    256   15    1 : tunables  120   60    0 : slabdata      0      0      0 ip_fib_alias          9    113     32  113    1 : tunables  120   60    0 : slabdata      1      1      0 ip_fib_hash           9    113     32  113    1 : tunables  120   60    0 : slabdata      1      1      0 ip_dst_cache          2     15    256   15    1 : tunables  120   60    0 : slabdata      1      1      0 arp_cache             1     30    128   30    1 : tunables  120   60    0 : slabdata      1      1      0 RAW                   2      9    448    9    1 : tunables   54   27    0 : slabdata      1      1      0 UDP                   1      8    480    8    1 : tunables   54   27    0 : slabdata      1      1      0 tw_sock_TCP           0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0 request_sock_TCP      0      0     64   59    1 : tunables  120   60    0 : slabdata      0      0      0 TCP                   1      3   1056    3    1 : tunables   24   12    0 : slabdata      1      1      0 eventpoll_pwq         0      0     36  101    1 : tunables  120   60    0 : slabdata      0      0      0 eventpoll_epi         0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0 sgpool-128            2      2   2048    2    1 : tunables   24   12    0 : slabdata      1      1      0 sgpool-64             2      4   1024    4    1 : tunables   54   27    0 : slabdata      1      1      0 sgpool-32             2      8    512    8    1 : tunables   54   27    0 : slabdata      1      1      0 sgpool-16             2     15    256   15    1 : tunables  120   60    0 : slabdata      1      1      0 sgpool-8              2     30    128   30    1 : tunables  120   60    0 : slabdata      1      1      0 scsi_io_context       0      0    104   37    1 : tunables  120   60    0 : slabdata      0      0      0 blkdev_ioc            0      0     32  113    1 : tunables  120   60    0 : slabdata      0      0      0 blkdev_queue          9     12    900    4    1 : tunables   54   27    0 : slabdata      3      3      0 blkdev_requests       4     22    176   22    1 : tunables  120   60    0 : slabdata      1      1      0 biovec-256            2      2   3072    1    1 : tunables   24   12    0 : slabdata      2      2      0 biovec-128            2      2   1536    2    1 : tunables   24   12    0 : slabdata      1      1      0 biovec-64             2      5    768    5    1 : tunables   54   27    0 : slabdata      1      1      0 biovec-16             2     20    192   20    1 : tunables  120   60    0 : slabdata      1      1      0 biovec-4              2     59     64   59    1 : tunables  120   60    0 : slabdata      1      1      0 biovec-1              2    203     16  203    1 : tunables  120   60    0 : slabdata      1      1      0 bio                   2     59     64   59    1 : tunables  120   60    0 : slabdata      1      1      0 sock_inode_cache     12     20    384   10    1 : tunables   54   27    0 : slabdata      2      2      0 skbuff_fclone_cache     0      0    352   11    1 : tunables   54   27    0 : slabdata      0      0      0 skbuff_head_cache    16     24    160   24    1 : tunables  120   60    0 : slabdata      1      1      0 file_lock_cache       0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0 proc_inode_cache   1276   1276    336   11    1 : tunables   54   27    0 : slabdata    116    116      0 sigqueue              0      0    144   27    1 : tunables  120   60    0 : slabdata      0      0      0 radix_tree_node      34     39    288   13    1 : tunables   54   27    0 : slabdata      3      3      0 bdev_cache            1      9    448    9    1 : tunables   54   27    0 : slabdata      1      1      0 sysfs_dir_cache    1177   1248     48   78    1 : tunables  120   60    0 : slabdata     16     16      0 mnt_cache            16     30    128   30    1 : tunables  120   60    0 : slabdata      1      1      0 inode_cache         317    324    320   12    1 : tunables   54   27    0 : slabdata     27     27      0 dentry             1730   1736    124   31    1 : tunables  120   60    0 : slabdata     56     56      0 filp                 96     96    160   24    1 : tunables  120   60    0 : slabdata      4      4      0 names_cache           1      1   4096    1    1 : tunables   24   12    0 : slabdata      1      1      0 idr_layer_cache      70     87    136   29    1 : tunables  120   60    0 : slabdata      3      3      0 buffer_head           0      0     52   72    1 : tunables  120   60    0 : slabdata      0      0      0 mm_struct             9      9    416    9    1 : tunables   54   27    0 : slabdata      1      1      0 vm_area_struct      184    184     84   46    1 : tunables  120   60    0 : slabdata      4      4      0 fs_cache             20    113     32  113    1 : tunables  120   60    0 : slabdata      1      1      0 files_cache          20     20    192   20    1 : tunables  120   60    0 : slabdata      1      1      0 signal_cache         30     30    384   10    1 : tunables   54   27    0 : slabdata      3      3      0 sighand_cache        21     21   1312    3    1 : tunables   24   12    0 : slabdata      7      7      0 task_struct          24     24    672    6    1 : tunables   54   27    0 : slabdata      4      4      0 anon_vma             65    339      8  339    1 : tunables  120   60    0 : slabdata      1      1      0 pid                  36    101     36  101    1 : tunables  120   60    0 : slabdata      1      1      0 size-4194304(DMA)     0      0 4194304    1 1024 : tunables    1    1    0 : slabdata      0      0      0 size-4194304          0      0 4194304    1 1024 : tunables    1    1    0 : slabdata      0      0      0 size-2097152(DMA)     0      0 2097152    1  512 : tunables    1    1    0 : slabdata      0      0      0 size-2097152          0      0 2097152    1  512 : tunables    1    1    0 : slabdata      0      0      0 size-1048576(DMA)     0      0 1048576    1  256 : tunables    1    1    0 : slabdata      0      0      0 size-1048576          0      0 1048576    1  256 : tunables    1    1    0 : slabdata      0      0      0 size-524288(DMA)      0      0 524288    1  128 : tunables    1    1    0 : slabdata      0      0      0 size-524288           0      0 524288    1  128 : tunables    1    1    0 : slabdata      0      0      0 size-262144(DMA)      0      0 262144    1   64 : tunables    1    1    0 : slabdata      0      0      0 size-262144           0      0 262144    1   64 : tunables    1    1    0 : slabdata      0      0      0 size-131072(DMA)      0      0 131072    1   32 : tunables    8    4    0 : slabdata      0      0      0 size-131072           0      0 131072    1   32 : tunables    8    4    0 : slabdata      0      0      0 size-65536(DMA)       0      0  65536    1   16 : tunables    8    4    0 : slabdata      0      0      0 size-65536            0      0  65536    1   16 : tunables    8    4    0 : slabdata      0      0      0 size-32768(DMA)       0      0  32768    1    8 : tunables    8    4    0 : slabdata      0      0      0 size-32768            0      0  32768    1    8 : tunables    8    4    0 : slabdata      0      0      0 size-16384(DMA)       0      0  16384    1    4 : tunables    8    4    0 : slabdata      0      0      0 size-16384            0      0  16384    1    4 : tunables    8    4    0 : slabdata      0      0      0 size-8192(DMA)        0      0   8192    1    2 : tunables    8    4    0 : slabdata      0      0      0 size-8192             0      0   8192    1    2 : tunables    8    4    0 : slabdata      0      0      0 size-4096(DMA)        0      0   4096    1    1 : tunables   24   12    0 : slabdata      0      0      0 size-4096             4      4   4096    1    1 : tunables   24   12    0 : slabdata      4      4      0 size-2048(DMA)        0      0   2048    2    1 : tunables   24   12    0 : slabdata      0      0      0 size-2048            12     14   2048    2    1 : tunables   24   12    0 : slabdata      7      7      0 size-1024(DMA)        0      0   1024    4    1 : tunables   54   27    0 : slabdata      0      0      0 size-1024            11     12   1024    4    1 : tunables   54   27    0 : slabdata      3      3      0 size-512(DMA)         0      0    512    8    1 : tunables   54   27    0 : slabdata      0      0      0 size-512            208    208    512    8    1 : tunables   54   27    0 : slabdata     26     26      0 size-256(DMA)         0      0    256   15    1 : tunables  120   60    0 : slabdata      0      0      0 size-256             75     75    256   15    1 : tunables  120   60    0 : slabdata      5      5      0 size-192(DMA)         0      0    192   20    1 : tunables  120   60    0 : slabdata      0      0      0 size-192             40     40    192   20    1 : tunables  120   60    0 : slabdata      2      2      0 size-128(DMA)         0      0    128   30    1 : tunables  120   60    0 : slabdata      0      0      0 size-128             86     90    128   30    1 : tunables  120   60    0 : slabdata      3      3      0 size-96(DMA)          0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0 size-96             388    400     96   40    1 : tunables  120   60    0 : slabdata     10     10      0 size-64(DMA)          0      0     64   59    1 : tunables  120   60    0 : slabdata      0      0      0 size-32(DMA)          0      0     32  113    1 : tunables  120   60    0 : slabdata      0      0      0 size-64             451    472     64   59    1 : tunables  120   60    0 : slabdata      8      8      0 size-32             871    904     32  113    1 : tunables  120   60    0 : slabdata      8      8      0 kmem_cache          125    160     96   40    1 : tunables  120   60    0 : slabdata      4      4      0
 * 1) name                : tunables   : slabdata /proc/slabinfo


 * active_objs
 * After creating a slab cache, you allocate your objects out of that slab cache. This is the count of objects you currently have allocated out of the cache.


 * num_objs
 * This is the current total number of objects in the cache.


 * objsize:
 * This is the size of each allocated object. There is overhead to maintaining the cache, so with a 512byte object and a 4096-byte page size, you could fit 7 objects in a single page and you would waste 512-slab_overhead bytes per allocation.  Slab overhead varies with object size (smaller objects have more objects per allocation and require more overhead to track used vs. unused objects).


 * ojbsperslab
 * This is how many objects can be put into each slab. To find the amount of wasted bytes per slab, multiply the objsize by objperslab, and subtract this from pagesperslab times the pagesize (often 4096).


 * pagesperslab
 * This is the size of each slab in units of memory pages.  Page size is architecture specific, but the most common size is 4k (4096 bytes).  Some architectures have an 8k page size, and ia64 can do a 16k page size.  Each slab for the cache is pagesperslab * arch_page_size bytes at a time, and total memory used by this particular slab cache is num_slabs * pagesperslab * arch_page_size.


 * active_slabs
 * This is the number of slabs that have at least one object in use.


 * num_slabs
 * This is the number of slabs currently allocated for the given cache.

On SMP machines, the slab cache will keep a per CPU cache of objects so that an object freed on CPU0 will be reused on CPU0 instead of CPU1 if possible. This improves cache performance on SMP systems greatly.


 * limit
 * This is the limit on the number of free objects that can be stored in the per-CPU free list for this slab cache.


 * batch-count
 * On SMP systems, when we refill the available object list, instead of doing one object at a time, we do batch-count objects at a time.

Note that is CONFIG_SLAB_DEBUG is enabled, then you'll get more numbers on each line and the lines will have these fields:    : tunables  : slabdata  : globalstat        : cpustats

I don't have time to document these right now.

Source: Documenting slabinfo - article by Doug Ledford in 2003 (for the 2.4 kernel - may be obsolete for 2.6)

Programs
The 2.6.22 kernel includes a program called slabinfo.c, located at: Documentation/vm/slabinfo.c. This program can be used for debugging the slub allocator, not the slab allocator.