[英]Nesting of rcu_read_locks
I store a RCU protected pointer MyStruct *
, in a RCU protected hashtable MyHash
. 我将RCU保护的指针
MyStruct *
存储在RCU保护的哈希表MyHash
。 When reading/updating MyStruct
via hashtable, I do as shown below. 通过哈希表读取/更新
MyStruct
,如下所示。
rcu_read_lock() /* For hashtable 'MyHash' */
hash_for_each_possible_rcu(MyHash, obj, member, key)
{
rcu_read_lock(); /* For RCU protected data(MyStruct*) stored in hashtable */
Mystruct* s = rcu_dereference_pointer(obj->s);
if(s)
{
s->read++;
}
rcu_read_unlock(); /* For RCU protected data(MyStruct*) stored in hashtable */
}
rcu_read_unlock() /* For hashtable 'MyHash'*/
Note that MyStruct
is itself part of another RCU protected list ( ie it is a RCU protected node of another list), which is stored in MyHash
for faster lookup. 请注意,
MyStruct
本身是另一个RCU保护列表的一部分(即它是另一个列表的RCU保护节点),该列表存储在MyHash
以加快查找速度。
As I understand, rcu_read_lock
's are required to make sure any writer update doesn't free up memory until all read-side critical sections are complete. 据我了解,需要
rcu_read_lock
来确保在所有读取端关键部分都完成之前,任何编写器更新都不会释放内存。 So, is it really necessary to nest rcu_read_lock
's or just having the outer rcu_read_lock
/ rcu_read_unlock
is sufficient? 那么,是否真的有必要嵌套
rcu_read_lock
或仅具有外部rcu_read_lock
/ rcu_read_unlock
就足够了?
IOW, since RCU locks are not tied to any single object, do we really need nested rcu locks when accessing multiple RCU protected objects together? IOW,由于RCU锁没有绑定到任何单个对象,当一起访问多个受RCU保护的对象时,我们真的需要嵌套的rcu锁吗?
No, nested rcu_read_lock()
is not required . 不,嵌套
rcu_read_lock()
不是必需的 。
Similar to other "nested" critical sections, the only effect of nested rcu_read_lock
is increment of the lock level. 与其他“嵌套”关键部分类似,嵌套的
rcu_read_lock
的唯一作用是增加锁定级别。 That is, futher rcu_read_unlock
does not immediately end critical section but just revert lock level back. 也就是说,进一步的
rcu_read_unlock
不会立即结束关键部分,而只是将锁定级别恢复到原来的水平。
However, supporting nested locking is treated as an advantage of RCU locking mechanism. 但是,支持嵌套锁定被视为RCU锁定机制的优点 。 Having supported nested operations one may develop components independently one from others.
支持嵌套操作后,您可以彼此独立地开发组件。
Eg, you may have object_increment
function which can be safely called without RCU lock: 例如,您可能具有
object_increment
函数,可以在没有RCU锁定的情况下安全地调用该函数:
void object_increment(Object obj)
{
rcu_read_lock();
Mystruct* s = obj->s;
if(s)
{
s->read++;
}
rcu_read_unlock();
}
Then call this function under RCU lock: 然后在RCU锁定下调用此函数:
rcu_read_lock(); /* For hashtable 'MyHash' */
hash_for_each_possible_rcu(MyHash, obj, member, key)
{
// It is perfectly valid to use the function even with RCU lock already taken
object_increment(obj);
}
rcu_read_unlock(); /* For hashtable 'MyHash'*/
Simple design is almost always outweigh small performance hit from the nested calls to rcu_read_lock
. 简单设计几乎总是胜过嵌套调用
rcu_read_lock
性能rcu_read_lock
。
Without nested calls allowed one would need to implement another component's function for access with RCU lock: 如果没有嵌套调用,则需要使用RCU锁来实现另一组件的功能以进行访问:
void object_increment_locked(Object obj)
{
Mystruct* s = obj->s;
if(s)
{
s->read++;
}
}
and carefully choose which function - locked or non-locked - to use in concrete situations: 并仔细选择在具体情况下要使用的功能-锁定或非锁定:
rcu_read_lock(); /* For hashtable 'MyHash' */
hash_for_each_possible_rcu(MyHash, obj, member, key)
{
// Already have a lock taken, so use _locked version of the function.
object_increment_locked(obj);
}
rcu_read_unlock(); /* For hashtable 'MyHash'*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.