Hi Paul, I was parsing the Data-Structures document and had a question about the following "Important note" text.
Could it be clarified in the below text better why "remaining callbacks are placed back on the RCU_DONE_TAIL segment", is a reason for not depending on ->head for determining if no callbacks are associated with the rcu_segcblist? If callbacks are added back to the DONE_TAIL segment, then I would think rcu_head should be != NULL. Infact the "rsclp->head = *rsclp->tails[RCU_DONE_TAIL];" in rcu_segcblist_extract_done_cbs should set the ->head to NULL if I understand correctly. Important note: It is the ->len field that determines whether or not there are callbacks associated with this rcu_segcblist structure, not the ->head pointer. The reason for this is that all the ready-to-invoke callbacks (that is, those in the RCU_DONE_TAIL segment) are extracted all at once at callback-invocation time. If callback invocation must be postponed, for example, because a high-priority process just woke up on this CPU, then the remaining callbacks are placed back on the RCU_DONE_TAIL segment. Either way, the ->len and ->len_lazy counts are adjusted after the corresponding callbacks have been invoked, and so again it is the ->lencount that accurately reflects whether or not there are callbacks associated with this rcu_segcblist structure. Of course, off-CPU sampling of the ->len count requires the use of appropriate synchronization, for example, memory barriers. This synchronization can be a bit subtle, particularly in the case of rcu_barrier(). Thanks! - Joel