v2.5.0.10 -> v2.5.0.11
[linux-flexiantxendom0-3.2.10.git] / mm / mempool.c
1 /*
2  *  linux/mm/mempool.c
3  *
4  *  memory buffer pool support. Such pools are mostly used
5  *  for guaranteed, deadlock-free memory allocations during
6  *  extreme VM load.
7  *
8  *  started by Ingo Molnar, Copyright (C) 2001
9  */
10
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <linux/mempool.h>
14
15 /**
16  * mempool_create - create a memory pool
17  * @min_nr:    the minimum number of elements guaranteed to be
18  *             allocated for this pool.
19  * @alloc_fn:  user-defined element-allocation function.
20  * @free_fn:   user-defined element-freeing function.
21  * @pool_data: optional private data available to the user-defined functions.
22  *
23  * this function creates and allocates a guaranteed size, preallocated
24  * memory pool. The pool can be used from the mempool_alloc and mempool_free
25  * functions. This function might sleep. Both the alloc_fn() and the free_fn()
26  * functions might sleep - as long as the mempool_alloc function is not called
27  * from IRQ contexts. The element allocated by alloc_fn() must be able to
28  * hold a struct list_head. (8 bytes on x86.)
29  */
30 mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
31                                 mempool_free_t *free_fn, void *pool_data)
32 {
33         mempool_t *pool;
34         int i;
35
36         pool = kmalloc(sizeof(*pool), GFP_KERNEL);
37         if (!pool)
38                 return NULL;
39         memset(pool, 0, sizeof(*pool));
40
41         spin_lock_init(&pool->lock);
42         pool->min_nr = min_nr;
43         pool->pool_data = pool_data;
44         INIT_LIST_HEAD(&pool->elements);
45         init_waitqueue_head(&pool->wait);
46         pool->alloc = alloc_fn;
47         pool->free = free_fn;
48
49         /*
50          * First pre-allocate the guaranteed number of buffers.
51          */
52         for (i = 0; i < min_nr; i++) {
53                 void *element;
54                 struct list_head *tmp;
55                 element = pool->alloc(GFP_KERNEL, pool->pool_data);
56
57                 if (unlikely(!element)) {
58                         /*
59                          * Not enough memory - free the allocated ones
60                          * and return:
61                          */
62                         list_for_each(tmp, &pool->elements) {
63                                 element = tmp;
64                                 pool->free(element, pool->pool_data);
65                         }
66                         kfree(pool);
67
68                         return NULL;
69                 }
70                 tmp = element;
71                 list_add(tmp, &pool->elements);
72                 pool->curr_nr++;
73         }
74         return pool;
75 }
76
77 /**
78  * mempool_resize - resize an existing memory pool
79  * @pool:       pointer to the memory pool which was allocated via
80  *              mempool_create().
81  * @new_min_nr: the new minimum number of elements guaranteed to be
82  *              allocated for this pool.
83  * @gfp_mask:   the usual allocation bitmask.
84  *
85  * This function shrinks/grows the pool. In the case of growing,
86  * it cannot be guaranteed that the pool will be grown to the new
87  * size immediately, but new mempool_free() calls will refill it.
88  *
89  * Note, the caller must guarantee that no mempool_destroy is called
90  * while this function is running. mempool_alloc() & mempool_free()
91  * might be called (eg. from IRQ contexts) while this function executes.
92  */
93 void mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask)
94 {
95         int delta;
96         void *element;
97         unsigned long flags;
98         struct list_head *tmp;
99
100         if (new_min_nr <= 0)
101                 BUG();
102
103         spin_lock_irqsave(&pool->lock, flags);
104         if (new_min_nr < pool->min_nr) {
105                 pool->min_nr = new_min_nr;
106                 /*
107                  * Free possible excess elements.
108                  */
109                 while (pool->curr_nr > pool->min_nr) {
110                         tmp = pool->elements.next;
111                         if (tmp == &pool->elements)
112                                 BUG();
113                         list_del(tmp);
114                         element = tmp;
115                         pool->curr_nr--;
116                         spin_unlock_irqrestore(&pool->lock, flags);
117
118                         pool->free(element, pool->pool_data);
119
120                         spin_lock_irqsave(&pool->lock, flags);
121                 }
122                 spin_unlock_irqrestore(&pool->lock, flags);
123                 return;
124         }
125         delta = new_min_nr - pool->min_nr;
126         pool->min_nr = new_min_nr;
127         spin_unlock_irqrestore(&pool->lock, flags);
128
129         /*
130          * We refill the pool up to the new treshold - but we dont
131          * (cannot) guarantee that the refill succeeds.
132          */
133         while (delta) {
134                 element = pool->alloc(gfp_mask, pool->pool_data);
135                 if (!element)
136                         break;
137                 mempool_free(element, pool);
138                 delta--;
139         }
140 }
141
142 /**
143  * mempool_destroy - deallocate a memory pool
144  * @pool:      pointer to the memory pool which was allocated via
145  *             mempool_create().
146  *
147  * this function only sleeps if the free_fn() function sleeps. The caller
148  * has to guarantee that no mempool_alloc() nor mempool_free() happens in
149  * this pool when calling this function.
150  */
151 void mempool_destroy(mempool_t *pool)
152 {
153         void *element;
154         struct list_head *head, *tmp;
155
156         if (!pool)
157                 return;
158
159         head = &pool->elements;
160         for (tmp = head->next; tmp != head; ) {
161                 element = tmp;
162                 tmp = tmp->next;
163                 pool->free(element, pool->pool_data);
164                 pool->curr_nr--;
165         }
166         if (pool->curr_nr)
167                 BUG();
168         kfree(pool);
169 }
170
171 /**
172  * mempool_alloc - allocate an element from a specific memory pool
173  * @pool:      pointer to the memory pool which was allocated via
174  *             mempool_create().
175  * @gfp_mask:  the usual allocation bitmask.
176  *
177  * this function only sleeps if the alloc_fn function sleeps or
178  * returns NULL. Note that due to preallocation, this function
179  * *never* fails.
180  */
181 void * mempool_alloc(mempool_t *pool, int gfp_mask)
182 {
183         void *element;
184         unsigned long flags;
185         struct list_head *tmp;
186         int curr_nr;
187         DECLARE_WAITQUEUE(wait, current);
188         int gfp_nowait = gfp_mask & ~__GFP_WAIT;
189
190 repeat_alloc:
191         element = pool->alloc(gfp_nowait, pool->pool_data);
192         if (likely(element != NULL))
193                 return element;
194
195         /*
196          * If the pool is less than 50% full then try harder
197          * to allocate an element:
198          */
199         if (gfp_mask != gfp_nowait) {
200                 if (pool->curr_nr <= pool->min_nr/2) {
201                         element = pool->alloc(gfp_mask, pool->pool_data);
202                         if (likely(element != NULL))
203                                 return element;
204                 }
205         } else
206                 /* we must not sleep */
207                 return NULL;
208
209         /*
210          * Kick the VM at this point.
211          */
212         wakeup_bdflush();
213
214         spin_lock_irqsave(&pool->lock, flags);
215         if (likely(pool->curr_nr)) {
216                 tmp = pool->elements.next;
217                 list_del(tmp);
218                 element = tmp;
219                 pool->curr_nr--;
220                 spin_unlock_irqrestore(&pool->lock, flags);
221
222                 return element;
223         }
224         add_wait_queue_exclusive(&pool->wait, &wait);
225         set_task_state(current, TASK_UNINTERRUPTIBLE);
226
227         curr_nr = pool->curr_nr;
228         spin_unlock_irqrestore(&pool->lock, flags);
229
230         if (!curr_nr) {
231                 run_task_queue(&tq_disk);
232                 schedule();
233         }
234
235         current->state = TASK_RUNNING;
236         remove_wait_queue(&pool->wait, &wait);
237
238         goto repeat_alloc;
239 }
240
241 /**
242  * mempool_free - return an element to the pool.
243  * @element:   pool element pointer.
244  * @pool:      pointer to the memory pool which was allocated via
245  *             mempool_create().
246  *
247  * this function only sleeps if the free_fn() function sleeps.
248  */
249 void mempool_free(void *element, mempool_t *pool)
250 {
251         unsigned long flags;
252
253         if (pool->curr_nr < pool->min_nr) {
254                 spin_lock_irqsave(&pool->lock, flags);
255                 if (pool->curr_nr < pool->min_nr) {
256                         list_add(element, &pool->elements);
257                         pool->curr_nr++;
258                         spin_unlock_irqrestore(&pool->lock, flags);
259                         wake_up(&pool->wait);
260                         return;
261                 }
262                 spin_unlock_irqrestore(&pool->lock, flags);
263         }
264         pool->free(element, pool->pool_data);
265 }
266
267 EXPORT_SYMBOL(mempool_create);
268 EXPORT_SYMBOL(mempool_resize);
269 EXPORT_SYMBOL(mempool_destroy);
270 EXPORT_SYMBOL(mempool_alloc);
271 EXPORT_SYMBOL(mempool_free);
272