- 论坛徽章:
- 0
|
回复 #1 fishswimming 的帖子
对curr_nr的写操作是在spin_lock_irqsave/spin_unlock_irqrestore中进行的,但是对curr_nr的读操作就是在普通内核进程上下文的情况下进行,因此在读curr_nr的时候调用smp_mb保证能够看到最近的更新。
从代码的角度看,
mempool_alloc 函数片段:
element = pool->alloc(gfp_temp, pool->pool_data);
if (likely(element != NULL))
return element;
spin_lock_irqsave(&pool->lock, flags);
if (likely(pool->curr_nr)) {
----- 不为空,则remove,并返回
element = remove_element(pool);
spin_unlock_irqrestore(&pool->lock, flags);
return element;
}
spin_unlock_irqrestore(&pool->lock, flags);
省略一下。。。
init_wait(&wait);
prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
smp_mb();
if (!pool->curr_nr) {
------ 一般情况下为0,但是如果恰好其他处理器进程释放了pool资源呢? 如此就不需要wait,而直接可以goto repeat_alloc
/*
* 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; |
|