git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
mm: compaction: direct compact when a high-order allocation fails
[safe/jmp/linux-2.6]
/
mm
/
mempool.c
diff --git
a/mm/mempool.c
b/mm/mempool.c
index
7bf064e
..
1a3bc3d
100644
(file)
--- a/
mm/mempool.c
+++ b/
mm/mempool.c
@@
-46,9
+46,9
@@
static void free_pool(mempool_t *pool)
* @pool_data: optional private data available to the user-defined functions.
*
* this function creates and allocates a guaranteed size, preallocated
* @pool_data: optional private data available to the user-defined functions.
*
* this function creates and allocates a guaranteed size, preallocated
- * memory pool. The pool can be used from the mempool_alloc
and mempool_free
+ * memory pool. The pool can be used from the mempool_alloc
() and mempool_free()
* functions. This function might sleep. Both the alloc_fn() and the free_fn()
* functions. This function might sleep. Both the alloc_fn() and the free_fn()
- * functions might sleep - as long as the mempool_alloc function is not called
+ * functions might sleep - as long as the mempool_alloc
()
function is not called
* from IRQ contexts.
*/
mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
* from IRQ contexts.
*/
mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
@@
-62,10
+62,9
@@
mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
mempool_free_t *free_fn, void *pool_data, int node_id)
{
mempool_t *pool;
mempool_free_t *free_fn, void *pool_data, int node_id)
{
mempool_t *pool;
- pool = kmalloc_node(sizeof(*pool), GFP_KERNEL, node_id);
+ pool = kmalloc_node(sizeof(*pool), GFP_KERNEL
| __GFP_ZERO
, node_id);
if (!pool)
return NULL;
if (!pool)
return NULL;
- memset(pool, 0, sizeof(*pool));
pool->elements = kmalloc_node(min_nr * sizeof(void *),
GFP_KERNEL, node_id);
if (!pool->elements) {
pool->elements = kmalloc_node(min_nr * sizeof(void *),
GFP_KERNEL, node_id);
if (!pool->elements) {
@@
-183,8
+182,8
@@
EXPORT_SYMBOL(mempool_resize);
*/
void mempool_destroy(mempool_t *pool)
{
*/
void mempool_destroy(mempool_t *pool)
{
- if (pool->curr_nr != pool->min_nr)
- BUG(); /* There were outstanding elements */
+ /* Check for outstanding elements */
+ BUG_ON(pool->curr_nr != pool->min_nr);
free_pool(pool);
}
EXPORT_SYMBOL(mempool_destroy);
free_pool(pool);
}
EXPORT_SYMBOL(mempool_destroy);
@@
-195,7
+194,7
@@
EXPORT_SYMBOL(mempool_destroy);
* mempool_create().
* @gfp_mask: the usual allocation bitmask.
*
* mempool_create().
* @gfp_mask: the usual allocation bitmask.
*
- * this function only sleeps if the alloc_fn function sleeps or
+ * this function only sleeps if the alloc_fn
()
function sleeps or
* returns NULL. Note that due to preallocation, this function
* *never* fails when called from process contexts. (it might
* fail if called from an IRQ context.)
* returns NULL. Note that due to preallocation, this function
* *never* fails when called from process contexts. (it might
* fail if called from an IRQ context.)
@@
-238,8
+237,13
@@
repeat_alloc:
init_wait(&wait);
prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
smp_mb();
init_wait(&wait);
prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
smp_mb();
- if (!pool->curr_nr)
- io_schedule();
+ if (!pool->curr_nr) {
+ /*
+ * FIXME: this should be io_schedule(). The timeout is there
+ * as a workaround for some DM problems in 2.6.18.
+ */
+ io_schedule_timeout(5*HZ);
+ }
finish_wait(&pool->wait, &wait);
goto repeat_alloc;
finish_wait(&pool->wait, &wait);
goto repeat_alloc;
@@
-258,6
+262,9
@@
void mempool_free(void *element, mempool_t *pool)
{
unsigned long flags;
{
unsigned long flags;
+ if (unlikely(element == NULL))
+ return;
+
smp_mb();
if (pool->curr_nr < pool->min_nr) {
spin_lock_irqsave(&pool->lock, flags);
smp_mb();
if (pool->curr_nr < pool->min_nr) {
spin_lock_irqsave(&pool->lock, flags);
@@
-292,22
+299,15
@@
EXPORT_SYMBOL(mempool_free_slab);
/*
* A commonly used alloc and free fn that kmalloc/kfrees the amount of memory
/*
* A commonly used alloc and free fn that kmalloc/kfrees the amount of memory
- * specfied by pool_data
+ * spec
i
fied by pool_data
*/
void *mempool_kmalloc(gfp_t gfp_mask, void *pool_data)
{
*/
void *mempool_kmalloc(gfp_t gfp_mask, void *pool_data)
{
- size_t size = (size_t)
(long)
pool_data;
+ size_t size = (size_t)pool_data;
return kmalloc(size, gfp_mask);
}
EXPORT_SYMBOL(mempool_kmalloc);
return kmalloc(size, gfp_mask);
}
EXPORT_SYMBOL(mempool_kmalloc);
-void *mempool_kzalloc(gfp_t gfp_mask, void *pool_data)
-{
- size_t size = (size_t) pool_data;
- return kzalloc(size, gfp_mask);
-}
-EXPORT_SYMBOL(mempool_kzalloc);
-
void mempool_kfree(void *element, void *pool_data)
{
kfree(element);
void mempool_kfree(void *element, void *pool_data)
{
kfree(element);