X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=mm%2Fmempool.c;h=1a3bc3d4d5543d5192848bedda8162933f07ada0;hb=fcdcddbcbbd39a3363bd48414bfe44553b6d698a;hp=7bf064e6a345e898a5eafc616cd691b50fbedcec;hpb=f183323d3822dee4d7b3147a59b6e8987fe201e0;p=safe%2Fjmp%2Flinux-2.6 diff --git a/mm/mempool.c b/mm/mempool.c index 7bf064e..1a3bc3d 100644 --- 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 - * 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 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, @@ -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; - pool = kmalloc_node(sizeof(*pool), GFP_KERNEL, node_id); + pool = kmalloc_node(sizeof(*pool), GFP_KERNEL | __GFP_ZERO, node_id); if (!pool) return NULL; - memset(pool, 0, sizeof(*pool)); 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) { - 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); @@ -195,7 +194,7 @@ EXPORT_SYMBOL(mempool_destroy); * 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.) @@ -238,8 +237,13 @@ repeat_alloc: 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; @@ -258,6 +262,9 @@ void mempool_free(void *element, mempool_t *pool) { unsigned long flags; + if (unlikely(element == NULL)) + return; + 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 - * specfied by pool_data + * specified by 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); -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);