我想知道nf_conntrack_find_get()
真的能在Linux内核中通过RCU保护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();
我认为,如果要保护节点(h),必须使用call_rcu()
而不是在destroy_conntrack()
中直接释放。
答案 0 :(得分:0)
我的问题是,然后可以将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。 该内存位置可以随时自由重用。
因此,节点始终具有相同的偏移量。我们甚至可以将其释放。
当然,必须保护一些限制。(内存屏障,原子操作,使用引用计数,检查重用节点...)
您在链接下方阅读的更多详细信息和限制