【发布时间】:2015-08-27 19:46:46
【问题描述】:
LWN 在 RCU 上给出以下示例:
订阅受 RCU 保护的 hlist 也类似于循环 列表:
1 rcu_read_lock(); 2 hlist_for_each_entry_rcu(p, q, head, list) { 3 do_something_with(p->a, p->b, p->c); 4 } 5 rcu_read_unlock();快速测验 3:为什么我们需要将两个指针传递给 hlist_for_each_entry_rcu() 而只需要一个 list_for_each_entry_rcu()?
答案:因为在 hlist 中需要检查 NULL 而不是遇到头部。 (尝试编写一个单指针 hlist_for_each_entry_rcu()。如果你想出一个好的解决方案,它 将是一件非常好的事情!)
我认为它必须引用旧版本的 hlist_for_each_entry_rcu(),因为 rculist.h 标头中的当前版本 (3.13.0) 实际上呈现了 hlist_for_each_entry_rcu 的定义,带有 3 个参数,因此不需要额外的第 4 个指针和似乎并不难发明:
#define hlist_for_each_entry_rcu(pos, head, member) \
for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\
typeof(*(pos)), member); \
pos; \
pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(\
&(pos)->member)), typeof(*(pos)), member))
我是否遗漏了当前 rculist.h 中给出的某些内容或更高版本是这样的非常好的事情?
我们可以看到__rcu_dereference_check 中正在发生一些微妙的事情,其中创建了额外的指针:
#define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/
#define rcu_dereference_check(p, c) \
__rcu_dereference_check((p), rcu_read_lock_held() || (c), __rcu)
#define __rcu_dereference_check(p, c, space) \
({ \
typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
rcu_lockdep_assert(c, "suspicious rcu_dereference_check()" \
" usage"); \
rcu_dereference_sparse(p, space); \
smp_read_barrier_depends(); \
((typeof(*p) __force __kernel *)(_________p1)); \
【问题讨论】:
-
这个问题应该在代码审查或类似的地方讨论吗? codereview.stackexchange.com
-
拜托,在这里给它一个机会
-
更改看起来只是指向指针技巧的指针,用于避免哨兵节点或单链表的特殊情况,但我不确定 RCU 的注意事项。
标签: c algorithm list linux-kernel rcu