1

我想知道nf_conntrack_find_get()RCU 在 linux 内核中真正保护 ct 指针。

Read-Copy-Update(RCU) 可以在节点更新时保护访问(读取)节点 rcu_read_side 临界区。但是,这并不意味着保护节点。

nf_conntrack_find_get()打电话___nf_conntrack_find__nf_conntrack_find返回h(rcu 药水)。

但是另一个进程可以访问相同的 h 和free(h).

在这个时候,最终我认为 ct 不受保护。

h用于计算偏移并获取 ct 指针。

我们可以思考h还是ct安全?

下面是代码..

/net/netfilter/nf_conntrack_core.c

__nf_conntrack_find_get() {

    rcu_read_lock();

    h = ____nf_conntrack_find(net, zone, tuple, hash);
    if (h) {
        // RCU can't protect free h. only ensures to read old copy.
        // If another processor free same h, h is freed.
        // is really h available next line?

        ct = nf_ct_tuplehash_to_ctrack(h);

        ....
    } 
}
rcu_read_unlock();

我认为如果要保护 node(h),必须使用call_rcu()而不是直接 free in destroy_conntrack()

4

1 回答 1

1

我的问题是 h 可以被释放另一个进程然后“h 安全吗?”,“如果 h 是安全的,它是如何工作的?”

这是答案。

请注意,在所有上下文中,h 的含义相同(ct 仅由 h 计算)。

问:h 安全吗?

首先,必须定义什么是“安全吗?”

通常,“指针是安全的”是指指针引用的地址是可访问的而不是被释放的。因此,如果使用指针或指针成员,则可以访问它们而不会违反。

在此上下文代码中观看,

答案是“h 可以被释放但没有发生违规!” (哇:O)。

如果在 destroy_conntrack() 中使用 call_rcu(),h 不能释放 util 宽限期。但是 ct 直接在 destroy_conntrack() 中释放。

如何在没有 call_rcu() 的情况下保护 ct。(甚至没有发生违规)。

诀窍是使用 hlist_nulls(SLAB_TYPESAFE_BY_RCU)。

ct 节点位于 SLAB_TYPESAFE_BY_RCU。该内存位置可以随时免费重用。

因此,节点始终具有相同的偏移量。我们可以访问它们甚至被释放。

当然,必须保护一些限制。(内存屏障,原子操作,使用引用计数,检查重用节点......)

您在以下链接中阅读的更多详细信息和限制

https://github.com/westerndigitalcorporation/RISC-V-Linux/blob/master/linux/Documentation/RCU/rculist_nulls.txt

于 2019-07-12T06:26:59.647 回答