LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Is it safe to invoke rcu_dereference() outside RCU critical sections in the kernel? (https://www.linuxquestions.org/questions/linux-kernel-70/is-it-safe-to-invoke-rcu_dereference-outside-rcu-critical-sections-in-the-kernel-4175732665/)

pappasbrent 01-11-2024 11:13 AM

Is it safe to invoke rcu_dereference() outside RCU critical sections in the kernel?
 
Hi all,

I have been reading the Linux kernel's RCU API documentation, and the docs seem to indicate that it is incorrect to call rcu_dereference() outside of an RCU read-side critical section (i.e., a section of code that begins with a call to rcu_read_lock() and ends with a call to rcu_read_unlock()).
However, I found several instances in the Linux kernel where this macro is invoked outside of a critical section.
Here is an example taken from line 5004 of net/mac80211/tx.c:

Code:

resp = rcu_dereference(link->u.ap.probe_resp);
Since this call to rcu_dereference() is outside a critical section, is it therefore erroneous?
Or am I misunderstanding how the RCU API works?

pappasbrent 01-12-2024 12:43 PM

So I took a deeper look at the invocation I linked to in my previous post in this thread, and I made an interesting discovery.
The invocation of rcu_dereference() on line 5004 of net/mac80211/tx.c is inside the definition of the function ieee80211_set_beacon_cntdwn().
This function is only invoked inside RCU read-side critical sections, so I suppose that transitively that means that all calls to rcu_dereference() inside its definition are called within critical sections as well.
This is fine, but leads me to another question: Should the definition of ieee80211_set_beacon_cntdwn() be annotated with one of the RCU annotation macros (e.g., __rcu, __user, or __kernel; defined on line 28 of include/linux/compiler_types.h) to signify that it is only to be called within RCU critical sections (I'm assuming the __rcu annotation)?

pappasbrent 01-12-2024 01:14 PM

Ok, I think I figured it out!
The __rcu macro I mentioned in my last post expands to the noderef and address_space() macro annotations, which according to this page, should only be used to data structures.
Therefore my previous idea to use this macro to annotate the definition of the function ieee80211_set_beacon_cntdwn() was wrong.
Instead, I think ieee80211_set_beacon_cntdwn() should be annotated with the __must_hold() macro, which according to the sparse documentation should be passed the name of the struct that the function is expected to have a lock on when it is called.
The call to rcu_dereference() in the body of ieee80211_set_beacon_cntdwn() is passed the struct named "link", like so:

Code:

rcu_dereference(link->u.ap.probe_resp)
So I think the annotation should ultimately be:

Code:

__must_hold(link)
Can anyone with more kernel development experience confirm if my reasoning is correct here?


All times are GMT -5. The time now is 04:38 PM.