Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932264AbbLNLJy (ORCPT ); Mon, 14 Dec 2015 06:09:54 -0500 Received: from mga09.intel.com ([134.134.136.24]:28584 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932121AbbLNLJx convert rfc822-to-8bit (ORCPT ); Mon, 14 Dec 2015 06:09:53 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,426,1444719600"; d="scan'208";a="873151410" From: "Wang, Zhi A" To: "linux-kernel@vger.kernel.org" , "linux-mm@kvack.org" , "akpm@linux-foundation.org" , Ingo Molnar Subject: [PATCH] mm: mempool: Factor out mempool_refill() Thread-Topic: [PATCH] mm: mempool: Factor out mempool_refill() Thread-Index: AQHRNVj+JGCwEtY9LE6p5gMA8BqGrp7KVEQg Date: Mon, 14 Dec 2015 11:09:43 +0000 Message-ID: References: <1449978390-10931-1-git-send-email-zhi.a.wang@intel.com> In-Reply-To: <1449978390-10931-1-git-send-email-zhi.a.wang@intel.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4069 Lines: 121 This patch factors out mempool_refill() from mempool_resize(). It's reasonable that the mempool user wants to refill the pool immdiately when it has chance e.g. inside a sleepible context, so that next time in the IRQ context the pool would have much more available elements to allocate. After the refactor, mempool_refill() can also executes with mempool_resize() /mempool_alloc/mempool_free() or another mempool_refill(). Signed-off-by: Zhi Wang --- include/linux/mempool.h | 1 + mm/mempool.c | 61 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/include/linux/mempool.h b/include/linux/mempool.h index 69b6951..71f7460 100644 --- a/include/linux/mempool.h +++ b/include/linux/mempool.h @@ -30,6 +30,7 @@ extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn, gfp_t gfp_mask, int nid); extern int mempool_resize(mempool_t *pool, int new_min_nr); +extern void mempool_refill(mempool_t *pool); extern void mempool_destroy(mempool_t *pool); extern void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask); extern void mempool_free(void *element, mempool_t *pool); diff --git a/mm/mempool.c b/mm/mempool.c index 004d42b..139c477 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -223,6 +223,47 @@ mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn, EXPORT_SYMBOL(mempool_create_node); /** + * mempool_refill - refill an existing memory pool immediately + * @pool: pointer to the memory pool which was allocated via + * mempool_create(). + * + * This function tries to refill the pool with new elements + * immediately. Similar with mempool_resize(), it cannot be + * guaranteed that the pool will be fully filled immediately. + * + * Note, the caller must guarantee that no mempool_destroy is called + * while this function is running. mempool_alloc() & mempool_free() + * might be called (eg. from IRQ contexts) while this function executes. + */ +void mempool_refill(mempool_t *pool) +{ + void *element; + unsigned long flags; + + spin_lock_irqsave(&pool->lock, flags); + if (pool->curr_nr >= pool->min_nr) { + spin_unlock_irqrestore(&pool->lock, flags); + return; + } + + while (pool->curr_nr < pool->min_nr) { + spin_unlock_irqrestore(&pool->lock, flags); + element = pool->alloc(GFP_KERNEL, pool->pool_data); + if (!element) + return; + spin_lock_irqsave(&pool->lock, flags); + if (pool->curr_nr < pool->min_nr) { + add_element(pool, element); + } else { + spin_unlock_irqrestore(&pool->lock, flags); + pool->free(element, pool->pool_data); /* Raced */ + return; + } + } +} +EXPORT_SYMBOL(mempool_refill); + +/** * mempool_resize - resize an existing memory pool * @pool: pointer to the memory pool which was allocated via * mempool_create(). @@ -256,7 +297,8 @@ int mempool_resize(mempool_t *pool, int new_min_nr) spin_lock_irqsave(&pool->lock, flags); } pool->min_nr = new_min_nr; - goto out_unlock; + spin_unlock_irqrestore(&pool->lock, flags); + goto out; } spin_unlock_irqrestore(&pool->lock, flags); @@ -279,22 +321,9 @@ int mempool_resize(mempool_t *pool, int new_min_nr) pool->elements = new_elements; pool->min_nr = new_min_nr; - while (pool->curr_nr < pool->min_nr) { - spin_unlock_irqrestore(&pool->lock, flags); - element = pool->alloc(GFP_KERNEL, pool->pool_data); - if (!element) - goto out; - spin_lock_irqsave(&pool->lock, flags); - if (pool->curr_nr < pool->min_nr) { - add_element(pool, element); - } else { - spin_unlock_irqrestore(&pool->lock, flags); - pool->free(element, pool->pool_data); /* Raced */ - goto out; - } - } -out_unlock: spin_unlock_irqrestore(&pool->lock, flags); + + mempool_refill(pool); out: return 0; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/