gpt4 book ai didi

linux - 我应该如何混合 RCU 阅读器和更新程序代码?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:50:28 25 4
gpt4 key购买 nike

我有一个样板函数,可以在树状数据库中找到一个结构:

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()而不是 rcu_dereference(),因为它有太多重复代码,所以我想知道 c() 的这种实现是否合法:

void c(int arg)
{
struct foo *bar;

rcu_read_lock();
bar = find_foo(arg);
bar = rcu_dereference_protected(bar, ...); /* THIS. */
rcu_read_unlock();

... /* make a backup pointer of bar->child1. */

rcu_assign_pointer(bar->child1, ...);

... /* free the old child or whatever. */
}

如果这不合法,我应该如何混合读取器和更新器代码?

最佳答案

实际上,c() 的第一个变体是正确的(更新端不需要特定的解引用),但它让 rcu 检查器感到困惑(检查器期望 rcu_dereference 出现在 rcu_read 部分)。

即使从 rcu 检查器的角度来看,c() 的第二个变体也是正确的,但是不需要 rcu_dereference_protected:bar 已经是rcu_dereference 的结果。

另一种让 rcu checker 开心的方法是使用

rcu_dereference_check(<pointer>, <condition-when-in-updater>)

代替

rcu_dereference(<pointer>)

内部 foo 实现。因此检查器不会提示 rcu_read 部分之外的 foo() 调用,直到它可以证明在这种情况下条件为 false

有了这样的 foo() 实现,c() 的第一个变体就可以了。

关于linux - 我应该如何混合 RCU 阅读器和更新程序代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31995257/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com