]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/dde/linux26/lib/src/arch/l4/kmem_cache.c
update
[l4.git] / l4 / pkg / dde / linux26 / lib / src / arch / l4 / kmem_cache.c
1 /*
2  * This file is part of DDE/Linux2.6.
3  *
4  * (c) 2006-2012 Bjoern Doebel <doebel@os.inf.tu-dresden.de>
5  *               Christian Helmuth <ch12@os.inf.tu-dresden.de>
6  *     economic rights: Technische Universitaet Dresden (Germany)
7  *
8  * This file is part of TUD:OS and distributed under the terms of the
9  * GNU General Public License 2.
10  * Please see the COPYING-GPL-2 file for details.
11  */
12
13 /*
14  * \brief   Kmem_cache implementation
15  *
16  * In Linux 2.6 this resides in mm/slab.c.
17  *
18  * I'll disregard the following function currently...
19  *
20  * extern struct kmem_cache *kmem_find_general_cachep(size_t size, gfp_t gfpflags);
21  * extern void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
22  */
23
24 /* Linux */
25 #include <linux/slab.h>
26
27 /* DDEKit */
28 #include <l4/dde/ddekit/memory.h>
29 #include <l4/dde/ddekit/lock.h>
30
31
32 /*******************
33  ** Configuration **
34  *******************/
35
36 #define DEBUG_SLAB 0
37
38 #if DEBUG_SLAB
39 # define DEBUG_SLAB_ALLOC 1
40 #else
41 # define DEBUG_SLAB_ALLOC 0
42 #endif
43
44 /*
45  * Kmem cache structure
46  */
47 struct kmem_cache
48 {
49         const char         *name;                 /**< cache name */
50         unsigned            size;                 /**< obj size */
51
52         struct ddekit_slab *ddekit_slab_cache;    /**< backing DDEKit cache */
53         ddekit_lock_t      cache_lock;            /**< lock */
54         void (*ctor)(void *);                     /**< object constructor */
55 };
56
57
58 /**
59  * Return size of objects in cache
60  */
61 unsigned int kmem_cache_size(struct kmem_cache *cache)
62 {
63         return cache->size;
64 }
65
66
67 /**
68  * Return name of cache
69  */
70 const char *kmem_cache_name(struct kmem_cache *cache)
71 {
72         return cache->name;
73 }
74
75
76 /**
77  * kmem_cache_shrink - Shrink a cache.
78  * @cachep: The cache to shrink.
79  *
80  * Releases as many slabs as possible for a cache.
81  * To help debugging, a zero exit status indicates all slabs were released.
82  */
83 int kmem_cache_shrink(struct kmem_cache *cache)
84 {
85         /* noop */
86         return 1;
87 }
88
89
90 /**
91  * kmem_cache_free - Deallocate an object
92  * @cachep: The cache the allocation was from.
93  * @objp: The previously allocated object.
94  *
95  * Free an object which was previously allocated from this
96  * cache.
97  */
98 void kmem_cache_free(struct kmem_cache *cache, void *objp)
99 {
100         ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" (%p)", cache->name, objp);
101
102         ddekit_lock_lock(&cache->cache_lock);
103         ddekit_slab_free(cache->ddekit_slab_cache, objp);
104         ddekit_lock_unlock(&cache->cache_lock);
105 }
106
107
108 /**
109  * kmem_cache_alloc - Allocate an object
110  * @cachep: The cache to allocate from.
111  * @flags: See kmalloc().
112  *
113  * Allocate an object from this cache.  The flags are only relevant
114  * if the cache has no available objects.
115  */
116 void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags)
117 {
118         void *ret;
119
120         ddekit_log(DEBUG_SLAB_ALLOC, "\"%s\" flags=%x", cache->name, flags);
121
122         ddekit_lock_lock(&cache->cache_lock);
123         ret = ddekit_slab_alloc(cache->ddekit_slab_cache);
124         ddekit_lock_unlock(&cache->cache_lock);
125
126         // XXX: is it valid to run ctor AND memset to zero?
127         if (flags & __GFP_ZERO)
128                 memset(ret, 0, cache->size);
129         else if (cache->ctor)
130                 cache->ctor(ret);
131
132         return ret;
133 }
134
135
136 /**
137  * kmem_cache_destroy - delete a cache
138  * @cachep: the cache to destroy
139  *
140  * Remove a struct kmem_cache object from the slab cache.
141  * Returns 0 on success.
142  *
143  * It is expected this function will be called by a module when it is
144  * unloaded.  This will remove the cache completely, and avoid a duplicate
145  * cache being allocated each time a module is loaded and unloaded, if the
146  * module doesn't have persistent in-kernel storage across loads and unloads.
147  *
148  * The cache must be empty before calling this function.
149  *
150  * The caller must guarantee that noone will allocate memory from the cache
151  * during the kmem_cache_destroy().
152  */
153 void kmem_cache_destroy(struct kmem_cache *cache)
154 {
155         ddekit_log(DEBUG_SLAB, "\"%s\"", cache->name);
156
157         ddekit_slab_destroy(cache->ddekit_slab_cache);
158         ddekit_simple_free(cache);
159 }
160
161
162 /**
163  * kmem_cache_create - Create a cache.
164  * @name: A string which is used in /proc/slabinfo to identify this cache.
165  * @size: The size of objects to be created in this cache.
166  * @align: The required alignment for the objects.
167  * @flags: SLAB flags
168  * @ctor: A constructor for the objects.
169  *
170  * Returns a ptr to the cache on success, NULL on failure.
171  * Cannot be called within a int, but can be interrupted.
172  * The @ctor is run when new pages are allocated by the cache
173  * and the @dtor is run before the pages are handed back.
174  *
175  * @name must be valid until the cache is destroyed. This implies that
176  * the module calling this has to destroy the cache before getting unloaded.
177  *
178  * The flags are
179  *
180  * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
181  * to catch references to uninitialised memory.
182  *
183  * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check
184  * for buffer overruns.
185  *
186  * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware
187  * cacheline.  This can be beneficial if you're counting cycles as closely
188  * as davem.
189  */
190 struct kmem_cache * kmem_cache_create(const char *name, size_t size, size_t align,
191                                       unsigned long flags,
192                                       void (*ctor)(void *))
193 {
194         ddekit_log(DEBUG_SLAB, "\"%s\" obj_size=%d", name, size);
195
196         struct kmem_cache *cache;
197
198         if (!name) {
199                 printk("kmem_cache name reqeuired\n");
200                 return 0;
201         }
202
203         cache = ddekit_simple_malloc(sizeof(*cache));
204         if (!cache) {
205                 printk("No memory for slab cache\n");
206                 return 0;
207         }
208
209         /* Initialize a physically contiguous cache for kmem */
210         if (!(cache->ddekit_slab_cache = ddekit_slab_init(size, 1))) {
211                 printk("DDEKit slab init failed\n");
212                 ddekit_simple_free(cache);
213                 return 0;
214         }
215
216         cache->name = name;
217         cache->size = size;
218         cache->ctor = ctor;
219
220         ddekit_lock_init_unlocked(&cache->cache_lock);
221
222         return cache;
223 }