slab: Remove obj_size from struct kmem_slab
[akaros.git] / kern / include / slab.h
1 /*
2  * Copyright (c) 2009 The Regents of the University of California
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * Kevin Klues <klueska@cs.berkeley.edu>
5  * See LICENSE for details.
6  *
7  * Slab allocator, based on the SunOS 5.4 allocator paper.
8  *
9  * There is a list of kmem_cache, which are the caches of objects of a given
10  * size.  This list is sorted in order of size.  Each kmem_cache has three
11  * lists of slabs: full, partial, and empty.
12  *
13  * For large objects, the kmem_slabs point to bufctls, which have the address
14  * of their large buffers.  These slabs can consist of more than one contiguous
15  * page.
16  *
17  * For small objects, the slabs do not use the bufctls.  Instead, they point to
18  * the next free object in the slab.  The free objects themselves hold the
19  * address of the next free item.  The slab structure is stored at the end of
20  * the page.  There is only one page per slab.
21  *
22  * Be careful with source arenas and NOTOUCH.  If a cache's source arena is not
23  * page-aligned memory, you need to set NOTOUCH.  Otherwise, for small objects,
24  * a slab will be constructed that uses the source for a page of objects.
25  */
26
27 #pragma once
28
29 #include <ros/common.h>
30 #include <arch/mmu.h>
31 #include <sys/queue.h>
32 #include <atomic.h>
33 #include <hash_helper.h>
34 #include <arena.h>
35
36 /* Back in the day, their cutoff for "large objects" was 512B, based on
37  * measurements and on not wanting more than 1/8 of internal fragmentation. */
38 #define NUM_BUF_PER_SLAB 8
39 #define SLAB_LARGE_CUTOFF (PGSIZE / NUM_BUF_PER_SLAB)
40
41 #define KMC_NAME_SZ                             32
42
43 /* Cache creation flags: */
44 #define KMC_NOTOUCH                             0x0001  /* Can't use source/object's memory */
45 #define KMC_QCACHE                              0x0002  /* Cache is an arena's qcache */
46 #define __KMC_USE_BUFCTL                0x1000  /* Internal use */
47
48 struct kmem_slab;
49
50 /* Control block for buffers for large-object slabs */
51 struct kmem_bufctl {
52         BSD_LIST_ENTRY(kmem_bufctl) link;
53         void *buf_addr;
54         struct kmem_slab *my_slab;
55 };
56 BSD_LIST_HEAD(kmem_bufctl_list, kmem_bufctl);
57
58 /* Slabs contain the objects.  Can be either full, partial, or empty,
59  * determined by checking the number of objects busy vs total.  For large
60  * slabs, the bufctl list is used to find a free buffer.  For small, the void*
61  * is used instead.*/
62 struct kmem_slab {
63         TAILQ_ENTRY(kmem_slab) link;
64         size_t num_busy_obj;
65         size_t num_total_obj;
66         union {
67                 struct kmem_bufctl_list bufctl_freelist;
68                 void *free_small_obj;
69         };
70 };
71 TAILQ_HEAD(kmem_slab_list, kmem_slab);
72
73 /* Actual cache */
74 struct kmem_cache {
75         SLIST_ENTRY(kmem_cache) link;
76         spinlock_t cache_lock;
77         size_t obj_size;
78         size_t import_amt;
79         int align;
80         int flags;
81         struct arena *source;
82         struct kmem_slab_list full_slab_list;
83         struct kmem_slab_list partial_slab_list;
84         struct kmem_slab_list empty_slab_list;
85         void (*ctor)(void *, size_t);
86         void (*dtor)(void *, size_t);
87         unsigned long nr_cur_alloc;
88         struct hash_helper hh;
89         struct kmem_bufctl_list *alloc_hash;
90         struct kmem_bufctl_list static_hash[HASH_INIT_SZ];
91         char name[KMC_NAME_SZ];
92 };
93
94 /* List of all kmem_caches, sorted in order of size */
95 SLIST_HEAD(kmem_cache_list, kmem_cache);
96 extern struct kmem_cache_list kmem_caches;
97
98 /* Cache management */
99 struct kmem_cache *kmem_cache_create(const char *name, size_t obj_size,
100                                      int align, int flags,
101                                      struct arena *source,
102                                      void (*ctor)(void *, size_t),
103                                      void (*dtor)(void *, size_t));
104 void kmem_cache_destroy(struct kmem_cache *cp);
105 /* Front end: clients of caches use these */
106 void *kmem_cache_alloc(struct kmem_cache *cp, int flags);
107 void kmem_cache_free(struct kmem_cache *cp, void *buf);
108 /* Back end: internal functions */
109 void kmem_cache_init(void);
110 void kmem_cache_reap(struct kmem_cache *cp);
111 /* Low-level interface for initializing a cache. */
112 void __kmem_cache_create(struct kmem_cache *kc, const char *name,
113                          size_t obj_size, int align, int flags,
114                          struct arena *source,
115                          void (*ctor)(void *, size_t),
116                          void (*dtor)(void *, size_t));
117
118 /* Debug */
119 void print_kmem_cache(struct kmem_cache *kc);
120 void print_kmem_slab(struct kmem_slab *slab);