Skip to the content.

Memory Pool

使用 mempool 的目的: The purpose of mempools is to help out in situations where a memory allocation must succeed, but sleeping is not an option. To that end, mempools pre-allocate a pool of memory and reserve it until it is needed. [^16] [^16]: kernel doc : Driver porting: low-level memory allocation

#0  r1bio_pool_alloc (gfp_flags=600064, data=0xffff888103acffd0) at drivers/md/raid1.c:131
#1  0xffffffff8133c353 in mempool_alloc (pool=pool@entry=0xffff888130eb10a0, gfp_mask=601088, gfp_mask@entry=3072) at mm/mempool.c:398
#2  0xffffffff81e27e52 in alloc_r1bio (bio=0xffff88810c470100, mddev=0xffff888107ca2000) at drivers/md/raid1.c:1209

如果一个正在 alloc ,但是正在调用 mempool_exit

在 mempool_init_node 预先分配内存

通过 mempool_t::lock 来实现互斥

基本的使用接口

[ ] 如何理解这里的注释

 */
void mempool_free(void *element, mempool_t *pool)
{
	unsigned long flags;

	if (unlikely(element == NULL))
		return;

	/*
	 * Paired with the wmb in mempool_alloc().  The preceding read is
	 * for @element and the following @pool->curr_nr.  This ensures
	 * that the visible value of @pool->curr_nr is from after the
	 * allocation of @element.  This is necessary for fringe cases
	 * where @element was passed to this task without going through
	 * barriers.
	 *
	 * For example, assume @p is %NULL at the beginning and one task
	 * performs "p = mempool_alloc(...);" while another task is doing
	 * "while (!p) cpu_relax(); mempool_free(p, ...);".  This function
	 * may end up using curr_nr value which is from before allocation
	 * of @p without the following rmb.
	 */
	smp_rmb();

	/*
	 * For correctness, we need a test which is guaranteed to trigger
	 * if curr_nr + #allocated == min_nr.  Testing curr_nr < min_nr
	 * without locking achieves that and refilling as soon as possible
	 * is desirable.
	 *
	 * Because curr_nr visible here is always a value after the
	 * allocation of @element, any task which decremented curr_nr below
	 * min_nr is guaranteed to see curr_nr < min_nr unless curr_nr gets
	 * incremented to min_nr afterwards.  If curr_nr gets incremented
	 * to min_nr after the allocation of @element, the elements
	 * allocated after that are subject to the same guarantee.
	 *
	 * Waiters happen iff curr_nr is 0 and the above guarantee also
	 * ensures that there will be frees which return elements to the
	 * pool waking up the waiters.
	 */
	if (unlikely(READ_ONCE(pool->curr_nr) < pool->min_nr)) {
		spin_lock_irqsave(&pool->lock, flags);
		if (likely(pool->curr_nr < pool->min_nr)) {
			add_element(pool, element);
			spin_unlock_irqrestore(&pool->lock, flags);
			wake_up(&pool->wait);
			return;
		}
		spin_unlock_irqrestore(&pool->lock, flags);
	}
	pool->free(element, pool->pool_data);
}

一个 mempool 的 element 是不可以 free 到另一个 mempool 中的

mempool 中支持持有存储指针,alloc 出来的元素大小是 mempool_s::alloc 决定的是靠当时

例如,一个存放 r1bio 的 mempool 的长度不是固定的

static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
{
	struct pool_info *pi = data;
	int size = offsetof(struct r1bio, bios[pi->raid_disks]);

	/* allocate a r1bio with room for raid_disks entries in the bios array */
	return kzalloc(size, gfp_flags);
}

所以是不能瞎鸡儿放置的。

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。