内存管理API之mempool_resize

int mempool_resize(mempool_t *pool, int new_min_nr)用于改变已经存在的缓存池能提供最小缓存的大小
其源码分析如下:
int mempool_resize(mempool_t *pool, int new_min_nr)
{
	void *element;
	void **new_elements;
	unsigned long flags;
	#缓存size 小于零,则打印当前的callstack
	BUG_ON(new_min_nr <= 0);
	#这个函数不能sleep
		might_sleep();
	#因此new_min_nr小于已经存在的min_nr的话,则将在min_nr中的多余的memory 释放掉,
	#例如原来能提供64 byte,但是现在形参new_min_nr 等于48,则这里要将16 byte的memory 释放掉。
	spin_lock_irqsave(&pool->lock, flags);
	if (new_min_nr <= pool->min_nr) {
		while (new_min_nr < pool->curr_nr) {
			element = remove_element(pool, GFP_KERNEL);
			spin_unlock_irqrestore(&pool->lock, flags);
			pool->free(element, pool->pool_data);
			spin_lock_irqsave(&pool->lock, flags);
		}
		pool->min_nr = new_min_nr;
		#将多余的缓存释放掉后,这个函数就退出了
		goto out_unlock;
	}
	spin_unlock_irqrestore(&pool->lock, flags);

	/* Grow the pool */
	#这里是第二种情况,就是要扩大缓存池的大小,这里重新通过kmalloc_array 申请一个数组,这里也
	#可以看到缓存池提供的memory都是物理连续的
	new_elements = kmalloc_array(new_min_nr, sizeof(*new_elements),
				     GFP_KERNEL);
	if (!new_elements)
		return -ENOMEM;

	spin_lock_irqsave(&pool->lock, flags);
	#这种case就缓存池缩小的case,前面已经检查分析过了,这里在检查一次
	if (unlikely(new_min_nr <= pool->min_nr)) {
		/* Raced, other resize will do our work */
		spin_unlock_irqrestore(&pool->lock, flags);
		kfree(new_elements);
		goto out;
	}
	#将老的缓存池中的内容cp到新的缓存池中
	memcpy(new_elements, pool->elements,
			pool->curr_nr * sizeof(*new_elements));
	kfree(pool->elements);
	#更新新的缓存池指针和能提供的最小缓存size
	pool->elements = new_elements;
	pool->min_nr = new_min_nr;
	#由于缓存池能提供的最小缓存的size 变大了,因此这里要检查一下当前能提供的缓存释放已经小于最小值了
	while (pool->curr_nr < pool->min_nr) {
		spin_unlock_irqrestore(&pool->lock, flags);
		#能提供的缓存已经小于最小值的话,这里重新申请memory
		element = pool->alloc(GFP_KERNEL, pool->pool_data);
		if (!element)
			goto out;
		spin_lock_irqsave(&pool->lock, flags);
		#将新申请的内存添加到list中,这里不明白为啥还有else的case,这里while循环已经可以保证else的case 不成立,这里又有锁保护。
		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);
out:
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值