| ================================= |
| A Tour Through RCU's Requirements |
| ================================= |
| |
| Copyright IBM Corporation, 2015 |
| |
| Author: Paul E. McKenney |
| |
| The initial version of this document appeared in the |
| `LWN <https://lwn.net/>`_ on those articles: |
| `part 1 <https://lwn.net/Articles/652156/>`_, |
| `part 2 <https://lwn.net/Articles/652677/>`_, and |
| `part 3 <https://lwn.net/Articles/653326/>`_. |
| |
| Introduction |
| ------------ |
| |
| Read-copy update (RCU) is a synchronization mechanism that is often used |
| as a replacement for reader-writer locking. RCU is unusual in that |
| updaters do not block readers, which means that RCU's read-side |
| primitives can be exceedingly fast and scalable. In addition, updaters |
| can make useful forward progress concurrently with readers. However, all |
| this concurrency between RCU readers and updaters does raise the |
| question of exactly what RCU readers are doing, which in turn raises the |
| question of exactly what RCU's requirements are. |
| |
| This document therefore summarizes RCU's requirements, and can be |
| thought of as an informal, high-level specification for RCU. It is |
| important to understand that RCU's specification is primarily empirical |
| in nature; in fact, I learned about many of these requirements the hard |
| way. This situation might cause some consternation, however, not only |
| has this learning process been a lot of fun, but it has also been a |
| great privilege to work with so many people willing to apply |
| technologies in interesting new ways. |
| |
| All that aside, here are the categories of currently known RCU |
| requirements: |
| |
| #. `Fundamental Requirements`_ |
| #. `Fundamental Non-Requirements`_ |
| #. `Parallelism Facts of Life`_ |
| #. `Quality-of-Implementation Requirements`_ |
| #. `Linux Kernel Complications`_ |
| #. `Software-Engineering Requirements`_ |
| #. `Other RCU Flavors`_ |
| #. `Possible Future Changes`_ |
| |
| This is followed by a summary_, however, the answers to |
| each quick quiz immediately follows the quiz. Select the big white space |
| with your mouse to see the answer. |
| |
| Fundamental Requirements |
| ------------------------ |
| |
| RCU's fundamental requirements are the closest thing RCU has to hard |
| mathematical requirements. These are: |
| |
| #. `Grace-Period Guarantee`_ |
| #. `Publish/Subscribe Guarantee`_ |
| #. `Memory-Barrier Guarantees`_ |
| #. `RCU Primitives Guaranteed to Execute Unconditionally`_ |
| #. `Guaranteed Read-to-Write Upgrade`_ |
| |
| Grace-Period Guarantee |
| ~~~~~~~~~~~~~~~~~~~~~~ |
| |
| RCU's grace-period guarantee is unusual in being premeditated: Jack |
| Slingwine and I had this guarantee firmly in mind when we started work |
| on RCU (then called “rclock”) in the early 1990s. That said, the past |
| two decades of experience with RCU have produced a much more detailed |
| understanding of this guarantee. |
| |
| RCU's grace-period guarantee allows updaters to wait for the completion |
| of all pre-existing RCU read-side critical sections. An RCU read-side |
| critical section begins with the marker rcu_read_lock() and ends |
| with the marker rcu_read_unlock(). These markers may be nested, and |
| RCU treats a nested set as one big RCU read-side critical section. |
| Production-quality implementations of rcu_read_lock() and |
| rcu_read_unlock() are extremely lightweight, and in fact have |
| exactly zero overhead in Linux kernels built for production use with |
| ``CONFIG_PREEMPTION=n``. |
| |
| This guarantee allows ordering to be enforced with extremely low |
| overhead to readers, for example: |
| |
| :: |
| |
| 1 int x, y; |
| 2 |
| 3 void thread0(void) |
| 4 { |
| 5 rcu_read_lock(); |
| 6 r1 = READ_ONCE(x); |
| 7 r2 = READ_ONCE(y); |
| 8 rcu_read_unlock(); |
| 9 } |
| 10 |
| 11 void thread1(void) |
| 12 { |
| 13 WRITE_ONCE(x, 1); |
| 14 synchronize_rcu(); |
| 15 WRITE_ONCE(y, 1); |
| 16 } |
| |
| Because the synchronize_rcu() on line 14 waits for all pre-existing |
| readers, any instance of thread0() that loads a value of zero from |
| ``x`` must complete before thread1() stores to ``y``, so that |
| instance must also load a value of zero from ``y``. Similarly, any |
| instance of thread0() that loads a value of one from ``y`` must have |
| started after the synchronize_rcu() started, and must therefore also |
| load a value of one from ``x``. Therefore, the outcome: |
| |
| :: |
| |
| (r1 == 0 && r2 == 1) |
| |
| cannot happen. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Wait a minute! You said that updaters can make useful forward | |
| | progress concurrently with readers, but pre-existing readers will | |
| | block synchronize_rcu()!!! | |
| | Just who are you trying to fool??? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | First, if updaters do not wish to be blocked by readers, they can use | |
| | call_rcu() or kfree_rcu(), which will be discussed later. | |
| | Second, even when using synchronize_rcu(), the other update-side | |
| | code does run concurrently with readers, whether pre-existing or not. | |
| +-----------------------------------------------------------------------+ |
| |
| This scenario resembles one of the first uses of RCU in |
| `DYNIX/ptx <https://en.wikipedia.org/wiki/DYNIX>`__, which managed a |
| distributed lock manager's transition into a state suitable for handling |
| recovery from node failure, more or less as follows: |
| |
| :: |
| |
| 1 #define STATE_NORMAL 0 |
| 2 #define STATE_WANT_RECOVERY 1 |
| 3 #define STATE_RECOVERING 2 |
| 4 #define STATE_WANT_NORMAL 3 |
| 5 |
| 6 int state = STATE_NORMAL; |
| 7 |
| 8 void do_something_dlm(void) |
| 9 { |
| 10 int state_snap; |
| 11 |
| 12 rcu_read_lock(); |
| 13 state_snap = READ_ONCE(state); |
| 14 if (state_snap == STATE_NORMAL) |
| 15 do_something(); |
| 16 else |
| 17 do_something_carefully(); |
| 18 rcu_read_unlock(); |
| 19 } |
| 20 |
| 21 void start_recovery(void) |
| 22 { |
| 23 WRITE_ONCE(state, STATE_WANT_RECOVERY); |
| 24 synchronize_rcu(); |
| 25 WRITE_ONCE(state, STATE_RECOVERING); |
| 26 recovery(); |
| 27 WRITE_ONCE(state, STATE_WANT_NORMAL); |
| 28 synchronize_rcu(); |
| 29 WRITE_ONCE(state, STATE_NORMAL); |
| 30 } |
| |
| The RCU read-side critical section in do_something_dlm() works with |
| the synchronize_rcu() in start_recovery() to guarantee that |
| do_something() never runs concurrently with recovery(), but with |
| little or no synchronization overhead in do_something_dlm(). |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Why is the synchronize_rcu() on line 28 needed? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | Without that extra grace period, memory reordering could result in | |
| | do_something_dlm() executing do_something() concurrently with | |
| | the last bits of recovery(). | |
| +-----------------------------------------------------------------------+ |
| |
| In order to avoid fatal problems such as deadlocks, an RCU read-side |
| critical section must not contain calls to synchronize_rcu(). |
| Similarly, an RCU read-side critical section must not contain anything |
| that waits, directly or indirectly, on completion of an invocation of |
| synchronize_rcu(). |
| |
| Although RCU's grace-period guarantee is useful in and of itself, with |
| `quite a few use cases <https://lwn.net/Articles/573497/>`__, it would |
| be good to be able to use RCU to coordinate read-side access to linked |
| data structures. For this, the grace-period guarantee is not sufficient, |
| as can be seen in function add_gp_buggy() below. We will look at the |
| reader's code later, but in the meantime, just think of the reader as |
| locklessly picking up the ``gp`` pointer, and, if the value loaded is |
| non-\ ``NULL``, locklessly accessing the ``->a`` and ``->b`` fields. |
| |
| :: |
| |
| 1 bool add_gp_buggy(int a, int b) |
| 2 { |
| 3 p = kmalloc(sizeof(*p), GFP_KERNEL); |
| 4 if (!p) |
| 5 return -ENOMEM; |
| 6 spin_lock(&gp_lock); |
| 7 if (rcu_access_pointer(gp)) { |
| 8 spin_unlock(&gp_lock); |
| 9 return false; |
| 10 } |
| 11 p->a = a; |
| 12 p->b = a; |
| 13 gp = p; /* ORDERING BUG */ |
| 14 spin_unlock(&gp_lock); |
| 15 return true; |
| 16 } |
| |
| The problem is that both the compiler and weakly ordered CPUs are within |
| their rights to reorder this code as follows: |
| |
| :: |
| |
| 1 bool add_gp_buggy_optimized(int a, int b) |
| 2 { |
| 3 p = kmalloc(sizeof(*p), GFP_KERNEL); |
| 4 if (!p) |
| 5 return -ENOMEM; |
| 6 spin_lock(&gp_lock); |
| 7 if (rcu_access_pointer(gp)) { |
| 8 spin_unlock(&gp_lock); |
| 9 return false; |
| 10 } |
| 11 gp = p; /* ORDERING BUG */ |
| 12 p->a = a; |
| 13 p->b = a; |
| 14 spin_unlock(&gp_lock); |
| 15 return true; |
| 16 } |
| |
| If an RCU reader fetches ``gp`` just after ``add_gp_buggy_optimized`` |
| executes line 11, it will see garbage in the ``->a`` and ``->b`` fields. |
| And this is but one of many ways in which compiler and hardware |
| optimizations could cause trouble. Therefore, we clearly need some way |
| to prevent the compiler and the CPU from reordering in this manner, |
| which brings us to the publish-subscribe guarantee discussed in the next |
| section. |
| |
| Publish/Subscribe Guarantee |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| RCU's publish-subscribe guarantee allows data to be inserted into a |
| linked data structure without disrupting RCU readers. The updater uses |
| rcu_assign_pointer() to insert the new data, and readers use |
| rcu_dereference() to access data, whether new or old. The following |
| shows an example of insertion: |
| |
| :: |
| |
| 1 bool add_gp(int a, int b) |
| 2 { |
| 3 p = kmalloc(sizeof(*p), GFP_KERNEL); |
| 4 if (!p) |
| 5 return -ENOMEM; |
| 6 spin_lock(&gp_lock); |
| 7 if (rcu_access_pointer(gp)) { |
| 8 spin_unlock(&gp_lock); |
| 9 return false; |
| 10 } |
| 11 p->a = a; |
| 12 p->b = a; |
| 13 rcu_assign_pointer(gp, p); |
| 14 spin_unlock(&gp_lock); |
| 15 return true; |
| 16 } |
| |
| The rcu_assign_pointer() on line 13 is conceptually equivalent to a |
| simple assignment statement, but also guarantees that its assignment |
| will happen after the two assignments in lines 11 and 12, similar to the |
| C11 ``memory_order_release`` store operation. It also prevents any |
| number of “interesting” compiler optimizations, for example, the use of |
| ``gp`` as a scratch location immediately preceding the assignment. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | But rcu_assign_pointer() does nothing to prevent the two | |
| | assignments to ``p->a`` and ``p->b`` from being reordered. Can't that | |
| | also cause problems? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | No, it cannot. The readers cannot see either of these two fields | |
| | until the assignment to ``gp``, by which time both fields are fully | |
| | initialized. So reordering the assignments to ``p->a`` and ``p->b`` | |
| | cannot possibly cause any problems. | |
| +-----------------------------------------------------------------------+ |
| |
| It is tempting to assume that the reader need not do anything special to |
| control its accesses to the RCU-protected data, as shown in |
| do_something_gp_buggy() below: |
| |
| :: |
| |
| 1 bool do_something_gp_buggy(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 p = gp; /* OPTIMIZATIONS GALORE!!! */ |
| 5 if (p) { |
| 6 do_something(p->a, p->b); |
| 7 rcu_read_unlock(); |
| 8 return true; |
| 9 } |
| 10 rcu_read_unlock(); |
| 11 return false; |
| 12 } |
| |
| However, this temptation must be resisted because there are a |
| surprisingly large number of ways that the compiler (or weak ordering |
| CPUs like the DEC Alpha) can trip this code up. For but one example, if |
| the compiler were short of registers, it might choose to refetch from |
| ``gp`` rather than keeping a separate copy in ``p`` as follows: |
| |
| :: |
| |
| 1 bool do_something_gp_buggy_optimized(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 if (gp) { /* OPTIMIZATIONS GALORE!!! */ |
| 5 do_something(gp->a, gp->b); |
| 6 rcu_read_unlock(); |
| 7 return true; |
| 8 } |
| 9 rcu_read_unlock(); |
| 10 return false; |
| 11 } |
| |
| If this function ran concurrently with a series of updates that replaced |
| the current structure with a new one, the fetches of ``gp->a`` and |
| ``gp->b`` might well come from two different structures, which could |
| cause serious confusion. To prevent this (and much else besides), |
| do_something_gp() uses rcu_dereference() to fetch from ``gp``: |
| |
| :: |
| |
| 1 bool do_something_gp(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 p = rcu_dereference(gp); |
| 5 if (p) { |
| 6 do_something(p->a, p->b); |
| 7 rcu_read_unlock(); |
| 8 return true; |
| 9 } |
| 10 rcu_read_unlock(); |
| 11 return false; |
| 12 } |
| |
| The rcu_dereference() uses volatile casts and (for DEC Alpha) memory |
| barriers in the Linux kernel. Should a |high-quality implementation of |
| C11 memory_order_consume [PDF]|_ |
| ever appear, then rcu_dereference() could be implemented as a |
| ``memory_order_consume`` load. Regardless of the exact implementation, a |
| pointer fetched by rcu_dereference() may not be used outside of the |
| outermost RCU read-side critical section containing that |
| rcu_dereference(), unless protection of the corresponding data |
| element has been passed from RCU to some other synchronization |
| mechanism, most commonly locking or reference counting |
| (see ../../rcuref.rst). |
| |
| .. |high-quality implementation of C11 memory_order_consume [PDF]| replace:: high-quality implementation of C11 ``memory_order_consume`` [PDF] |
| .. _high-quality implementation of C11 memory_order_consume [PDF]: http://www.rdrop.com/users/paulmck/RCU/consume.2015.07.13a.pdf |
| |
| In short, updaters use rcu_assign_pointer() and readers use |
| rcu_dereference(), and these two RCU API elements work together to |
| ensure that readers have a consistent view of newly added data elements. |
| |
| Of course, it is also necessary to remove elements from RCU-protected |
| data structures, for example, using the following process: |
| |
| #. Remove the data element from the enclosing structure. |
| #. Wait for all pre-existing RCU read-side critical sections to complete |
| (because only pre-existing readers can possibly have a reference to |
| the newly removed data element). |
| #. At this point, only the updater has a reference to the newly removed |
| data element, so it can safely reclaim the data element, for example, |
| by passing it to kfree(). |
| |
| This process is implemented by remove_gp_synchronous(): |
| |
| :: |
| |
| 1 bool remove_gp_synchronous(void) |
| 2 { |
| 3 struct foo *p; |
| 4 |
| 5 spin_lock(&gp_lock); |
| 6 p = rcu_access_pointer(gp); |
| 7 if (!p) { |
| 8 spin_unlock(&gp_lock); |
| 9 return false; |
| 10 } |
| 11 rcu_assign_pointer(gp, NULL); |
| 12 spin_unlock(&gp_lock); |
| 13 synchronize_rcu(); |
| 14 kfree(p); |
| 15 return true; |
| 16 } |
| |
| This function is straightforward, with line 13 waiting for a grace |
| period before line 14 frees the old data element. This waiting ensures |
| that readers will reach line 7 of do_something_gp() before the data |
| element referenced by ``p`` is freed. The rcu_access_pointer() on |
| line 6 is similar to rcu_dereference(), except that: |
| |
| #. The value returned by rcu_access_pointer() cannot be |
| dereferenced. If you want to access the value pointed to as well as |
| the pointer itself, use rcu_dereference() instead of |
| rcu_access_pointer(). |
| #. The call to rcu_access_pointer() need not be protected. In |
| contrast, rcu_dereference() must either be within an RCU |
| read-side critical section or in a code segment where the pointer |
| cannot change, for example, in code protected by the corresponding |
| update-side lock. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Without the rcu_dereference() or the rcu_access_pointer(), | |
| | what destructive optimizations might the compiler make use of? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | Let's start with what happens to do_something_gp() if it fails to | |
| | use rcu_dereference(). It could reuse a value formerly fetched | |
| | from this same pointer. It could also fetch the pointer from ``gp`` | |
| | in a byte-at-a-time manner, resulting in *load tearing*, in turn | |
| | resulting a bytewise mash-up of two distinct pointer values. It might | |
| | even use value-speculation optimizations, where it makes a wrong | |
| | guess, but by the time it gets around to checking the value, an | |
| | update has changed the pointer to match the wrong guess. Too bad | |
| | about any dereferences that returned pre-initialization garbage in | |
| | the meantime! | |
| | For remove_gp_synchronous(), as long as all modifications to | |
| | ``gp`` are carried out while holding ``gp_lock``, the above | |
| | optimizations are harmless. However, ``sparse`` will complain if you | |
| | define ``gp`` with ``__rcu`` and then access it without using either | |
| | rcu_access_pointer() or rcu_dereference(). | |
| +-----------------------------------------------------------------------+ |
| |
| In short, RCU's publish-subscribe guarantee is provided by the |
| combination of rcu_assign_pointer() and rcu_dereference(). This |
| guarantee allows data elements to be safely added to RCU-protected |
| linked data structures without disrupting RCU readers. This guarantee |
| can be used in combination with the grace-period guarantee to also allow |
| data elements to be removed from RCU-protected linked data structures, |
| again without disrupting RCU readers. |
| |
| This guarantee was only partially premeditated. DYNIX/ptx used an |
| explicit memory barrier for publication, but had nothing resembling |
| rcu_dereference() for subscription, nor did it have anything |
| resembling the dependency-ordering barrier that was later subsumed |
| into rcu_dereference() and later still into READ_ONCE(). The |
| need for these operations made itself known quite suddenly at a |
| late-1990s meeting with the DEC Alpha architects, back in the days when |
| DEC was still a free-standing company. It took the Alpha architects a |
| good hour to convince me that any sort of barrier would ever be needed, |
| and it then took me a good *two* hours to convince them that their |
| documentation did not make this point clear. More recent work with the C |
| and C++ standards committees have provided much education on tricks and |
| traps from the compiler. In short, compilers were much less tricky in |
| the early 1990s, but in 2015, don't even think about omitting |
| rcu_dereference()! |
| |
| Memory-Barrier Guarantees |
| ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The previous section's simple linked-data-structure scenario clearly |
| demonstrates the need for RCU's stringent memory-ordering guarantees on |
| systems with more than one CPU: |
| |
| #. Each CPU that has an RCU read-side critical section that begins |
| before synchronize_rcu() starts is guaranteed to execute a full |
| memory barrier between the time that the RCU read-side critical |
| section ends and the time that synchronize_rcu() returns. Without |
| this guarantee, a pre-existing RCU read-side critical section might |
| hold a reference to the newly removed ``struct foo`` after the |
| kfree() on line 14 of remove_gp_synchronous(). |
| #. Each CPU that has an RCU read-side critical section that ends after |
| synchronize_rcu() returns is guaranteed to execute a full memory |
| barrier between the time that synchronize_rcu() begins and the |
| time that the RCU read-side critical section begins. Without this |
| guarantee, a later RCU read-side critical section running after the |
| kfree() on line 14 of remove_gp_synchronous() might later run |
| do_something_gp() and find the newly deleted ``struct foo``. |
| #. If the task invoking synchronize_rcu() remains on a given CPU, |
| then that CPU is guaranteed to execute a full memory barrier sometime |
| during the execution of synchronize_rcu(). This guarantee ensures |
| that the kfree() on line 14 of remove_gp_synchronous() really |
| does execute after the removal on line 11. |
| #. If the task invoking synchronize_rcu() migrates among a group of |
| CPUs during that invocation, then each of the CPUs in that group is |
| guaranteed to execute a full memory barrier sometime during the |
| execution of synchronize_rcu(). This guarantee also ensures that |
| the kfree() on line 14 of remove_gp_synchronous() really does |
| execute after the removal on line 11, but also in the case where the |
| thread executing the synchronize_rcu() migrates in the meantime. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Given that multiple CPUs can start RCU read-side critical sections at | |
| | any time without any ordering whatsoever, how can RCU possibly tell | |
| | whether or not a given RCU read-side critical section starts before a | |
| | given instance of synchronize_rcu()? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | If RCU cannot tell whether or not a given RCU read-side critical | |
| | section starts before a given instance of synchronize_rcu(), then | |
| | it must assume that the RCU read-side critical section started first. | |
| | In other words, a given instance of synchronize_rcu() can avoid | |
| | waiting on a given RCU read-side critical section only if it can | |
| | prove that synchronize_rcu() started first. | |
| | A related question is “When rcu_read_lock() doesn't generate any | |
| | code, why does it matter how it relates to a grace period?” The | |
| | answer is that it is not the relationship of rcu_read_lock() | |
| | itself that is important, but rather the relationship of the code | |
| | within the enclosed RCU read-side critical section to the code | |
| | preceding and following the grace period. If we take this viewpoint, | |
| | then a given RCU read-side critical section begins before a given | |
| | grace period when some access preceding the grace period observes the | |
| | effect of some access within the critical section, in which case none | |
| | of the accesses within the critical section may observe the effects | |
| | of any access following the grace period. | |
| | | |
| | As of late 2016, mathematical models of RCU take this viewpoint, for | |
| | example, see slides 62 and 63 of the `2016 LinuxCon | |
| | EU <http://www2.rdrop.com/users/paulmck/scalability/paper/LinuxMM.201 | |
| | 6.10.04c.LCE.pdf>`__ | |
| | presentation. | |
| +-----------------------------------------------------------------------+ |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | The first and second guarantees require unbelievably strict ordering! | |
| | Are all these memory barriers *really* required? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | Yes, they really are required. To see why the first guarantee is | |
| | required, consider the following sequence of events: | |
| | | |
| | #. CPU 1: rcu_read_lock() | |
| | #. CPU 1: ``q = rcu_dereference(gp); /* Very likely to return p. */`` | |
| | #. CPU 0: ``list_del_rcu(p);`` | |
| | #. CPU 0: synchronize_rcu() starts. | |
| | #. CPU 1: ``do_something_with(q->a);`` | |
| | ``/* No smp_mb(), so might happen after kfree(). */`` | |
| | #. CPU 1: rcu_read_unlock() | |
| | #. CPU 0: synchronize_rcu() returns. | |
| | #. CPU 0: ``kfree(p);`` | |
| | | |
| | Therefore, there absolutely must be a full memory barrier between the | |
| | end of the RCU read-side critical section and the end of the grace | |
| | period. | |
| | | |
| | The sequence of events demonstrating the necessity of the second rule | |
| | is roughly similar: | |
| | | |
| | #. CPU 0: ``list_del_rcu(p);`` | |
| | #. CPU 0: synchronize_rcu() starts. | |
| | #. CPU 1: rcu_read_lock() | |
| | #. CPU 1: ``q = rcu_dereference(gp);`` | |
| | ``/* Might return p if no memory barrier. */`` | |
| | #. CPU 0: synchronize_rcu() returns. | |
| | #. CPU 0: ``kfree(p);`` | |
| | #. CPU 1: ``do_something_with(q->a); /* Boom!!! */`` | |
| | #. CPU 1: rcu_read_unlock() | |
| | | |
| | And similarly, without a memory barrier between the beginning of the | |
| | grace period and the beginning of the RCU read-side critical section, | |
| | CPU 1 might end up accessing the freelist. | |
| | | |
| | The “as if” rule of course applies, so that any implementation that | |
| | acts as if the appropriate memory barriers were in place is a correct | |
| | implementation. That said, it is much easier to fool yourself into | |
| | believing that you have adhered to the as-if rule than it is to | |
| | actually adhere to it! | |
| +-----------------------------------------------------------------------+ |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | You claim that rcu_read_lock() and rcu_read_unlock() generate | |
| | absolutely no code in some kernel builds. This means that the | |
| | compiler might arbitrarily rearrange consecutive RCU read-side | |
| | critical sections. Given such rearrangement, if a given RCU read-side | |
| | critical section is done, how can you be sure that all prior RCU | |
| | read-side critical sections are done? Won't the compiler | |
| | rearrangements make that impossible to determine? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | In cases where rcu_read_lock() and rcu_read_unlock() generate | |
| | absolutely no code, RCU infers quiescent states only at special | |
| | locations, for example, within the scheduler. Because calls to | |
| | schedule() had better prevent calling-code accesses to shared | |
| | variables from being rearranged across the call to schedule(), if | |
| | RCU detects the end of a given RCU read-side critical section, it | |
| | will necessarily detect the end of all prior RCU read-side critical | |
| | sections, no matter how aggressively the compiler scrambles the code. | |
| | Again, this all assumes that the compiler cannot scramble code across | |
| | calls to the scheduler, out of interrupt handlers, into the idle | |
| | loop, into user-mode code, and so on. But if your kernel build allows | |
| | that sort of scrambling, you have broken far more than just RCU! | |
| +-----------------------------------------------------------------------+ |
| |
| Note that these memory-barrier requirements do not replace the |
| fundamental RCU requirement that a grace period wait for all |
| pre-existing readers. On the contrary, the memory barriers called out in |
| this section must operate in such a way as to *enforce* this fundamental |
| requirement. Of course, different implementations enforce this |
| requirement in different ways, but enforce it they must. |
| |
| RCU Primitives Guaranteed to Execute Unconditionally |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The common-case RCU primitives are unconditional. They are invoked, they |
| do their job, and they return, with no possibility of error, and no need |
| to retry. This is a key RCU design philosophy. |
| |
| However, this philosophy is pragmatic rather than pigheaded. If someone |
| comes up with a good justification for a particular conditional RCU |
| primitive, it might well be implemented and added. After all, this |
| guarantee was reverse-engineered, not premeditated. The unconditional |
| nature of the RCU primitives was initially an accident of |
| implementation, and later experience with synchronization primitives |
| with conditional primitives caused me to elevate this accident to a |
| guarantee. Therefore, the justification for adding a conditional |
| primitive to RCU would need to be based on detailed and compelling use |
| cases. |
| |
| Guaranteed Read-to-Write Upgrade |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| As far as RCU is concerned, it is always possible to carry out an update |
| within an RCU read-side critical section. For example, that RCU |
| read-side critical section might search for a given data element, and |
| then might acquire the update-side spinlock in order to update that |
| element, all while remaining in that RCU read-side critical section. Of |
| course, it is necessary to exit the RCU read-side critical section |
| before invoking synchronize_rcu(), however, this inconvenience can |
| be avoided through use of the call_rcu() and kfree_rcu() API |
| members described later in this document. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | But how does the upgrade-to-write operation exclude other readers? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | It doesn't, just like normal RCU updates, which also do not exclude | |
| | RCU readers. | |
| +-----------------------------------------------------------------------+ |
| |
| This guarantee allows lookup code to be shared between read-side and |
| update-side code, and was premeditated, appearing in the earliest |
| DYNIX/ptx RCU documentation. |
| |
| Fundamental Non-Requirements |
| ---------------------------- |
| |
| RCU provides extremely lightweight readers, and its read-side |
| guarantees, though quite useful, are correspondingly lightweight. It is |
| therefore all too easy to assume that RCU is guaranteeing more than it |
| really is. Of course, the list of things that RCU does not guarantee is |
| infinitely long, however, the following sections list a few |
| non-guarantees that have caused confusion. Except where otherwise noted, |
| these non-guarantees were premeditated. |
| |
| #. `Readers Impose Minimal Ordering`_ |
| #. `Readers Do Not Exclude Updaters`_ |
| #. `Updaters Only Wait For Old Readers`_ |
| #. `Grace Periods Don't Partition Read-Side Critical Sections`_ |
| #. `Read-Side Critical Sections Don't Partition Grace Periods`_ |
| |
| Readers Impose Minimal Ordering |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Reader-side markers such as rcu_read_lock() and |
| rcu_read_unlock() provide absolutely no ordering guarantees except |
| through their interaction with the grace-period APIs such as |
| synchronize_rcu(). To see this, consider the following pair of |
| threads: |
| |
| :: |
| |
| 1 void thread0(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 WRITE_ONCE(x, 1); |
| 5 rcu_read_unlock(); |
| 6 rcu_read_lock(); |
| 7 WRITE_ONCE(y, 1); |
| 8 rcu_read_unlock(); |
| 9 } |
| 10 |
| 11 void thread1(void) |
| 12 { |
| 13 rcu_read_lock(); |
| 14 r1 = READ_ONCE(y); |
| 15 rcu_read_unlock(); |
| 16 rcu_read_lock(); |
| 17 r2 = READ_ONCE(x); |
| 18 rcu_read_unlock(); |
| 19 } |
| |
| After thread0() and thread1() execute concurrently, it is quite |
| possible to have |
| |
| :: |
| |
| (r1 == 1 && r2 == 0) |
| |
| (that is, ``y`` appears to have been assigned before ``x``), which would |
| not be possible if rcu_read_lock() and rcu_read_unlock() had |
| much in the way of ordering properties. But they do not, so the CPU is |
| within its rights to do significant reordering. This is by design: Any |
| significant ordering constraints would slow down these fast-path APIs. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Can't the compiler also reorder this code? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | No, the volatile casts in READ_ONCE() and WRITE_ONCE() | |
| | prevent the compiler from reordering in this particular case. | |
| +-----------------------------------------------------------------------+ |
| |
| Readers Do Not Exclude Updaters |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Neither rcu_read_lock() nor rcu_read_unlock() exclude updates. |
| All they do is to prevent grace periods from ending. The following |
| example illustrates this: |
| |
| :: |
| |
| 1 void thread0(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 r1 = READ_ONCE(y); |
| 5 if (r1) { |
| 6 do_something_with_nonzero_x(); |
| 7 r2 = READ_ONCE(x); |
| 8 WARN_ON(!r2); /* BUG!!! */ |
| 9 } |
| 10 rcu_read_unlock(); |
| 11 } |
| 12 |
| 13 void thread1(void) |
| 14 { |
| 15 spin_lock(&my_lock); |
| 16 WRITE_ONCE(x, 1); |
| 17 WRITE_ONCE(y, 1); |
| 18 spin_unlock(&my_lock); |
| 19 } |
| |
| If the thread0() function's rcu_read_lock() excluded the |
| thread1() function's update, the WARN_ON() could never fire. But |
| the fact is that rcu_read_lock() does not exclude much of anything |
| aside from subsequent grace periods, of which thread1() has none, so |
| the WARN_ON() can and does fire. |
| |
| Updaters Only Wait For Old Readers |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| It might be tempting to assume that after synchronize_rcu() |
| completes, there are no readers executing. This temptation must be |
| avoided because new readers can start immediately after |
| synchronize_rcu() starts, and synchronize_rcu() is under no |
| obligation to wait for these new readers. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Suppose that synchronize_rcu() did wait until *all* readers had | |
| | completed instead of waiting only on pre-existing readers. For how | |
| | long would the updater be able to rely on there being no readers? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | For no time at all. Even if synchronize_rcu() were to wait until | |
| | all readers had completed, a new reader might start immediately after | |
| | synchronize_rcu() completed. Therefore, the code following | |
| | synchronize_rcu() can *never* rely on there being no readers. | |
| +-----------------------------------------------------------------------+ |
| |
| Grace Periods Don't Partition Read-Side Critical Sections |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| It is tempting to assume that if any part of one RCU read-side critical |
| section precedes a given grace period, and if any part of another RCU |
| read-side critical section follows that same grace period, then all of |
| the first RCU read-side critical section must precede all of the second. |
| However, this just isn't the case: A single grace period does not |
| partition the set of RCU read-side critical sections. An example of this |
| situation can be illustrated as follows, where ``x``, ``y``, and ``z`` |
| are initially all zero: |
| |
| :: |
| |
| 1 void thread0(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 WRITE_ONCE(a, 1); |
| 5 WRITE_ONCE(b, 1); |
| 6 rcu_read_unlock(); |
| 7 } |
| 8 |
| 9 void thread1(void) |
| 10 { |
| 11 r1 = READ_ONCE(a); |
| 12 synchronize_rcu(); |
| 13 WRITE_ONCE(c, 1); |
| 14 } |
| 15 |
| 16 void thread2(void) |
| 17 { |
| 18 rcu_read_lock(); |
| 19 r2 = READ_ONCE(b); |
| 20 r3 = READ_ONCE(c); |
| 21 rcu_read_unlock(); |
| 22 } |
| |
| It turns out that the outcome: |
| |
| :: |
| |
| (r1 == 1 && r2 == 0 && r3 == 1) |
| |
| is entirely possible. The following figure show how this can happen, |
| with each circled ``QS`` indicating the point at which RCU recorded a |
| *quiescent state* for each thread, that is, a state in which RCU knows |
| that the thread cannot be in the midst of an RCU read-side critical |
| section that started before the current grace period: |
| |
| .. kernel-figure:: GPpartitionReaders1.svg |
| |
| If it is necessary to partition RCU read-side critical sections in this |
| manner, it is necessary to use two grace periods, where the first grace |
| period is known to end before the second grace period starts: |
| |
| :: |
| |
| 1 void thread0(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 WRITE_ONCE(a, 1); |
| 5 WRITE_ONCE(b, 1); |
| 6 rcu_read_unlock(); |
| 7 } |
| 8 |
| 9 void thread1(void) |
| 10 { |
| 11 r1 = READ_ONCE(a); |
| 12 synchronize_rcu(); |
| 13 WRITE_ONCE(c, 1); |
| 14 } |
| 15 |
| 16 void thread2(void) |
| 17 { |
| 18 r2 = READ_ONCE(c); |
| 19 synchronize_rcu(); |
| 20 WRITE_ONCE(d, 1); |
| 21 } |
| 22 |
| 23 void thread3(void) |
| 24 { |
| 25 rcu_read_lock(); |
| 26 r3 = READ_ONCE(b); |
| 27 r4 = READ_ONCE(d); |
| 28 rcu_read_unlock(); |
| 29 } |
| |
| Here, if ``(r1 == 1)``, then thread0()'s write to ``b`` must happen |
| before the end of thread1()'s grace period. If in addition |
| ``(r4 == 1)``, then thread3()'s read from ``b`` must happen after |
| the beginning of thread2()'s grace period. If it is also the case |
| that ``(r2 == 1)``, then the end of thread1()'s grace period must |
| precede the beginning of thread2()'s grace period. This mean that |
| the two RCU read-side critical sections cannot overlap, guaranteeing |
| that ``(r3 == 1)``. As a result, the outcome: |
| |
| :: |
| |
| (r1 == 1 && r2 == 1 && r3 == 0 && r4 == 1) |
| |
| cannot happen. |
| |
| This non-requirement was also non-premeditated, but became apparent when |
| studying RCU's interaction with memory ordering. |
| |
| Read-Side Critical Sections Don't Partition Grace Periods |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| It is also tempting to assume that if an RCU read-side critical section |
| happens between a pair of grace periods, then those grace periods cannot |
| overlap. However, this temptation leads nowhere good, as can be |
| illustrated by the following, with all variables initially zero: |
| |
| :: |
| |
| 1 void thread0(void) |
| 2 { |
| 3 rcu_read_lock(); |
| 4 WRITE_ONCE(a, 1); |
| 5 WRITE_ONCE(b, 1); |
| 6 rcu_read_unlock(); |
| 7 } |
| 8 |
| 9 void thread1(void) |
| 10 { |
| 11 r1 = READ_ONCE(a); |
| 12 synchronize_rcu(); |
| 13 WRITE_ONCE(c, 1); |
| 14 } |
| 15 |
| 16 void thread2(void) |
| 17 { |
| 18 rcu_read_lock(); |
| 19 WRITE_ONCE(d, 1); |
| 20 r2 = READ_ONCE(c); |
| 21 rcu_read_unlock(); |
| 22 } |
| 23 |
| 24 void thread3(void) |
| 25 { |
| 26 r3 = READ_ONCE(d); |
| 27 synchronize_rcu(); |
| 28 WRITE_ONCE(e, 1); |
| 29 } |
| 30 |
| 31 void thread4(void) |
| 32 { |
| 33 rcu_read_lock(); |
| 34 r4 = READ_ONCE(b); |
| 35 r5 = READ_ONCE(e); |
| 36 rcu_read_unlock(); |
| 37 } |
| |
| In this case, the outcome: |
| |
| :: |
| |
| (r1 == 1 && r2 == 1 && r3 == 1 && r4 == 0 && r5 == 1) |
| |
| is entirely possible, as illustrated below: |
| |
| .. kernel-figure:: ReadersPartitionGP1.svg |
| |
| Again, an RCU read-side critical section can overlap almost all of a |
| given grace period, just so long as it does not overlap the entire grace |
| period. As a result, an RCU read-side critical section cannot partition |
| a pair of RCU grace periods. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | How long a sequence of grace periods, each separated by an RCU | |
| | read-side critical section, would be required to partition the RCU | |
| | read-side critical sections at the beginning and end of the chain? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | In theory, an infinite number. In practice, an unknown number that is | |
| | sensitive to both implementation details and timing considerations. | |
| | Therefore, even in practice, RCU users must abide by the theoretical | |
| | rather than the practical answer. | |
| +-----------------------------------------------------------------------+ |
| |
| Parallelism Facts of Life |
| ------------------------- |
| |
| These parallelism facts of life are by no means specific to RCU, but the |
| RCU implementation must abide by them. They therefore bear repeating: |
| |
| #. Any CPU or task may be delayed at any time, and any attempts to avoid |
| these delays by disabling preemption, interrupts, or whatever are |
| completely futile. This is most obvious in preemptible user-level |
| environments and in virtualized environments (where a given guest |
| OS's VCPUs can be preempted at any time by the underlying |
| hypervisor), but can also happen in bare-metal environments due to |
| ECC errors, NMIs, and other hardware events. Although a delay of more |
| than about 20 seconds can result in splats, the RCU implementation is |
| obligated to use algorithms that can tolerate extremely long delays, |
| but where “extremely long” is not long enough to allow wrap-around |
| when incrementing a 64-bit counter. |
| #. Both the compiler and the CPU can reorder memory accesses. Where it |
| matters, RCU must use compiler directives and memory-barrier |
| instructions to preserve ordering. |
| #. Conflicting writes to memory locations in any given cache line will |
| result in expensive cache misses. Greater numbers of concurrent |
| writes and more-frequent concurrent writes will result in more |
| dramatic slowdowns. RCU is therefore obligated to use algorithms that |
| have sufficient locality to avoid significant performance and |
| scalability problems. |
| #. As a rough rule of thumb, only one CPU's worth of processing may be |
| carried out under the protection of any given exclusive lock. RCU |
| must therefore use scalable locking designs. |
| #. Counters are finite, especially on 32-bit systems. RCU's use of |
| counters must therefore tolerate counter wrap, or be designed such |
| that counter wrap would take way more time than a single system is |
| likely to run. An uptime of ten years is quite possible, a runtime of |
| a century much less so. As an example of the latter, RCU's |
| dyntick-idle nesting counter allows 54 bits for interrupt nesting |
| level (this counter is 64 bits even on a 32-bit system). Overflowing |
| this counter requires 2\ :sup:`54` half-interrupts on a given CPU |
| without that CPU ever going idle. If a half-interrupt happened every |
| microsecond, it would take 570 years of runtime to overflow this |
| counter, which is currently believed to be an acceptably long time. |
| #. Linux systems can have thousands of CPUs running a single Linux |
| kernel in a single shared-memory environment. RCU must therefore pay |
| close attention to high-end scalability. |
| |
| This last parallelism fact of life means that RCU must pay special |
| attention to the preceding facts of life. The idea that Linux might |
| scale to systems with thousands of CPUs would have been met with some |
| skepticism in the 1990s, but these requirements would have otherwise |
| have been unsurprising, even in the early 1990s. |
| |
| Quality-of-Implementation Requirements |
| -------------------------------------- |
| |
| These sections list quality-of-implementation requirements. Although an |
| RCU implementation that ignores these requirements could still be used, |
| it would likely be subject to limitations that would make it |
| inappropriate for industrial-strength production use. Classes of |
| quality-of-implementation requirements are as follows: |
| |
| #. `Specialization`_ |
| #. `Performance and Scalability`_ |
| #. `Forward Progress`_ |
| #. `Composability`_ |
| #. `Corner Cases`_ |
| |
| These classes is covered in the following sections. |
| |
| Specialization |
| ~~~~~~~~~~~~~~ |
| |
| RCU is and always has been intended primarily for read-mostly |
| situations, which means that RCU's read-side primitives are optimized, |
| often at the expense of its update-side primitives. Experience thus far |
| is captured by the following list of situations: |
| |
| #. Read-mostly data, where stale and inconsistent data is not a problem: |
| RCU works great! |
| #. Read-mostly data, where data must be consistent: RCU works well. |
| #. Read-write data, where data must be consistent: RCU *might* work OK. |
| Or not. |
| #. Write-mostly data, where data must be consistent: RCU is very |
| unlikely to be the right tool for the job, with the following |
| exceptions, where RCU can provide: |
| |
| a. Existence guarantees for update-friendly mechanisms. |
| b. Wait-free read-side primitives for real-time use. |
| |
| This focus on read-mostly situations means that RCU must interoperate |
| with other synchronization primitives. For example, the add_gp() and |
| remove_gp_synchronous() examples discussed earlier use RCU to |
| protect readers and locking to coordinate updaters. However, the need |
| extends much farther, requiring that a variety of synchronization |
| primitives be legal within RCU read-side critical sections, including |
| spinlocks, sequence locks, atomic operations, reference counters, and |
| memory barriers. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | What about sleeping locks? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | These are forbidden within Linux-kernel RCU read-side critical | |
| | sections because it is not legal to place a quiescent state (in this | |
| | case, voluntary context switch) within an RCU read-side critical | |
| | section. However, sleeping locks may be used within userspace RCU | |
| | read-side critical sections, and also within Linux-kernel sleepable | |
| | RCU `(SRCU) <Sleepable RCU_>`__ read-side critical sections. In | |
| | addition, the -rt patchset turns spinlocks into a sleeping locks so | |
| | that the corresponding critical sections can be preempted, which also | |
| | means that these sleeplockified spinlocks (but not other sleeping | |
| | locks!) may be acquire within -rt-Linux-kernel RCU read-side critical | |
| | sections. | |
| | Note that it *is* legal for a normal RCU read-side critical section | |
| | to conditionally acquire a sleeping locks (as in | |
| | mutex_trylock()), but only as long as it does not loop | |
| | indefinitely attempting to conditionally acquire that sleeping locks. | |
| | The key point is that things like mutex_trylock() either return | |
| | with the mutex held, or return an error indication if the mutex was | |
| | not immediately available. Either way, mutex_trylock() returns | |
| | immediately without sleeping. | |
| +-----------------------------------------------------------------------+ |
| |
| It often comes as a surprise that many algorithms do not require a |
| consistent view of data, but many can function in that mode, with |
| network routing being the poster child. Internet routing algorithms take |
| significant time to propagate updates, so that by the time an update |
| arrives at a given system, that system has been sending network traffic |
| the wrong way for a considerable length of time. Having a few threads |
| continue to send traffic the wrong way for a few more milliseconds is |
| clearly not a problem: In the worst case, TCP retransmissions will |
| eventually get the data where it needs to go. In general, when tracking |
| the state of the universe outside of the computer, some level of |
| inconsistency must be tolerated due to speed-of-light delays if nothing |
| else. |
| |
| Furthermore, uncertainty about external state is inherent in many cases. |
| For example, a pair of veterinarians might use heartbeat to determine |
| whether or not a given cat was alive. But how long should they wait |
| after the last heartbeat to decide that the cat is in fact dead? Waiting |
| less than 400 milliseconds makes no sense because this would mean that a |
| relaxed cat would be considered to cycle between death and life more |
| than 100 times per minute. Moreover, just as with human beings, a cat's |
| heart might stop for some period of time, so the exact wait period is a |
| judgment call. One of our pair of veterinarians might wait 30 seconds |
| before pronouncing the cat dead, while the other might insist on waiting |
| a full minute. The two veterinarians would then disagree on the state of |
| the cat during the final 30 seconds of the minute following the last |
| heartbeat. |
| |
| Interestingly enough, this same situation applies to hardware. When push |
| comes to shove, how do we tell whether or not some external server has |
| failed? We send messages to it periodically, and declare it failed if we |
| don't receive a response within a given period of time. Policy decisions |
| can usually tolerate short periods of inconsistency. The policy was |
| decided some time ago, and is only now being put into effect, so a few |
| milliseconds of delay is normally inconsequential. |
| |
| However, there are algorithms that absolutely must see consistent data. |
| For example, the translation between a user-level SystemV semaphore ID |
| to the corresponding in-kernel data structure is protected by RCU, but |
| it is absolutely forbidden to update a semaphore that has just been |
| removed. In the Linux kernel, this need for consistency is accommodated |
| by acquiring spinlocks located in the in-kernel data structure from |
| within the RCU read-side critical section, and this is indicated by the |
| green box in the figure above. Many other techniques may be used, and |
| are in fact used within the Linux kernel. |
| |
| In short, RCU is not required to maintain consistency, and other |
| mechanisms may be used in concert with RCU when consistency is required. |
| RCU's specialization allows it to do its job extremely well, and its |
| ability to interoperate with other synchronization mechanisms allows the |
| right mix of synchronization tools to be used for a given job. |
| |
| Performance and Scalability |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Energy efficiency is a critical component of performance today, and |
| Linux-kernel RCU implementations must therefore avoid unnecessarily |
| awakening idle CPUs. I cannot claim that this requirement was |
| premeditated. In fact, I learned of it during a telephone conversation |
| in which I was given “frank and open” feedback on the importance of |
| energy efficiency in battery-powered systems and on specific |
| energy-efficiency shortcomings of the Linux-kernel RCU implementation. |
| In my experience, the battery-powered embedded community will consider |
| any unnecessary wakeups to be extremely unfriendly acts. So much so that |
| mere Linux-kernel-mailing-list posts are insufficient to vent their ire. |
| |
| Memory consumption is not particularly important for in most situations, |
| and has become decreasingly so as memory sizes have expanded and memory |
| costs have plummeted. However, as I learned from Matt Mackall's |
| `bloatwatch <http://elinux.org/Linux_Tiny-FAQ>`__ efforts, memory |
| footprint is critically important on single-CPU systems with |
| non-preemptible (``CONFIG_PREEMPTION=n``) kernels, and thus `tiny |
| RCU <https://lore.kernel.org/r/20090113221724.GA15307@linux.vnet.ibm.com>`__ |
| was born. Josh Triplett has since taken over the small-memory banner |
| with his `Linux kernel tinification <https://tiny.wiki.kernel.org/>`__ |
| project, which resulted in `SRCU <Sleepable RCU_>`__ becoming optional |
| for those kernels not needing it. |
| |
| The remaining performance requirements are, for the most part, |
| unsurprising. For example, in keeping with RCU's read-side |
| specialization, rcu_dereference() should have negligible overhead |
| (for example, suppression of a few minor compiler optimizations). |
| Similarly, in non-preemptible environments, rcu_read_lock() and |
| rcu_read_unlock() should have exactly zero overhead. |
| |
| In preemptible environments, in the case where the RCU read-side |
| critical section was not preempted (as will be the case for the |
| highest-priority real-time process), rcu_read_lock() and |
| rcu_read_unlock() should have minimal overhead. In particular, they |
| should not contain atomic read-modify-write operations, memory-barrier |
| instructions, preemption disabling, interrupt disabling, or backwards |
| branches. However, in the case where the RCU read-side critical section |
| was preempted, rcu_read_unlock() may acquire spinlocks and disable |
| interrupts. This is why it is better to nest an RCU read-side critical |
| section within a preempt-disable region than vice versa, at least in |
| cases where that critical section is short enough to avoid unduly |
| degrading real-time latencies. |
| |
| The synchronize_rcu() grace-period-wait primitive is optimized for |
| throughput. It may therefore incur several milliseconds of latency in |
| addition to the duration of the longest RCU read-side critical section. |
| On the other hand, multiple concurrent invocations of |
| synchronize_rcu() are required to use batching optimizations so that |
| they can be satisfied by a single underlying grace-period-wait |
| operation. For example, in the Linux kernel, it is not unusual for a |
| single grace-period-wait operation to serve more than `1,000 separate |
| invocations <https://www.usenix.org/conference/2004-usenix-annual-technical-conference/making-rcu-safe-deep-sub-millisecond-response>`__ |
| of synchronize_rcu(), thus amortizing the per-invocation overhead |
| down to nearly zero. However, the grace-period optimization is also |
| required to avoid measurable degradation of real-time scheduling and |
| interrupt latencies. |
| |
| In some cases, the multi-millisecond synchronize_rcu() latencies are |
| unacceptable. In these cases, synchronize_rcu_expedited() may be |
| used instead, reducing the grace-period latency down to a few tens of |
| microseconds on small systems, at least in cases where the RCU read-side |
| critical sections are short. There are currently no special latency |
| requirements for synchronize_rcu_expedited() on large systems, but, |
| consistent with the empirical nature of the RCU specification, that is |
| subject to change. However, there most definitely are scalability |
| requirements: A storm of synchronize_rcu_expedited() invocations on |
| 4096 CPUs should at least make reasonable forward progress. In return |
| for its shorter latencies, synchronize_rcu_expedited() is permitted |
| to impose modest degradation of real-time latency on non-idle online |
| CPUs. Here, “modest” means roughly the same latency degradation as a |
| scheduling-clock interrupt. |
| |
| There are a number of situations where even |
| synchronize_rcu_expedited()'s reduced grace-period latency is |
| unacceptable. In these situations, the asynchronous call_rcu() can |
| be used in place of synchronize_rcu() as follows: |
| |
| :: |
| |
| 1 struct foo { |
| 2 int a; |
| 3 int b; |
| 4 struct rcu_head rh; |
| 5 }; |
| 6 |
| 7 static void remove_gp_cb(struct rcu_head *rhp) |
| 8 { |
| 9 struct foo *p = container_of(rhp, struct foo, rh); |
| 10 |
| 11 kfree(p); |
| 12 } |
| 13 |
| 14 bool remove_gp_asynchronous(void) |
| 15 { |
| 16 struct foo *p; |
| 17 |
| 18 spin_lock(&gp_lock); |
| 19 p = rcu_access_pointer(gp); |
| 20 if (!p) { |
| 21 spin_unlock(&gp_lock); |
| 22 return false; |
| 23 } |
| 24 rcu_assign_pointer(gp, NULL); |
| 25 call_rcu(&p->rh, remove_gp_cb); |
| 26 spin_unlock(&gp_lock); |
| 27 return true; |
| 28 } |
| |
| A definition of ``struct foo`` is finally needed, and appears on |
| lines 1-5. The function remove_gp_cb() is passed to call_rcu() |
| on line 25, and will be invoked after the end of a subsequent grace |
| period. This gets the same effect as remove_gp_synchronous(), but |
| without forcing the updater to wait for a grace period to elapse. The |
| call_rcu() function may be used in a number of situations where |
| neither synchronize_rcu() nor synchronize_rcu_expedited() would |
| be legal, including within preempt-disable code, local_bh_disable() |
| code, interrupt-disable code, and interrupt handlers. However, even |
| call_rcu() is illegal within NMI handlers and from idle and offline |
| CPUs. The callback function (remove_gp_cb() in this case) will be |
| executed within softirq (software interrupt) environment within the |
| Linux kernel, either within a real softirq handler or under the |
| protection of local_bh_disable(). In both the Linux kernel and in |
| userspace, it is bad practice to write an RCU callback function that |
| takes too long. Long-running operations should be relegated to separate |
| threads or (in the Linux kernel) workqueues. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Why does line 19 use rcu_access_pointer()? After all, | |
| | call_rcu() on line 25 stores into the structure, which would | |
| | interact badly with concurrent insertions. Doesn't this mean that | |
| | rcu_dereference() is required? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | Presumably the ``->gp_lock`` acquired on line 18 excludes any | |
| | changes, including any insertions that rcu_dereference() would | |
| | protect against. Therefore, any insertions will be delayed until | |
| | after ``->gp_lock`` is released on line 25, which in turn means that | |
| | rcu_access_pointer() suffices. | |
| +-----------------------------------------------------------------------+ |
| |
| However, all that remove_gp_cb() is doing is invoking kfree() on |
| the data element. This is a common idiom, and is supported by |
| kfree_rcu(), which allows “fire and forget” operation as shown |
| below: |
| |
| :: |
| |
| 1 struct foo { |
| 2 int a; |
| 3 int b; |
| 4 struct rcu_head rh; |
| 5 }; |
| 6 |
| 7 bool remove_gp_faf(void) |
| 8 { |
| 9 struct foo *p; |
| 10 |
| 11 spin_lock(&gp_lock); |
| 12 p = rcu_dereference(gp); |
| 13 if (!p) { |
| 14 spin_unlock(&gp_lock); |
| 15 return false; |
| 16 } |
| 17 rcu_assign_pointer(gp, NULL); |
| 18 kfree_rcu(p, rh); |
| 19 spin_unlock(&gp_lock); |
| 20 return true; |
| 21 } |
| |
| Note that remove_gp_faf() simply invokes kfree_rcu() and |
| proceeds, without any need to pay any further attention to the |
| subsequent grace period and kfree(). It is permissible to invoke |
| kfree_rcu() from the same environments as for call_rcu(). |
| Interestingly enough, DYNIX/ptx had the equivalents of call_rcu() |
| and kfree_rcu(), but not synchronize_rcu(). This was due to the |
| fact that RCU was not heavily used within DYNIX/ptx, so the very few |
| places that needed something like synchronize_rcu() simply |
| open-coded it. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Earlier it was claimed that call_rcu() and kfree_rcu() | |
| | allowed updaters to avoid being blocked by readers. But how can that | |
| | be correct, given that the invocation of the callback and the freeing | |
| | of the memory (respectively) must still wait for a grace period to | |
| | elapse? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | We could define things this way, but keep in mind that this sort of | |
| | definition would say that updates in garbage-collected languages | |
| | cannot complete until the next time the garbage collector runs, which | |
| | does not seem at all reasonable. The key point is that in most cases, | |
| | an updater using either call_rcu() or kfree_rcu() can proceed | |
| | to the next update as soon as it has invoked call_rcu() or | |
| | kfree_rcu(), without having to wait for a subsequent grace | |
| | period. | |
| +-----------------------------------------------------------------------+ |
| |
| But what if the updater must wait for the completion of code to be |
| executed after the end of the grace period, but has other tasks that can |
| be carried out in the meantime? The polling-style |
| get_state_synchronize_rcu() and cond_synchronize_rcu() functions |
| may be used for this purpose, as shown below: |
| |
| :: |
| |
| 1 bool remove_gp_poll(void) |
| 2 { |
| 3 struct foo *p; |
| 4 unsigned long s; |
| 5 |
| 6 spin_lock(&gp_lock); |
| 7 p = rcu_access_pointer(gp); |
| 8 if (!p) { |
| 9 spin_unlock(&gp_lock); |
| 10 return false; |
| 11 } |
| 12 rcu_assign_pointer(gp, NULL); |
| 13 spin_unlock(&gp_lock); |
| 14 s = get_state_synchronize_rcu(); |
| 15 do_something_while_waiting(); |
| 16 cond_synchronize_rcu(s); |
| 17 kfree(p); |
| 18 return true; |
| 19 } |
| |
| On line 14, get_state_synchronize_rcu() obtains a “cookie” from RCU, |
| then line 15 carries out other tasks, and finally, line 16 returns |
| immediately if a grace period has elapsed in the meantime, but otherwise |
| waits as required. The need for ``get_state_synchronize_rcu`` and |
| cond_synchronize_rcu() has appeared quite recently, so it is too |
| early to tell whether they will stand the test of time. |
| |
| RCU thus provides a range of tools to allow updaters to strike the |
| required tradeoff between latency, flexibility and CPU overhead. |
| |
| Forward Progress |
| ~~~~~~~~~~~~~~~~ |
| |
| In theory, delaying grace-period completion and callback invocation is |
| harmless. In practice, not only are memory sizes finite but also |
| callbacks sometimes do wakeups, and sufficiently deferred wakeups can be |
| difficult to distinguish from system hangs. Therefore, RCU must provide |
| a number of mechanisms to promote forward progress. |
| |
| These mechanisms are not foolproof, nor can they be. For one simple |
| example, an infinite loop in an RCU read-side critical section must by |
| definition prevent later grace periods from ever completing. For a more |
| involved example, consider a 64-CPU system built with |
| ``CONFIG_RCU_NOCB_CPU=y`` and booted with ``rcu_nocbs=1-63``, where |
| CPUs 1 through 63 spin in tight loops that invoke call_rcu(). Even |
| if these tight loops also contain calls to cond_resched() (thus |
| allowing grace periods to complete), CPU 0 simply will not be able to |
| invoke callbacks as fast as the other 63 CPUs can register them, at |
| least not until the system runs out of memory. In both of these |
| examples, the Spiderman principle applies: With great power comes great |
| responsibility. However, short of this level of abuse, RCU is required |
| to ensure timely completion of grace periods and timely invocation of |
| callbacks. |
| |
| RCU takes the following steps to encourage timely completion of grace |
| periods: |
| |
| #. If a grace period fails to complete within 100 milliseconds, RCU |
| causes future invocations of cond_resched() on the holdout CPUs |
| to provide an RCU quiescent state. RCU also causes those CPUs' |
| need_resched() invocations to return ``true``, but only after the |
| corresponding CPU's next scheduling-clock. |
| #. CPUs mentioned in the ``nohz_full`` kernel boot parameter can run |
| indefinitely in the kernel without scheduling-clock interrupts, which |
| defeats the above need_resched() strategem. RCU will therefore |
| invoke resched_cpu() on any ``nohz_full`` CPUs still holding out |
| after 109 milliseconds. |
| #. In kernels built with ``CONFIG_RCU_BOOST=y``, if a given task that |
| has been preempted within an RCU read-side critical section is |
| holding out for more than 500 milliseconds, RCU will resort to |
| priority boosting. |
| #. If a CPU is still holding out 10 seconds into the grace period, RCU |
| will invoke resched_cpu() on it regardless of its ``nohz_full`` |
| state. |
| |
| The above values are defaults for systems running with ``HZ=1000``. They |
| will vary as the value of ``HZ`` varies, and can also be changed using |
| the relevant Kconfig options and kernel boot parameters. RCU currently |
| does not do much sanity checking of these parameters, so please use |
| caution when changing them. Note that these forward-progress measures |
| are provided only for RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks |
| RCU`_. |
| |
| RCU takes the following steps in call_rcu() to encourage timely |
| invocation of callbacks when any given non-\ ``rcu_nocbs`` CPU has |
| 10,000 callbacks, or has 10,000 more callbacks than it had the last time |
| encouragement was provided: |
| |
| #. Starts a grace period, if one is not already in progress. |
| #. Forces immediate checking for quiescent states, rather than waiting |
| for three milliseconds to have elapsed since the beginning of the |
| grace period. |
| #. Immediately tags the CPU's callbacks with their grace period |
| completion numbers, rather than waiting for the ``RCU_SOFTIRQ`` |
| handler to get around to it. |
| #. Lifts callback-execution batch limits, which speeds up callback |
| invocation at the expense of degrading realtime response. |
| |
| Again, these are default values when running at ``HZ=1000``, and can be |
| overridden. Again, these forward-progress measures are provided only for |
| RCU, not for `SRCU <Sleepable RCU_>`__ or `Tasks |
| RCU`_. Even for RCU, callback-invocation forward |
| progress for ``rcu_nocbs`` CPUs is much less well-developed, in part |
| because workloads benefiting from ``rcu_nocbs`` CPUs tend to invoke |
| call_rcu() relatively infrequently. If workloads emerge that need |
| both ``rcu_nocbs`` CPUs and high call_rcu() invocation rates, then |
| additional forward-progress work will be required. |
| |
| Composability |
| ~~~~~~~~~~~~~ |
| |
| Composability has received much attention in recent years, perhaps in |
| part due to the collision of multicore hardware with object-oriented |
| techniques designed in single-threaded environments for single-threaded |
| use. And in theory, RCU read-side critical sections may be composed, and |
| in fact may be nested arbitrarily deeply. In practice, as with all |
| real-world implementations of composable constructs, there are |
| limitations. |
| |
| Implementations of RCU for which rcu_read_lock() and |
| rcu_read_unlock() generate no code, such as Linux-kernel RCU when |
| ``CONFIG_PREEMPTION=n``, can be nested arbitrarily deeply. After all, there |
| is no overhead. Except that if all these instances of |
| rcu_read_lock() and rcu_read_unlock() are visible to the |
| compiler, compilation will eventually fail due to exhausting memory, |
| mass storage, or user patience, whichever comes first. If the nesting is |
| not visible to the compiler, as is the case with mutually recursive |
| functions each in its own translation unit, stack overflow will result. |
| If the nesting takes the form of loops, perhaps in the guise of tail |
| recursion, either the control variable will overflow or (in the Linux |
| kernel) you will get an RCU CPU stall warning. Nevertheless, this class |
| of RCU implementations is one of the most composable constructs in |
| existence. |
| |
| RCU implementations that explicitly track nesting depth are limited by |
| the nesting-depth counter. For example, the Linux kernel's preemptible |
| RCU limits nesting to ``INT_MAX``. This should suffice for almost all |
| practical purposes. That said, a consecutive pair of RCU read-side |
| critical sections between which there is an operation that waits for a |
| grace period cannot be enclosed in another RCU read-side critical |
| section. This is because it is not legal to wait for a grace period |
| within an RCU read-side critical section: To do so would result either |
| in deadlock or in RCU implicitly splitting the enclosing RCU read-side |
| critical section, neither of which is conducive to a long-lived and |
| prosperous kernel. |
| |
| It is worth noting that RCU is not alone in limiting composability. For |
| example, many transactional-memory implementations prohibit composing a |
| pair of transactions separated by an irrevocable operation (for example, |
| a network receive operation). For another example, lock-based critical |
| sections can be composed surprisingly freely, but only if deadlock is |
| avoided. |
| |
| In short, although RCU read-side critical sections are highly |
| composable, care is required in some situations, just as is the case for |
| any other composable synchronization mechanism. |
| |
| Corner Cases |
| ~~~~~~~~~~~~ |
| |
| A given RCU workload might have an endless and intense stream of RCU |
| read-side critical sections, perhaps even so intense that there was |
| never a point in time during which there was not at least one RCU |
| read-side critical section in flight. RCU cannot allow this situation to |
| block grace periods: As long as all the RCU read-side critical sections |
| are finite, grace periods must also be finite. |
| |
| That said, preemptible RCU implementations could potentially result in |
| RCU read-side critical sections being preempted for long durations, |
| which has the effect of creating a long-duration RCU read-side critical |
| section. This situation can arise only in heavily loaded systems, but |
| systems using real-time priorities are of course more vulnerable. |
| Therefore, RCU priority boosting is provided to help deal with this |
| case. That said, the exact requirements on RCU priority boosting will |
| likely evolve as more experience accumulates. |
| |
| Other workloads might have very high update rates. Although one can |
| argue that such workloads should instead use something other than RCU, |
| the fact remains that RCU must handle such workloads gracefully. This |
| requirement is another factor driving batching of grace periods, but it |
| is also the driving force behind the checks for large numbers of queued |
| RCU callbacks in the call_rcu() code path. Finally, high update |
| rates should not delay RCU read-side critical sections, although some |
| small read-side delays can occur when using |
| synchronize_rcu_expedited(), courtesy of this function's use of |
| smp_call_function_single(). |
| |
| Although all three of these corner cases were understood in the early |
| 1990s, a simple user-level test consisting of ``close(open(path))`` in a |
| tight loop in the early 2000s suddenly provided a much deeper |
| appreciation of the high-update-rate corner case. This test also |
| motivated addition of some RCU code to react to high update rates, for |
| example, if a given CPU finds itself with more than 10,000 RCU callbacks |
| queued, it will cause RCU to take evasive action by more aggressively |
| starting grace periods and more aggressively forcing completion of |
| grace-period processing. This evasive action causes the grace period to |
| complete more quickly, but at the cost of restricting RCU's batching |
| optimizations, thus increasing the CPU overhead incurred by that grace |
| period. |
| |
| Software-Engineering Requirements |
| --------------------------------- |
| |
| Between Murphy's Law and “To err is human”, it is necessary to guard |
| against mishaps and misuse: |
| |
| #. It is all too easy to forget to use rcu_read_lock() everywhere |
| that it is needed, so kernels built with ``CONFIG_PROVE_RCU=y`` will |
| splat if rcu_dereference() is used outside of an RCU read-side |
| critical section. Update-side code can use |
| rcu_dereference_protected(), which takes a `lockdep |
| expression <https://lwn.net/Articles/371986/>`__ to indicate what is |
| providing the protection. If the indicated protection is not |
| provided, a lockdep splat is emitted. |
| Code shared between readers and updaters can use |
| rcu_dereference_check(), which also takes a lockdep expression, |
| and emits a lockdep splat if neither rcu_read_lock() nor the |
| indicated protection is in place. In addition, |
| rcu_dereference_raw() is used in those (hopefully rare) cases |
| where the required protection cannot be easily described. Finally, |
| rcu_read_lock_held() is provided to allow a function to verify |
| that it has been invoked within an RCU read-side critical section. I |
| was made aware of this set of requirements shortly after Thomas |
| Gleixner audited a number of RCU uses. |
| #. A given function might wish to check for RCU-related preconditions |
| upon entry, before using any other RCU API. The |
| rcu_lockdep_assert() does this job, asserting the expression in |
| kernels having lockdep enabled and doing nothing otherwise. |
| #. It is also easy to forget to use rcu_assign_pointer() and |
| rcu_dereference(), perhaps (incorrectly) substituting a simple |
| assignment. To catch this sort of error, a given RCU-protected |
| pointer may be tagged with ``__rcu``, after which sparse will |
| complain about simple-assignment accesses to that pointer. Arnd |
| Bergmann made me aware of this requirement, and also supplied the |
| needed `patch series <https://lwn.net/Articles/376011/>`__. |
| #. Kernels built with ``CONFIG_DEBUG_OBJECTS_RCU_HEAD=y`` will splat if |
| a data element is passed to call_rcu() twice in a row, without a |
| grace period in between. (This error is similar to a double free.) |
| The corresponding ``rcu_head`` structures that are dynamically |
| allocated are automatically tracked, but ``rcu_head`` structures |
| allocated on the stack must be initialized with |
| init_rcu_head_on_stack() and cleaned up with |
| destroy_rcu_head_on_stack(). Similarly, statically allocated |
| non-stack ``rcu_head`` structures must be initialized with |
| init_rcu_head() and cleaned up with destroy_rcu_head(). |
| Mathieu Desnoyers made me aware of this requirement, and also |
| supplied the needed |
| `patch <https://lore.kernel.org/r/20100319013024.GA28456@Krystal>`__. |
| #. An infinite loop in an RCU read-side critical section will eventually |
| trigger an RCU CPU stall warning splat, with the duration of |
| “eventually” being controlled by the ``RCU_CPU_STALL_TIMEOUT`` |
| ``Kconfig`` option, or, alternatively, by the |
| ``rcupdate.rcu_cpu_stall_timeout`` boot/sysfs parameter. However, RCU |
| is not obligated to produce this splat unless there is a grace period |
| waiting on that particular RCU read-side critical section. |
| |
| Some extreme workloads might intentionally delay RCU grace periods, |
| and systems running those workloads can be booted with |
| ``rcupdate.rcu_cpu_stall_suppress`` to suppress the splats. This |
| kernel parameter may also be set via ``sysfs``. Furthermore, RCU CPU |
| stall warnings are counter-productive during sysrq dumps and during |
| panics. RCU therefore supplies the rcu_sysrq_start() and |
| rcu_sysrq_end() API members to be called before and after long |
| sysrq dumps. RCU also supplies the rcu_panic() notifier that is |
| automatically invoked at the beginning of a panic to suppress further |
| RCU CPU stall warnings. |
| |
| This requirement made itself known in the early 1990s, pretty much |
| the first time that it was necessary to debug a CPU stall. That said, |
| the initial implementation in DYNIX/ptx was quite generic in |
| comparison with that of Linux. |
| |
| #. Although it would be very good to detect pointers leaking out of RCU |
| read-side critical sections, there is currently no good way of doing |
| this. One complication is the need to distinguish between pointers |
| leaking and pointers that have been handed off from RCU to some other |
| synchronization mechanism, for example, reference counting. |
| #. In kernels built with ``CONFIG_RCU_TRACE=y``, RCU-related information |
| is provided via event tracing. |
| #. Open-coded use of rcu_assign_pointer() and rcu_dereference() |
| to create typical linked data structures can be surprisingly |
| error-prone. Therefore, RCU-protected `linked |
| lists <https://lwn.net/Articles/609973/#RCU%20List%20APIs>`__ and, |
| more recently, RCU-protected `hash |
| tables <https://lwn.net/Articles/612100/>`__ are available. Many |
| other special-purpose RCU-protected data structures are available in |
| the Linux kernel and the userspace RCU library. |
| #. Some linked structures are created at compile time, but still require |
| ``__rcu`` checking. The RCU_POINTER_INITIALIZER() macro serves |
| this purpose. |
| #. It is not necessary to use rcu_assign_pointer() when creating |
| linked structures that are to be published via a single external |
| pointer. The RCU_INIT_POINTER() macro is provided for this task. |
| |
| This not a hard-and-fast list: RCU's diagnostic capabilities will |
| continue to be guided by the number and type of usage bugs found in |
| real-world RCU usage. |
| |
| Linux Kernel Complications |
| -------------------------- |
| |
| The Linux kernel provides an interesting environment for all kinds of |
| software, including RCU. Some of the relevant points of interest are as |
| follows: |
| |
| #. `Configuration`_ |
| #. `Firmware Interface`_ |
| #. `Early Boot`_ |
| #. `Interrupts and NMIs`_ |
| #. `Loadable Modules`_ |
| #. `Hotplug CPU`_ |
| #. `Scheduler and RCU`_ |
| #. `Tracing and RCU`_ |
| #. `Accesses to User Memory and RCU`_ |
| #. `Energy Efficiency`_ |
| #. `Scheduling-Clock Interrupts and RCU`_ |
| #. `Memory Efficiency`_ |
| #. `Performance, Scalability, Response Time, and Reliability`_ |
| |
| This list is probably incomplete, but it does give a feel for the most |
| notable Linux-kernel complications. Each of the following sections |
| covers one of the above topics. |
| |
| Configuration |
| ~~~~~~~~~~~~~ |
| |
| RCU's goal is automatic configuration, so that almost nobody needs to |
| worry about RCU's ``Kconfig`` options. And for almost all users, RCU |
| does in fact work well “out of the box.” |
| |
| However, there are specialized use cases that are handled by kernel boot |
| parameters and ``Kconfig`` options. Unfortunately, the ``Kconfig`` |
| system will explicitly ask users about new ``Kconfig`` options, which |
| requires almost all of them be hidden behind a ``CONFIG_RCU_EXPERT`` |
| ``Kconfig`` option. |
| |
| This all should be quite obvious, but the fact remains that Linus |
| Torvalds recently had to |
| `remind <https://lore.kernel.org/r/CA+55aFy4wcCwaL4okTs8wXhGZ5h-ibecy_Meg9C4MNQrUnwMcg@mail.gmail.com>`__ |
| me of this requirement. |
| |
| Firmware Interface |
| ~~~~~~~~~~~~~~~~~~ |
| |
| In many cases, kernel obtains information about the system from the |
| firmware, and sometimes things are lost in translation. Or the |
| translation is accurate, but the original message is bogus. |
| |
| For example, some systems' firmware overreports the number of CPUs, |
| sometimes by a large factor. If RCU naively believed the firmware, as it |
| used to do, it would create too many per-CPU kthreads. Although the |
| resulting system will still run correctly, the extra kthreads needlessly |
| consume memory and can cause confusion when they show up in ``ps`` |
| listings. |
| |
| RCU must therefore wait for a given CPU to actually come online before |
| it can allow itself to believe that the CPU actually exists. The |
| resulting “ghost CPUs” (which are never going to come online) cause a |
| number of `interesting |
| complications <https://paulmck.livejournal.com/37494.html>`__. |
| |
| Early Boot |
| ~~~~~~~~~~ |
| |
| The Linux kernel's boot sequence is an interesting process, and RCU is |
| used early, even before rcu_init() is invoked. In fact, a number of |
| RCU's primitives can be used as soon as the initial task's |
| ``task_struct`` is available and the boot CPU's per-CPU variables are |
| set up. The read-side primitives (rcu_read_lock(), |
| rcu_read_unlock(), rcu_dereference(), and |
| rcu_access_pointer()) will operate normally very early on, as will |
| rcu_assign_pointer(). |
| |
| Although call_rcu() may be invoked at any time during boot, |
| callbacks are not guaranteed to be invoked until after all of RCU's |
| kthreads have been spawned, which occurs at early_initcall() time. |
| This delay in callback invocation is due to the fact that RCU does not |
| invoke callbacks until it is fully initialized, and this full |
| initialization cannot occur until after the scheduler has initialized |
| itself to the point where RCU can spawn and run its kthreads. In theory, |
| it would be possible to invoke callbacks earlier, however, this is not a |
| panacea because there would be severe restrictions on what operations |
| those callbacks could invoke. |
| |
| Perhaps surprisingly, synchronize_rcu() and |
| synchronize_rcu_expedited(), will operate normally during very early |
| boot, the reason being that there is only one CPU and preemption is |
| disabled. This means that the call synchronize_rcu() (or friends) |
| itself is a quiescent state and thus a grace period, so the early-boot |
| implementation can be a no-op. |
| |
| However, once the scheduler has spawned its first kthread, this early |
| boot trick fails for synchronize_rcu() (as well as for |
| synchronize_rcu_expedited()) in ``CONFIG_PREEMPTION=y`` kernels. The |
| reason is that an RCU read-side critical section might be preempted, |
| which means that a subsequent synchronize_rcu() really does have to |
| wait for something, as opposed to simply returning immediately. |
| Unfortunately, synchronize_rcu() can't do this until all of its |
| kthreads are spawned, which doesn't happen until some time during |
| early_initcalls() time. But this is no excuse: RCU is nevertheless |
| required to correctly handle synchronous grace periods during this time |
| period. Once all of its kthreads are up and running, RCU starts running |
| normally. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | How can RCU possibly handle grace periods before all of its kthreads | |
| | have been spawned??? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | Very carefully! | |
| | During the “dead zone” between the time that the scheduler spawns the | |
| | first task and the time that all of RCU's kthreads have been spawned, | |
| | all synchronous grace periods are handled by the expedited | |
| | grace-period mechanism. At runtime, this expedited mechanism relies | |
| | on workqueues, but during the dead zone the requesting task itself | |
| | drives the desired expedited grace period. Because dead-zone | |
| | execution takes place within task context, everything works. Once the | |
| | dead zone ends, expedited grace periods go back to using workqueues, | |
| | as is required to avoid problems that would otherwise occur when a | |
| | user task received a POSIX signal while driving an expedited grace | |
| | period. | |
| | | |
| | And yes, this does mean that it is unhelpful to send POSIX signals to | |
| | random tasks between the time that the scheduler spawns its first | |
| | kthread and the time that RCU's kthreads have all been spawned. If | |
| | there ever turns out to be a good reason for sending POSIX signals | |
| | during that time, appropriate adjustments will be made. (If it turns | |
| | out that POSIX signals are sent during this time for no good reason, | |
| | other adjustments will be made, appropriate or otherwise.) | |
| +-----------------------------------------------------------------------+ |
| |
| I learned of these boot-time requirements as a result of a series of |
| system hangs. |
| |
| Interrupts and NMIs |
| ~~~~~~~~~~~~~~~~~~~ |
| |
| The Linux kernel has interrupts, and RCU read-side critical sections are |
| legal within interrupt handlers and within interrupt-disabled regions of |
| code, as are invocations of call_rcu(). |
| |
| Some Linux-kernel architectures can enter an interrupt handler from |
| non-idle process context, and then just never leave it, instead |
| stealthily transitioning back to process context. This trick is |
| sometimes used to invoke system calls from inside the kernel. These |
| “half-interrupts” mean that RCU has to be very careful about how it |
| counts interrupt nesting levels. I learned of this requirement the hard |
| way during a rewrite of RCU's dyntick-idle code. |
| |
| The Linux kernel has non-maskable interrupts (NMIs), and RCU read-side |
| critical sections are legal within NMI handlers. Thankfully, RCU |
| update-side primitives, including call_rcu(), are prohibited within |
| NMI handlers. |
| |
| The name notwithstanding, some Linux-kernel architectures can have |
| nested NMIs, which RCU must handle correctly. Andy Lutomirski `surprised |
| me <https://lore.kernel.org/r/CALCETrXLq1y7e_dKFPgou-FKHB6Pu-r8+t-6Ds+8=va7anBWDA@mail.gmail.com>`__ |
| with this requirement; he also kindly surprised me with `an |
| algorithm <https://lore.kernel.org/r/CALCETrXSY9JpW3uE6H8WYk81sg56qasA2aqmjMPsq5dOtzso=g@mail.gmail.com>`__ |
| that meets this requirement. |
| |
| Furthermore, NMI handlers can be interrupted by what appear to RCU to be |
| normal interrupts. One way that this can happen is for code that |
| directly invokes ct_irq_enter() and ct_irq_exit() to be called |
| from an NMI handler. This astonishing fact of life prompted the current |
| code structure, which has ct_irq_enter() invoking |
| ct_nmi_enter() and ct_irq_exit() invoking ct_nmi_exit(). |
| And yes, I also learned of this requirement the hard way. |
| |
| Loadable Modules |
| ~~~~~~~~~~~~~~~~ |
| |
| The Linux kernel has loadable modules, and these modules can also be |
| unloaded. After a given module has been unloaded, any attempt to call |
| one of its functions results in a segmentation fault. The module-unload |
| functions must therefore cancel any delayed calls to loadable-module |
| functions, for example, any outstanding mod_timer() must be dealt |
| with via timer_shutdown_sync() or similar. |
| |
| Unfortunately, there is no way to cancel an RCU callback; once you |
| invoke call_rcu(), the callback function is eventually going to be |
| invoked, unless the system goes down first. Because it is normally |
| considered socially irresponsible to crash the system in response to a |
| module unload request, we need some other way to deal with in-flight RCU |
| callbacks. |
| |
| RCU therefore provides rcu_barrier(), which waits until all |
| in-flight RCU callbacks have been invoked. If a module uses |
| call_rcu(), its exit function should therefore prevent any future |
| invocation of call_rcu(), then invoke rcu_barrier(). In theory, |
| the underlying module-unload code could invoke rcu_barrier() |
| unconditionally, but in practice this would incur unacceptable |
| latencies. |
| |
| Nikita Danilov noted this requirement for an analogous |
| filesystem-unmount situation, and Dipankar Sarma incorporated |
| rcu_barrier() into RCU. The need for rcu_barrier() for module |
| unloading became apparent later. |
| |
| .. important:: |
| |
| The rcu_barrier() function is not, repeat, |
| *not*, obligated to wait for a grace period. It is instead only required |
| to wait for RCU callbacks that have already been posted. Therefore, if |
| there are no RCU callbacks posted anywhere in the system, |
| rcu_barrier() is within its rights to return immediately. Even if |
| there are callbacks posted, rcu_barrier() does not necessarily need |
| to wait for a grace period. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Wait a minute! Each RCU callbacks must wait for a grace period to | |
| | complete, and rcu_barrier() must wait for each pre-existing | |
| | callback to be invoked. Doesn't rcu_barrier() therefore need to | |
| | wait for a full grace period if there is even one callback posted | |
| | anywhere in the system? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | Absolutely not!!! | |
| | Yes, each RCU callbacks must wait for a grace period to complete, but | |
| | it might well be partly (or even completely) finished waiting by the | |
| | time rcu_barrier() is invoked. In that case, rcu_barrier() | |
| | need only wait for the remaining portion of the grace period to | |
| | elapse. So even if there are quite a few callbacks posted, | |
| | rcu_barrier() might well return quite quickly. | |
| | | |
| | So if you need to wait for a grace period as well as for all | |
| | pre-existing callbacks, you will need to invoke both | |
| | synchronize_rcu() and rcu_barrier(). If latency is a concern, | |
| | you can always use workqueues to invoke them concurrently. | |
| +-----------------------------------------------------------------------+ |
| |
| Hotplug CPU |
| ~~~~~~~~~~~ |
| |
| The Linux kernel supports CPU hotplug, which means that CPUs can come |
| and go. It is of course illegal to use any RCU API member from an |
| offline CPU, with the exception of `SRCU <Sleepable RCU_>`__ read-side |
| critical sections. This requirement was present from day one in |
| DYNIX/ptx, but on the other hand, the Linux kernel's CPU-hotplug |
| implementation is “interesting.” |
| |
| The Linux-kernel CPU-hotplug implementation has notifiers that are used |
| to allow the various kernel subsystems (including RCU) to respond |
| appropriately to a given CPU-hotplug operation. Most RCU operations may |
| be invoked from CPU-hotplug notifiers, including even synchronous |
| grace-period operations such as (synchronize_rcu() and |
| synchronize_rcu_expedited()). However, these synchronous operations |
| do block and therefore cannot be invoked from notifiers that execute via |
| stop_machine(), specifically those between the ``CPUHP_AP_OFFLINE`` |
| and ``CPUHP_AP_ONLINE`` states. |
| |
| In addition, all-callback-wait operations such as rcu_barrier() may |
| not be invoked from any CPU-hotplug notifier. This restriction is due |
| to the fact that there are phases of CPU-hotplug operations where the |
| outgoing CPU's callbacks will not be invoked until after the CPU-hotplug |
| operation ends, which could also result in deadlock. Furthermore, |
| rcu_barrier() blocks CPU-hotplug operations during its execution, |
| which results in another type of deadlock when invoked from a CPU-hotplug |
| notifier. |
| |
| Finally, RCU must avoid deadlocks due to interaction between hotplug, |
| timers and grace period processing. It does so by maintaining its own set |
| of books that duplicate the centrally maintained ``cpu_online_mask``, |
| and also by reporting quiescent states explicitly when a CPU goes |
| offline. This explicit reporting of quiescent states avoids any need |
| for the force-quiescent-state loop (FQS) to report quiescent states for |
| offline CPUs. However, as a debugging measure, the FQS loop does splat |
| if offline CPUs block an RCU grace period for too long. |
| |
| An offline CPU's quiescent state will be reported either: |
| |
| 1. As the CPU goes offline using RCU's hotplug notifier (rcu_report_dead()). |
| 2. When grace period initialization (rcu_gp_init()) detects a |
| race either with CPU offlining or with a task unblocking on a leaf |
| ``rcu_node`` structure whose CPUs are all offline. |
| |
| The CPU-online path (rcu_cpu_starting()) should never need to report |
| a quiescent state for an offline CPU. However, as a debugging measure, |
| it does emit a warning if a quiescent state was not already reported |
| for that CPU. |
| |
| During the checking/modification of RCU's hotplug bookkeeping, the |
| corresponding CPU's leaf node lock is held. This avoids race conditions |
| between RCU's hotplug notifier hooks, the grace period initialization |
| code, and the FQS loop, all of which refer to or modify this bookkeeping. |
| |
| Scheduler and RCU |
| ~~~~~~~~~~~~~~~~~ |
| |
| RCU makes use of kthreads, and it is necessary to avoid excessive CPU-time |
| accumulation by these kthreads. This requirement was no surprise, but |
| RCU's violation of it when running context-switch-heavy workloads when |
| built with ``CONFIG_NO_HZ_FULL=y`` `did come as a surprise |
| [PDF] <http://www.rdrop.com/users/paulmck/scalability/paper/BareMetal.2015.01.15b.pdf>`__. |
| RCU has made good progress towards meeting this requirement, even for |
| context-switch-heavy ``CONFIG_NO_HZ_FULL=y`` workloads, but there is |
| room for further improvement. |
| |
| There is no longer any prohibition against holding any of |
| scheduler's runqueue or priority-inheritance spinlocks across an |
| rcu_read_unlock(), even if interrupts and preemption were enabled |
| somewhere within the corresponding RCU read-side critical section. |
| Therefore, it is now perfectly legal to execute rcu_read_lock() |
| with preemption enabled, acquire one of the scheduler locks, and hold |
| that lock across the matching rcu_read_unlock(). |
| |
| Similarly, the RCU flavor consolidation has removed the need for negative |
| nesting. The fact that interrupt-disabled regions of code act as RCU |
| read-side critical sections implicitly avoids earlier issues that used |
| to result in destructive recursion via interrupt handler's use of RCU. |
| |
| Tracing and RCU |
| ~~~~~~~~~~~~~~~ |
| |
| It is possible to use tracing on RCU code, but tracing itself uses RCU. |
| For this reason, rcu_dereference_raw_check() is provided for use |
| by tracing, which avoids the destructive recursion that could otherwise |
| ensue. This API is also used by virtualization in some architectures, |
| where RCU readers execute in environments in which tracing cannot be |
| used. The tracing folks both located the requirement and provided the |
| needed fix, so this surprise requirement was relatively painless. |
| |
| Accesses to User Memory and RCU |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The kernel needs to access user-space memory, for example, to access data |
| referenced by system-call parameters. The get_user() macro does this job. |
| |
| However, user-space memory might well be paged out, which means that |
| get_user() might well page-fault and thus block while waiting for the |
| resulting I/O to complete. It would be a very bad thing for the compiler to |
| reorder a get_user() invocation into an RCU read-side critical section. |
| |
| For example, suppose that the source code looked like this: |
| |
| :: |
| |
| 1 rcu_read_lock(); |
| 2 p = rcu_dereference(gp); |
| 3 v = p->value; |
| 4 rcu_read_unlock(); |
| 5 get_user(user_v, user_p); |
| 6 do_something_with(v, user_v); |
| |
| The compiler must not be permitted to transform this source code into |
| the following: |
| |
| :: |
| |
| 1 rcu_read_lock(); |
| 2 p = rcu_dereference(gp); |
| 3 get_user(user_v, user_p); // BUG: POSSIBLE PAGE FAULT!!! |
| 4 v = p->value; |
| 5 rcu_read_unlock(); |
| 6 do_something_with(v, user_v); |
| |
| If the compiler did make this transformation in a ``CONFIG_PREEMPTION=n`` kernel |
| build, and if get_user() did page fault, the result would be a quiescent |
| state in the middle of an RCU read-side critical section. This misplaced |
| quiescent state could result in line 4 being a use-after-free access, |
| which could be bad for your kernel's actuarial statistics. Similar examples |
| can be constructed with the call to get_user() preceding the |
| rcu_read_lock(). |
| |
| Unfortunately, get_user() doesn't have any particular ordering properties, |
| and in some architectures the underlying ``asm`` isn't even marked |
| ``volatile``. And even if it was marked ``volatile``, the above access to |
| ``p->value`` is not volatile, so the compiler would not have any reason to keep |
| those two accesses in order. |
| |
| Therefore, the Linux-kernel definitions of rcu_read_lock() and |
| rcu_read_unlock() must act as compiler barriers, at least for outermost |
| instances of rcu_read_lock() and rcu_read_unlock() within a nested set |
| of RCU read-side critical sections. |
| |
| Energy Efficiency |
| ~~~~~~~~~~~~~~~~~ |
| |
| Interrupting idle CPUs is considered socially unacceptable, especially |
| by people with battery-powered embedded systems. RCU therefore conserves |
| energy by detecting which CPUs are idle, including tracking CPUs that |
| have been interrupted from idle. This is a large part of the |
| energy-efficiency requirement, so I learned of this via an irate phone |
| call. |
| |
| Because RCU avoids interrupting idle CPUs, it is illegal to execute an |
| RCU read-side critical section on an idle CPU. (Kernels built with |
| ``CONFIG_PROVE_RCU=y`` will splat if you try it.) |
| |
| It is similarly socially unacceptable to interrupt an ``nohz_full`` CPU |
| running in userspace. RCU must therefore track ``nohz_full`` userspace |
| execution. RCU must therefore be able to sample state at two points in |
| time, and be able to determine whether or not some other CPU spent any |
| time idle and/or executing in userspace. |
| |
| These energy-efficiency requirements have proven quite difficult to |
| understand and to meet, for example, there have been more than five |
| clean-sheet rewrites of RCU's energy-efficiency code, the last of which |
| was finally able to demonstrate `real energy savings running on real |
| hardware |
| [PDF] <http://www.rdrop.com/users/paulmck/realtime/paper/AMPenergy.2013.04.19a.pdf>`__. |
| As noted earlier, I learned of many of these requirements via angry |
| phone calls: Flaming me on the Linux-kernel mailing list was apparently |
| not sufficient to fully vent their ire at RCU's energy-efficiency bugs! |
| |
| Scheduling-Clock Interrupts and RCU |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The kernel transitions between in-kernel non-idle execution, userspace |
| execution, and the idle loop. Depending on kernel configuration, RCU |
| handles these states differently: |
| |
| +-----------------+------------------+------------------+-----------------+ |
| | ``HZ`` Kconfig | In-Kernel | Usermode | Idle | |
| +=================+==================+==================+=================+ |
| | ``HZ_PERIODIC`` | Can rely on | Can rely on | Can rely on | |
| | | scheduling-clock | scheduling-clock | RCU's | |
| | | interrupt. | interrupt and | dyntick-idle | |
| | | | its detection | detection. | |
| | | | of interrupt | | |
| | | | from usermode. | | |
| +-----------------+------------------+------------------+-----------------+ |
| | ``NO_HZ_IDLE`` | Can rely on | Can rely on | Can rely on | |
| | | scheduling-clock | scheduling-clock | RCU's | |
| | | interrupt. | interrupt and | dyntick-idle | |
| | | | its detection | detection. | |
| | | | of interrupt | | |
| | | | from usermode. | | |
| +-----------------+------------------+------------------+-----------------+ |
| | ``NO_HZ_FULL`` | Can only | Can rely on | Can rely on | |
| | | sometimes rely | RCU's | RCU's | |
| | | on | dyntick-idle | dyntick-idle | |
| | | scheduling-clock | detection. | detection. | |
| | | interrupt. In | | | |
| | | other cases, it | | | |
| | | is necessary to | | | |
| | | bound kernel | | | |
| | | execution times | | | |
| | | and/or use | | | |
| | | IPIs. | | | |
| +-----------------+------------------+------------------+-----------------+ |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | Why can't ``NO_HZ_FULL`` in-kernel execution rely on the | |
| | scheduling-clock interrupt, just like ``HZ_PERIODIC`` and | |
| | ``NO_HZ_IDLE`` do? | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | Because, as a performance optimization, ``NO_HZ_FULL`` does not | |
| | necessarily re-enable the scheduling-clock interrupt on entry to each | |
| | and every system call. | |
| +-----------------------------------------------------------------------+ |
| |
| However, RCU must be reliably informed as to whether any given CPU is |
| currently in the idle loop, and, for ``NO_HZ_FULL``, also whether that |
| CPU is executing in usermode, as discussed |
| `earlier <Energy Efficiency_>`__. It also requires that the |
| scheduling-clock interrupt be enabled when RCU needs it to be: |
| |
| #. If a CPU is either idle or executing in usermode, and RCU believes it |
| is non-idle, the scheduling-clock tick had better be running. |
| Otherwise, you will get RCU CPU stall warnings. Or at best, very long |
| (11-second) grace periods, with a pointless IPI waking the CPU from |
| time to time. |
| #. If a CPU is in a portion of the kernel that executes RCU read-side |
| critical sections, and RCU believes this CPU to be idle, you will get |
| random memory corruption. **DON'T DO THIS!!!** |
| This is one reason to test with lockdep, which will complain about |
| this sort of thing. |
| #. If a CPU is in a portion of the kernel that is absolutely positively |
| no-joking guaranteed to never execute any RCU read-side critical |
| sections, and RCU believes this CPU to be idle, no problem. This |
| sort of thing is used by some architectures for light-weight |
| exception handlers, which can then avoid the overhead of |
| ct_irq_enter() and ct_irq_exit() at exception entry and |
| exit, respectively. Some go further and avoid the entireties of |
| irq_enter() and irq_exit(). |
| Just make very sure you are running some of your tests with |
| ``CONFIG_PROVE_RCU=y``, just in case one of your code paths was in |
| fact joking about not doing RCU read-side critical sections. |
| #. If a CPU is executing in the kernel with the scheduling-clock |
| interrupt disabled and RCU believes this CPU to be non-idle, and if |
| the CPU goes idle (from an RCU perspective) every few jiffies, no |
| problem. It is usually OK for there to be the occasional gap between |
| idle periods of up to a second or so. |
| If the gap grows too long, you get RCU CPU stall warnings. |
| #. If a CPU is either idle or executing in usermode, and RCU believes it |
| to be idle, of course no problem. |
| #. If a CPU is executing in the kernel, the kernel code path is passing |
| through quiescent states at a reasonable frequency (preferably about |
| once per few jiffies, but the occasional excursion to a second or so |
| is usually OK) and the scheduling-clock interrupt is enabled, of |
| course no problem. |
| If the gap between a successive pair of quiescent states grows too |
| long, you get RCU CPU stall warnings. |
| |
| +-----------------------------------------------------------------------+ |
| | **Quick Quiz**: | |
| +-----------------------------------------------------------------------+ |
| | But what if my driver has a hardware interrupt handler that can run | |
| | for many seconds? I cannot invoke schedule() from an hardware | |
| | interrupt handler, after all! | |
| +-----------------------------------------------------------------------+ |
| | **Answer**: | |
| +-----------------------------------------------------------------------+ |
| | One approach is to do ``ct_irq_exit();ct_irq_enter();`` every so | |
| | often. But given that long-running interrupt handlers can cause other | |
| | problems, not least for response time, shouldn't you work to keep | |
| | your interrupt handler's runtime within reasonable bounds? | |
| +-----------------------------------------------------------------------+ |
| |
| But as long as RCU is properly informed of kernel state transitions |
| between in-kernel execution, usermode execution, and idle, and as long |
| as the scheduling-clock interrupt is enabled when RCU needs it to be, |
| you can rest assured that the bugs you encounter will be in some other |
| part of RCU or some other part of the kernel! |
| |
| Memory Efficiency |
| ~~~~~~~~~~~~~~~~~ |
| |
| Although small-memory non-realtime systems can simply use Tiny RCU, code |
| size is only one aspect of memory efficiency. Another aspect is the size |
| of the ``rcu_head`` structure used by call_rcu() and |
| kfree_rcu(). Although this structure contains nothing more than a |
| pair of pointers, it does appear in many RCU-protected data structures, |
| including some that are size critical. The ``page`` structure is a case |
| in point, as evidenced by the many occurrences of the ``union`` keyword |
| within that structure. |
| |
| This need for memory efficiency is one reason that RCU uses hand-crafted |
| singly linked lists to track the ``rcu_head`` structures that are |
| waiting for a grace period to elapse. It is also the reason why |
| ``rcu_head`` structures do not contain debug information, such as fields |
| tracking the file and line of the call_rcu() or kfree_rcu() that |
| posted them. Although this information might appear in debug-only kernel |
| builds at some point, in the meantime, the ``->func`` field will often |
| provide the needed debug information. |
| |
| However, in some cases, the need for memory efficiency leads to even |
| more extreme measures. Returning to the ``page`` structure, the |
| ``rcu_head`` field shares storage with a great many other structures |
| that are used at various points in the corresponding page's lifetime. In |
| order to correctly resolve certain `race |
| conditions <https://lore.kernel.org/r/1439976106-137226-1-git-send-email-kirill.shutemov@linux.intel.com>`__, |
| the Linux kernel's memory-management subsystem needs a particular bit to |
| remain zero during all phases of grace-period processing, and that bit |
| happens to map to the bottom bit of the ``rcu_head`` structure's |
| ``->next`` field. RCU makes this guarantee as long as call_rcu() is |
| used to post the callback, as opposed to kfree_rcu() or some future |
| “lazy” variant of call_rcu() that might one day be created for |
| energy-efficiency purposes. |
| |
| That said, there are limits. RCU requires that the ``rcu_head`` |
| structure be aligned to a two-byte boundary, and passing a misaligned |
| ``rcu_head`` structure to one of the call_rcu() family of functions |
| will result in a splat. It is therefore necessary to exercise caution |
| when packing structures containing fields of type ``rcu_head``. Why not |
| a four-byte or even eight-byte alignment requirement? Because the m68k |
| architecture provides only two-byte alignment, and thus acts as |
| alignment's least common denominator. |
| |
| The reason for reserving the bottom bit of pointers to ``rcu_head`` |
| structures is to leave the door open to “lazy” callbacks whose |
| invocations can safely be deferred. Deferring invocation could |
| potentially have energy-efficiency benefits, but only if the rate of |
| non-lazy callbacks decreases significantly for some important workload. |
| In the meantime, reserving the bottom bit keeps this option open in case |
| it one day becomes useful. |
| |
| Performance, Scalability, Response Time, and Reliability |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| Expanding on the `earlier |
| discussion <Performance and Scalability_>`__, RCU is used heavily by |
| hot code paths in performance-critical portions of the Linux kernel's |
| networking, security, virtualization, and scheduling code paths. RCU |
| must therefore use efficient implementations, especially in its |
| read-side primitives. To that end, it would be good if preemptible RCU's |
| implementation of rcu_read_lock() could be inlined, however, doing |
| this requires resolving ``#include`` issues with the ``task_struct`` |
| structure. |
| |
| The Linux kernel supports hardware configurations with up to 4096 CPUs, |
| which means that RCU must be extremely scalable. Algorithms that involve |
| frequent acquisitions of global locks or frequent atomic operations on |
| global variables simply cannot be tolerated within the RCU |
| implementation. RCU therefore makes heavy use of a combining tree based |
| on the ``rcu_node`` structure. RCU is required to tolerate all CPUs |
| continuously invoking any combination of RCU's runtime primitives with |
| minimal per-operation overhead. In fact, in many cases, increasing load |
| must *decrease* the per-operation overhead, witness the batching |
| optimizations for synchronize_rcu(), call_rcu(), |
| synchronize_rcu_expedited(), and rcu_barrier(). As a general |
| rule, RCU must cheerfully accept whatever the rest of the Linux kernel |
| decides to throw at it. |
| |
| The Linux kernel is used for real-time workloads, especially in |
| conjunction with the `-rt |
| patchset <https://wiki.linuxfoundation.org/realtime/>`__. The |
| real-time-latency response requirements are such that the traditional |
| approach of disabling preemption across RCU read-side critical sections |
| is inappropriate. Kernels built with ``CONFIG_PREEMPTION=y`` therefore use |
| an RCU implementation that allows RCU read-side critical sections to be |
| preempted. This requirement made its presence known after users made it |
| clear that an earlier `real-time |
| patch <https://lwn.net/Articles/107930/>`__ did not meet their needs, in |
| conjunction with some `RCU |
| issues <https://lore.kernel.org/r/20050318002026.GA2693@us.ibm.com>`__ |
| encountered by a very early version of the -rt patchset. |
| |
| In addition, RCU must make do with a sub-100-microsecond real-time |
| latency budget. In fact, on smaller systems with the -rt patchset, the |
| Linux kernel provides sub-20-microsecond real-time latencies for the |
| whole kernel, including RCU. RCU's scalability and latency must |
| therefore be sufficient for these sorts of configurations. To my |
| surprise, the sub-100-microsecond real-time latency budget `applies to |
| even the largest systems |
| [PDF] <http://www.rdrop.com/users/paulmck/realtime/paper/bigrt.2013.01.31a.LCA.pdf>`__, |
| up to and including systems with 4096 CPUs. This real-time requirement |
| motivated the grace-period kthread, which also simplified handling of a |
| number of race conditions. |
| |
| RCU must avoid degrading real-time response for CPU-bound threads, |
| whether executing in usermode (which is one use case for |
| ``CONFIG_NO_HZ_FULL=y``) or in the kernel. That said, CPU-bound loops in |
| the kernel must execute cond_resched() at least once per few tens of |
| milliseconds in order to avoid receiving an IPI from RCU. |
| |
| Finally, RCU's status as a synchronization primitive means that any RCU |
| failure can result in arbitrary memory corruption that can be extremely |
| difficult to debug. This means that RCU must be extremely reliable, |
| which in practice also means that RCU must have an aggressive |
| stress-test suite. This stress-test suite is called ``rcutorture``. |
| |
| Although the need for ``rcutorture`` was no surprise, the current |
| immense popularity of the Linux kernel is posing interesting—and perhaps |
| unprecedented—validation challenges. To see this, keep in mind that |
| there are well over one billion instances of the Linux kernel running |
| today, given Android smartphones, Linux-powered televisions, and |
| servers. This number can be expected to increase sharply with the advent |
| of the celebrated Internet of Things. |
| |
| Suppose that RCU contains a race condition that manifests on average |
| once per million years of runtime. This bug will be occurring about |
| three times per *day* across the installed base. RCU could simply hide |
| behind hardware error rates, given that no one should really expect |
| their smartphone to last for a million years. However, anyone taking too |
| much comfort from this thought should consider the fact that in most |
| jurisdictions, a successful multi-year test of a given mechanism, which |
| might include a Linux kernel, suffices for a number of types of |
| safety-critical certifications. In fact, rumor has it that the Linux |
| kernel is already being used in production for safety-critical |
| applications. I don't know about you, but I would feel quite bad if a |
| bug in RCU killed someone. Which might explain my recent focus on |
| validation and verification. |
| |
| Other RCU Flavors |
| ----------------- |
| |
| One of the more surprising things about RCU is that there are now no |
| fewer than five *flavors*, or API families. In addition, the primary |
| flavor that has been the sole focus up to this point has two different |
| implementations, non-preemptible and preemptible. The other four flavors |
| are listed below, with requirements for each described in a separate |
| section. |
| |
| #. `Bottom-Half Flavor (Historical)`_ |
| #. `Sched Flavor (Historical)`_ |
| #. `Sleepable RCU`_ |
| #. `Tasks RCU`_ |
| |
| Bottom-Half Flavor (Historical) |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The RCU-bh flavor of RCU has since been expressed in terms of the other |
| RCU flavors as part of a consolidation of the three flavors into a |
| single flavor. The read-side API remains, and continues to disable |
| softirq and to be accounted for by lockdep. Much of the material in this |
| section is therefore strictly historical in nature. |
| |
| The softirq-disable (AKA “bottom-half”, hence the “_bh” abbreviations) |
| flavor of RCU, or *RCU-bh*, was developed by Dipankar Sarma to provide a |
| flavor of RCU that could withstand the network-based denial-of-service |
| attacks researched by Robert Olsson. These attacks placed so much |
| networking load on the system that some of the CPUs never exited softirq |
| execution, which in turn prevented those CPUs from ever executing a |
| context switch, which, in the RCU implementation of that time, prevented |
| grace periods from ever ending. The result was an out-of-memory |
| condition and a system hang. |
| |
| The solution was the creation of RCU-bh, which does |
| local_bh_disable() across its read-side critical sections, and which |
| uses the transition from one type of softirq processing to another as a |
| quiescent state in addition to context switch, idle, user mode, and |
| offline. This means that RCU-bh grace periods can complete even when |
| some of the CPUs execute in softirq indefinitely, thus allowing |
| algorithms based on RCU-bh to withstand network-based denial-of-service |
| attacks. |
| |
| Because rcu_read_lock_bh() and rcu_read_unlock_bh() disable and |
| re-enable softirq handlers, any attempt to start a softirq handlers |
| during the RCU-bh read-side critical section will be deferred. In this |
| case, rcu_read_unlock_bh() will invoke softirq processing, which can |
| take considerable time. One can of course argue that this softirq |
| overhead should be associated with the code following the RCU-bh |
| read-side critical section rather than rcu_read_unlock_bh(), but the |
| fact is that most profiling tools cannot be expected to make this sort |
| of fine distinction. For example, suppose that a three-millisecond-long |
| RCU-bh read-side critical section executes during a time of heavy |
| networking load. There will very likely be an attempt to invoke at least |
| one softirq handler during that three milliseconds, but any such |
| invocation will be delayed until the time of the |
| rcu_read_unlock_bh(). This can of course make it appear at first |
| glance as if rcu_read_unlock_bh() was executing very slowly. |
| |
| The `RCU-bh |
| API <https://lwn.net/Articles/609973/#RCU%20Per-Flavor%20API%20Table>`__ |
| includes rcu_read_lock_bh(), rcu_read_unlock_bh(), rcu_dereference_bh(), |
| rcu_dereference_bh_check(), and rcu_read_lock_bh_held(). However, the |
| old RCU-bh update-side APIs are now gone, replaced by synchronize_rcu(), |
| synchronize_rcu_expedited(), call_rcu(), and rcu_barrier(). In addition, |
| anything that disables bottom halves also marks an RCU-bh read-side |
| critical section, including local_bh_disable() and local_bh_enable(), |
| local_irq_save() and local_irq_restore(), and so on. |
| |
| Sched Flavor (Historical) |
| ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| The RCU-sched flavor of RCU has since been expressed in terms of the |
| other RCU flavors as part of a consolidation of the three flavors into a |
| single flavor. The read-side API remains, and continues to disable |
| preemption and to be accounted for by lockdep. Much of the material in |
| this section is therefore strictly historical in nature. |
| |
| Before preemptible RCU, waiting for an RCU grace period had the side |
| effect of also waiting for all pre-existing interrupt and NMI handlers. |
| However, there are legitimate preemptible-RCU implementations that do |
| not have this property, given that any point in the code outside of an |
| RCU read-side critical section can be a quiescent state. Therefore, |
| *RCU-sched* was created, which follows “classic” RCU in that an |
| RCU-sched grace period waits for pre-existing interrupt and NMI |
| handlers. In kernels built with ``CONFIG_PREEMPTION=n``, the RCU and |
| RCU-sched APIs have identical implementations, while kernels built with |
| ``CONFIG_PREEMPTION=y`` provide a separate implementation for each. |
| |
| Note well that in ``CONFIG_PREEMPTION=y`` kernels, |
| rcu_read_lock_sched() and rcu_read_unlock_sched() disable and |
| re-enable preemption, respectively. This means that if there was a |
| preemption attempt during the RCU-sched read-side critical section, |
| rcu_read_unlock_sched() will enter the scheduler, with all the |
| latency and overhead entailed. Just as with rcu_read_unlock_bh(), |
| this can make it look as if rcu_read_unlock_sched() was executing |
| very slowly. However, the highest-priority task won't be preempted, so |
| that task will enjoy low-overhead rcu_read_unlock_sched() |
| invocations. |
| |
| The `RCU-sched |
| API <https://lwn.net/Articles/609973/#RCU%20Per-Flavor%20API%20Table>`__ |
| includes rcu_read_lock_sched(), rcu_read_unlock_sched(), |
| rcu_read_lock_sched_notrace(), rcu_read_unlock_sched_notrace(), |
| rcu_dereference_sched(), rcu_dereference_sched_check(), and |
| rcu_read_lock_sched_held(). However, the old RCU-sched update-side APIs |
| are now gone, replaced by synchronize_rcu(), synchronize_rcu_expedited(), |
| call_rcu(), and rcu_barrier(). In addition, anything that disables |
| preemption also marks an RCU-sched read-side critical section, |
| including preempt_disable() and preempt_enable(), local_irq_save() |
| and local_irq_restore(), and so on. |
| |
| Sleepable RCU |
| ~~~~~~~~~~~~~ |
| |
| For well over a decade, someone saying “I need to block within an RCU |
| read-side critical section” was a reliable indication that this someone |
| did not understand RCU. After all, if you are always blocking in an RCU |
| read-side critical section, you can probably afford to use a |
| higher-overhead synchronization mechanism. However, that changed with |
| the advent of the Linux kernel's notifiers, whose RCU read-side critical |
| sections almost never sleep, but sometimes need to. This resulted in the |
| introduction of `sleepable RCU <https://lwn.net/Articles/202847/>`__, or |
| *SRCU*. |
| |
| SRCU allows different domains to be defined, with each such domain |
| defined by an instance of an ``srcu_struct`` structure. A pointer to |
| this structure must be passed in to each SRCU function, for example, |
| ``synchronize_srcu(&ss)``, where ``ss`` is the ``srcu_struct`` |
| structure. The key benefit of these domains is that a slow SRCU reader |
| in one domain does not delay an SRCU grace period in some other domain. |
| That said, one consequence of these domains is that read-side code must |
| pass a “cookie” from srcu_read_lock() to srcu_read_unlock(), for |
| example, as follows: |
| |
| :: |
| |
| 1 int idx; |
| 2 |
| 3 idx = srcu_read_lock(&ss); |
| 4 do_something(); |
| 5 srcu_read_unlock(&ss, idx); |
| |
| As noted above, it is legal to block within SRCU read-side critical |
| sections, however, with great power comes great responsibility. If you |
| block forever in one of a given domain's SRCU read-side critical |
| sections, then that domain's grace periods will also be blocked forever. |
| Of course, one good way to block forever is to deadlock, which can |
| happen if any operation in a given domain's SRCU read-side critical |
| section can wait, either directly or indirectly, for that domain's grace |
| period to elapse. For example, this results in a self-deadlock: |
| |
| :: |
| |
| 1 int idx; |
| 2 |
| 3 idx = srcu_read_lock(&ss); |
| 4 do_something(); |
| 5 synchronize_srcu(&ss); |
| 6 srcu_read_unlock(&ss, idx); |
| |
| However, if line 5 acquired a mutex that was held across a |
| synchronize_srcu() for domain ``ss``, deadlock would still be |
| possible. Furthermore, if line 5 acquired a mutex that was held across a |
| synchronize_srcu() for some other domain ``ss1``, and if an |
| ``ss1``-domain SRCU read-side critical section acquired another mutex |
| that was held across as ``ss``-domain synchronize_srcu(), deadlock |
| would again be possible. Such a deadlock cycle could extend across an |
| arbitrarily large number of different SRCU domains. Again, with great |
| power comes great responsibility. |
| |
| Unlike the other RCU flavors, SRCU read-side critical sections can run |
| on idle and even offline CPUs. This ability requires that |
| srcu_read_lock() and srcu_read_unlock() contain memory barriers, |
| which means that SRCU readers will run a bit slower than would RCU |
| readers. It also motivates the smp_mb__after_srcu_read_unlock() API, |
| which, in combination with srcu_read_unlock(), guarantees a full |
| memory barrier. |
| |
| Also unlike other RCU flavors, synchronize_srcu() may **not** be |
| invoked from CPU-hotplug notifiers, due to the fact that SRCU grace |
| periods make use of timers and the possibility of timers being |
| temporarily “stranded” on the outgoing CPU. This stranding of timers |
| means that timers posted to the outgoing CPU will not fire until late in |
| the CPU-hotplug process. The problem is that if a notifier is waiting on |
| an SRCU grace period, that grace period is waiting on a timer, and that |
| timer is stranded on the outgoing CPU, then the notifier will never be |
| awakened, in other words, deadlock has occurred. This same situation of |
| course also prohibits srcu_barrier() from being invoked from |
| CPU-hotplug notifiers. |
| |
| SRCU also differs from other RCU flavors in that SRCU's expedited and |
| non-expedited grace periods are implemented by the same mechanism. This |
| means that in the current SRCU implementation, expediting a future grace |
| period has the side effect of expediting all prior grace periods that |
| have not yet completed. (But please note that this is a property of the |
| current implementation, not necessarily of future implementations.) In |
| addition, if SRCU has been idle for longer than the interval specified |
| by the ``srcutree.exp_holdoff`` kernel boot parameter (25 microseconds |
| by default), and if a synchronize_srcu() invocation ends this idle |
| period, that invocation will be automatically expedited. |
| |
| As of v4.12, SRCU's callbacks are maintained per-CPU, eliminating a |
| locking bottleneck present in prior kernel versions. Although this will |
| allow users to put much heavier stress on call_srcu(), it is |
| important to note that SRCU does not yet take any special steps to deal |
| with callback flooding. So if you are posting (say) 10,000 SRCU |
| callbacks per second per CPU, you are probably totally OK, but if you |
| intend to post (say) 1,000,000 SRCU callbacks per second per CPU, please |
| run some tests first. SRCU just might need a few adjustment to deal with |
| that sort of load. Of course, your mileage may vary based on the speed |
| of your CPUs and the size of your memory. |
| |
| The `SRCU |
| API <https://lwn.net/Articles/609973/#RCU%20Per-Flavor%20API%20Table>`__ |
| includes srcu_read_lock(), srcu_read_unlock(), |
| srcu_dereference(), srcu_dereference_check(), |
| synchronize_srcu(), synchronize_srcu_expedited(), |
| call_srcu(), srcu_barrier(), and srcu_read_lock_held(). It |
| also includes DEFINE_SRCU(), DEFINE_STATIC_SRCU(), and |
| init_srcu_struct() APIs for defining and initializing |
| ``srcu_struct`` structures. |
| |
| More recently, the SRCU API has added polling interfaces: |
| |
| #. start_poll_synchronize_srcu() returns a cookie identifying |
| the completion of a future SRCU grace period and ensures |
| that this grace period will be started. |
| #. poll_state_synchronize_srcu() returns ``true`` iff the |
| specified cookie corresponds to an already-completed |
| SRCU grace period. |
| #. get_state_synchronize_srcu() returns a cookie just like |
| start_poll_synchronize_srcu() does, but differs in that |
| it does nothing to ensure that any future SRCU grace period |
| will be started. |
| |
| These functions are used to avoid unnecessary SRCU grace periods in |
| certain types of buffer-cache algorithms having multi-stage age-out |
| mechanisms. The idea is that by the time the block has aged completely |
| from the cache, an SRCU grace period will be very likely to have elapsed. |
| |
| Tasks RCU |
| ~~~~~~~~~ |
| |
| Some forms of tracing use “trampolines” to handle the binary rewriting |
| required to install different types of probes. It would be good to be |
| able to free old trampolines, which sounds like a job for some form of |
| RCU. However, because it is necessary to be able to install a trace |
| anywhere in the code, it is not possible to use read-side markers such |
| as rcu_read_lock() and rcu_read_unlock(). In addition, it does |
| not work to have these markers in the trampoline itself, because there |
| would need to be instructions following rcu_read_unlock(). Although |
| synchronize_rcu() would guarantee that execution reached the |
| rcu_read_unlock(), it would not be able to guarantee that execution |
| had completely left the trampoline. Worse yet, in some situations |
| the trampoline's protection must extend a few instructions *prior* to |
| execution reaching the trampoline. For example, these few instructions |
| might calculate the address of the trampoline, so that entering the |
| trampoline would be pre-ordained a surprisingly long time before execution |
| actually reached the trampoline itself. |
| |
| The solution, in the form of `Tasks |
| RCU <https://lwn.net/Articles/607117/>`__, is to have implicit read-side |
| critical sections that are delimited by voluntary context switches, that |
| is, calls to schedule(), cond_resched(), and |
| synchronize_rcu_tasks(). In addition, transitions to and from |
| userspace execution also delimit tasks-RCU read-side critical sections. |
| |
| The tasks-RCU API is quite compact, consisting only of |
| call_rcu_tasks(), synchronize_rcu_tasks(), and |
| rcu_barrier_tasks(). In ``CONFIG_PREEMPTION=n`` kernels, trampolines |
| cannot be preempted, so these APIs map to call_rcu(), |
| synchronize_rcu(), and rcu_barrier(), respectively. In |
| ``CONFIG_PREEMPTION=y`` kernels, trampolines can be preempted, and these |
| three APIs are therefore implemented by separate functions that check |
| for voluntary context switches. |
| |
| Tasks Rude RCU |
| ~~~~~~~~~~~~~~ |
| |
| Some forms of tracing need to wait for all preemption-disabled regions |
| of code running on any online CPU, including those executed when RCU is |
| not watching. This means that synchronize_rcu() is insufficient, and |
| Tasks Rude RCU must be used instead. This flavor of RCU does its work by |
| forcing a workqueue to be scheduled on each online CPU, hence the "Rude" |
| moniker. And this operation is considered to be quite rude by real-time |
| workloads that don't want their ``nohz_full`` CPUs receiving IPIs and |
| by battery-powered systems that don't want their idle CPUs to be awakened. |
| |
| The tasks-rude-RCU API is also reader-marking-free and thus quite compact, |
| consisting of call_rcu_tasks_rude(), synchronize_rcu_tasks_rude(), |
| and rcu_barrier_tasks_rude(). |
| |
| Tasks Trace RCU |
| ~~~~~~~~~~~~~~~ |
| |
| Some forms of tracing need to sleep in readers, but cannot tolerate |
| SRCU's read-side overhead, which includes a full memory barrier in both |
| srcu_read_lock() and srcu_read_unlock(). This need is handled by a |
| Tasks Trace RCU that uses scheduler locking and IPIs to synchronize with |
| readers. Real-time systems that cannot tolerate IPIs may build their |
| kernels with ``CONFIG_TASKS_TRACE_RCU_READ_MB=y``, which avoids the IPIs at |
| the expense of adding full memory barriers to the read-side primitives. |
| |
| The tasks-trace-RCU API is also reasonably compact, |
| consisting of rcu_read_lock_trace(), rcu_read_unlock_trace(), |
| rcu_read_lock_trace_held(), call_rcu_tasks_trace(), |
| synchronize_rcu_tasks_trace(), and rcu_barrier_tasks_trace(). |
| |
| Possible Future Changes |
| ----------------------- |
| |
| One of the tricks that RCU uses to attain update-side scalability is to |
| increase grace-period latency with increasing numbers of CPUs. If this |
| becomes a serious problem, it will be necessary to rework the |
| grace-period state machine so as to avoid the need for the additional |
| latency. |
| |
| RCU disables CPU hotplug in a few places, perhaps most notably in the |
| rcu_barrier() operations. If there is a strong reason to use |
| rcu_barrier() in CPU-hotplug notifiers, it will be necessary to |
| avoid disabling CPU hotplug. This would introduce some complexity, so |
| there had better be a *very* good reason. |
| |
| The tradeoff between grace-period latency on the one hand and |
| interruptions of other CPUs on the other hand may need to be |
| re-examined. The desire is of course for zero grace-period latency as |
| well as zero interprocessor interrupts undertaken during an expedited |
| grace period operation. While this ideal is unlikely to be achievable, |
| it is quite possible that further improvements can be made. |
| |
| The multiprocessor implementations of RCU use a combining tree that |
| groups CPUs so as to reduce lock contention and increase cache locality. |
| However, this combining tree does not spread its memory across NUMA |
| nodes nor does it align the CPU groups with hardware features such as |
| sockets or cores. Such spreading and alignment is currently believed to |
| be unnecessary because the hotpath read-side primitives do not access |
| the combining tree, nor does call_rcu() in the common case. If you |
| believe that your architecture needs such spreading and alignment, then |
| your architecture should also benefit from the |
| ``rcutree.rcu_fanout_leaf`` boot parameter, which can be set to the |
| number of CPUs in a socket, NUMA node, or whatever. If the number of |
| CPUs is too large, use a fraction of the number of CPUs. If the number |
| of CPUs is a large prime number, well, that certainly is an |
| “interesting” architectural choice! More flexible arrangements might be |
| considered, but only if ``rcutree.rcu_fanout_leaf`` has proven |
| inadequate, and only if the inadequacy has been demonstrated by a |
| carefully run and realistic system-level workload. |
| |
| Please note that arrangements that require RCU to remap CPU numbers will |
| require extremely good demonstration of need and full exploration of |
| alternatives. |
| |
| RCU's various kthreads are reasonably recent additions. It is quite |
| likely that adjustments will be required to more gracefully handle |
| extreme loads. It might also be necessary to be able to relate CPU |
| utilization by RCU's kthreads and softirq handlers to the code that |
| instigated this CPU utilization. For example, RCU callback overhead |
| might be charged back to the originating call_rcu() instance, though |
| probably not in production kernels. |
| |
| Additional work may be required to provide reasonable forward-progress |
| guarantees under heavy load for grace periods and for callback |
| invocation. |
| |
| Summary |
| ------- |
| |
| This document has presented more than two decade's worth of RCU |
| requirements. Given that the requirements keep changing, this will not |
| be the last word on this subject, but at least it serves to get an |
| important subset of the requirements set forth. |
| |
| Acknowledgments |
| --------------- |
| |
| I am grateful to Steven Rostedt, Lai Jiangshan, Ingo Molnar, Oleg |
| Nesterov, Borislav Petkov, Peter Zijlstra, Boqun Feng, and Andy |
| Lutomirski for their help in rendering this article human readable, and |
| to Michelle Rankin for her support of this effort. Other contributions |
| are acknowledged in the Linux kernel's git archive. |