D.4.2.4.2 rcu_read_unlock()

Figure: __rcu_read_unlock() Implementation
\begin{figure}{ \scriptsize
\begin{verbatim}1 void __rcu_read_unlock(void)
2...
...idx])--;
17 local_irq_restore(flags);
18 }
19 }\end{verbatim}
}\end{figure}

The implementation of rcu_read_unlock() is shown in Figure [*]. Line 7 fetches the rcu_read_lock_nesting counter, which line 8 checks to see if we are under the protection of an enclosing rcu_read_lock() primitive. If so, line 9 simply decrements the counter.

However, as with rcu_read_lock(), we otherwise must do more work. Lines 13 and 17 disable and restore irqs in order to prevent the scheduling-clock interrupt from invoking the grace-period state machine while in the midst of rcu_read_unlock() processing. Line 14 picks up the rcu_flipctr_idx that was saved by the matching rcu_read_lock(), line 15 decrements rcu_read_lock_nesting so that irq and NMI/SMI handlers will henceforth update rcu_flipctr, line 16 decrements the counter (with the same index as, but possibly on a different CPU than, that incremented by the matching rcu_read_lock().

The ACCESS_ONCE() macros and irq disabling are required for similar reasons that they are in rcu_read_lock().

Quick Quiz D.59: What problems could arise if the lines containing ACCESS_ONCE() in rcu_read_unlock() were reordered by the compiler? End Quick Quiz

Quick Quiz D.60: What problems could arise if the lines containing ACCESS_ONCE() in rcu_read_unlock() were reordered by the CPU? End Quick Quiz

Quick Quiz D.61: What problems could arise in rcu_read_unlock() if irqs were not disabled? End Quick Quiz

Paul E. McKenney 2011-12-16