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); Or am I misunderstanding how the RCU API works? |
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)? |
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) Code:
__must_hold(link) |
All times are GMT -5. The time now is 04:38 PM. |