繁体   English   中英

嵌套rcu_read_locks

[英]Nesting of rcu_read_locks

我将RCU保护的指针MyStruct *存储在RCU保护的哈希表MyHash 通过哈希表读取/更新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'*/

请注意, MyStruct本身是另一个RCU保护列表的一部分(即它是另一个列表的RCU保护节点),该列表存储在MyHash以加快查找速度。

据我了解,需要rcu_read_lock来确保在所有读取端关键部分都完成之前,任何编写器更新都不会释放内存。 那么,是否真的有必要嵌套rcu_read_lock或仅具有外部rcu_read_lock / rcu_read_unlock就足够了?

IOW,由于RCU锁没有绑定到任何单个对象,当一起访问多个受RCU保护的对象时,我们真的需要嵌套的rcu锁吗?

不,嵌套rcu_read_lock() 不是必需的

与其他“嵌套”关键部分类似,嵌套的rcu_read_lock的唯一作用是增加锁定级别。 也就是说,进一步的rcu_read_unlock不会立即结束关键部分,而只是将锁定级别恢复到原来的水平。

但是,支持嵌套锁定被视为RCU锁定机制的优点 支持嵌套操作后,您可以彼此独立地开发组件。

例如,您可能具有object_increment函数,可以在没有RCU锁定的情况下安全地调用该函数:

void object_increment(Object obj)
{
    rcu_read_lock();
    Mystruct* s = obj->s;
    if(s) 
    {
        s->read++;
    }
    rcu_read_unlock();
}

然后在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'*/

简单设计几乎总是胜过嵌套调用rcu_read_lock性能rcu_read_lock


如果没有嵌套调用,则需要使用RCU锁来实现另一组件的功能以进行访问:

void object_increment_locked(Object obj)
{
    Mystruct* s = obj->s;
    if(s) 
    {
        s->read++;
    }
}

并仔细选择在具体情况下要使用的功能-锁定或非锁定:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM