简体   繁体   English

嵌套rcu_read_locks

[英]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.

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