我有一个样板函数,可以在树状数据库中找到一个结构:
struct foo {
struct foo *child1; /* RCU-protected. */
struct foo *child2; /* RCU-protected. */
... /* Other stuff */
}
static struct foo *find_foo(int arg)
{
struct foo *parent;
... /* Do something to find parent. */
return rcu_dereference(parent->child1); /* or child2. Whatever. */
}
然后我有几个函数可以解决这个问题:
void a(int arg)
{
struct foo *bar;
rcu_read_lock();
bar = find_foo(arg);
... /* Read something from bar and do something with it. */
rcu_read_unlock();
}
然后我有一个更新器/取料器。它需要像“a”函数一样找到对象(假设它已经从外部进行了互斥):
void c(int arg)
{
struct foo *bar;
bar = find_foo(arg);
... /* make a backup pointer of bar->child1. */
rcu_assign_pointer(bar->child1, ...);
... /* free the old child or whatever. */
}
我的问题是,rcu_dereference()
的文档说它必须在读取方的关键部分(即rcu_read_lock()
和rcu_read_unlock()
之间)进行调用。 c()
通过调用find_foo()
违反此规则。
我犹豫是否制作了使用rcu_dereference_protected()
代替find_foo()
的{{1}}的全新版本,因为它的代码太重了,所以我想知道这个实现是否rcu_dereference()
是合法的:
c()
如果这不合法,我应该如何混合使用读者和更新程序代码?
答案 0 :(得分:1)
实际上, if *something involving sys.argv[1]*:
print line
的第一个变体是正确的(在更新程序方面不需要特定的解引用),但它会使rcu检查器混淆(检查器期望在{{1}下发生c()
})。
即使从rcu检查器的角度来看,rcu_dereference
的第二个变体也是正确的,但不需要rcu_read
:c()
已经是rcu_dereference_protected
的结果。
让rcu checker高兴的另一种方法是使用
bar
而不是
rcu_dereference
在rcu_dereference_check(<pointer>, <condition-when-in-updater>)
内实施。所以检查员不会在rcu_dereference(<pointer>)
部分之外的foo()调用上投诉,直到它可以证明在这种情况下条件是foo
。
通过此rcu_read
实施,false
的第一个变体就可以了。