Restore docs "rcu: Restore barrier() to rcu_read_lock() and rcu_read_unlock()"

This restores docs back in ReST format.

Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
[ paulmck: Added Joel's SoB per Stephen Rothwell feedback. ]
[ paulmck: Joel approved via private email. ]
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
This commit is contained in:
Joel Fernandes (Google) 2019-08-01 17:39:22 -04:00 committed by Paul E. McKenney
parent d7424e283c
commit 71cb46ae46
1 changed files with 54 additions and 0 deletions

View File

@ -1691,6 +1691,7 @@ follows:
#. `Hotplug CPU`_
#. `Scheduler and RCU`_
#. `Tracing and RCU`_
#. `Accesses to User Memory and RCU`_
#. `Energy Efficiency`_
#. `Scheduling-Clock Interrupts and RCU`_
#. `Memory Efficiency`_
@ -2004,6 +2005,59 @@ 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_PREEMPT=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
~~~~~~~~~~~~~~~~~