Merge branches 'cond_resched.2017.12.04a', 'dyntick.2017.11.28a', 'fixes.2017.12.11a', 'srbd.2017.12.05a' and 'torture.2017.12.11a' into HEAD
cond_resched.2017.12.04a: Convert cond_resched_rcu_qs() to cond_resched() dyntick.2017.11.28a: Make RCU dynticks handle interrupts from NMI fixes.2017.12.11a: Miscellaneous fixes srbd.2017.12.05a: Remove now-redundant smp_read_barrier_depends() torture.2017.12.11a: Torture-testing update
This commit is contained in:
@@ -1183,8 +1183,8 @@ CPU (and from tracing) unless otherwise stated.
|
||||
Its fields are as follows:
|
||||
|
||||
<pre>
|
||||
1 int dynticks_nesting;
|
||||
2 int dynticks_nmi_nesting;
|
||||
1 long dynticks_nesting;
|
||||
2 long dynticks_nmi_nesting;
|
||||
3 atomic_t dynticks;
|
||||
4 bool rcu_need_heavy_qs;
|
||||
5 unsigned long rcu_qs_ctr;
|
||||
@@ -1192,15 +1192,31 @@ Its fields are as follows:
|
||||
</pre>
|
||||
|
||||
<p>The <tt>->dynticks_nesting</tt> field counts the
|
||||
nesting depth of normal interrupts.
|
||||
In addition, this counter is incremented when exiting dyntick-idle
|
||||
mode and decremented when entering it.
|
||||
nesting depth of process execution, so that in normal circumstances
|
||||
this counter has value zero or one.
|
||||
NMIs, irqs, and tracers are counted by the <tt>->dynticks_nmi_nesting</tt>
|
||||
field.
|
||||
Because NMIs cannot be masked, changes to this variable have to be
|
||||
undertaken carefully using an algorithm provided by Andy Lutomirski.
|
||||
The initial transition from idle adds one, and nested transitions
|
||||
add two, so that a nesting level of five is represented by a
|
||||
<tt>->dynticks_nmi_nesting</tt> value of nine.
|
||||
This counter can therefore be thought of as counting the number
|
||||
of reasons why this CPU cannot be permitted to enter dyntick-idle
|
||||
mode, aside from non-maskable interrupts (NMIs).
|
||||
NMIs are counted by the <tt>->dynticks_nmi_nesting</tt>
|
||||
field, except that NMIs that interrupt non-dyntick-idle execution
|
||||
are not counted.
|
||||
mode, aside from process-level transitions.
|
||||
|
||||
<p>However, it turns out that when running in non-idle kernel context,
|
||||
the Linux kernel is fully capable of entering interrupt handlers that
|
||||
never exit and perhaps also vice versa.
|
||||
Therefore, whenever the <tt>->dynticks_nesting</tt> field is
|
||||
incremented up from zero, the <tt>->dynticks_nmi_nesting</tt> field
|
||||
is set to a large positive number, and whenever the
|
||||
<tt>->dynticks_nesting</tt> field is decremented down to zero,
|
||||
the the <tt>->dynticks_nmi_nesting</tt> field is set to zero.
|
||||
Assuming that the number of misnested interrupts is not sufficient
|
||||
to overflow the counter, this approach corrects the
|
||||
<tt>->dynticks_nmi_nesting</tt> field every time the corresponding
|
||||
CPU enters the idle loop from process context.
|
||||
|
||||
</p><p>The <tt>->dynticks</tt> field counts the corresponding
|
||||
CPU's transitions to and from dyntick-idle mode, so that this counter
|
||||
@@ -1232,14 +1248,16 @@ in response.
|
||||
<tr><th> </th></tr>
|
||||
<tr><th align="left">Quick Quiz:</th></tr>
|
||||
<tr><td>
|
||||
Why not just count all NMIs?
|
||||
Wouldn't that be simpler and less error prone?
|
||||
Why not simply combine the <tt>->dynticks_nesting</tt>
|
||||
and <tt>->dynticks_nmi_nesting</tt> counters into a
|
||||
single counter that just counts the number of reasons that
|
||||
the corresponding CPU is non-idle?
|
||||
</td></tr>
|
||||
<tr><th align="left">Answer:</th></tr>
|
||||
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||
It seems simpler only until you think hard about how to go about
|
||||
updating the <tt>rcu_dynticks</tt> structure's
|
||||
<tt>->dynticks</tt> field.
|
||||
Because this would fail in the presence of interrupts whose
|
||||
handlers never return and of handlers that manage to return
|
||||
from a made-up interrupt.
|
||||
</font></td></tr>
|
||||
<tr><td> </td></tr>
|
||||
</table>
|
||||
|
@@ -581,7 +581,8 @@ This guarantee was only partially premeditated.
|
||||
DYNIX/ptx used an explicit memory barrier for publication, but had nothing
|
||||
resembling <tt>rcu_dereference()</tt> for subscription, nor did it
|
||||
have anything resembling the <tt>smp_read_barrier_depends()</tt>
|
||||
that was later subsumed into <tt>rcu_dereference()</tt>.
|
||||
that was later subsumed into <tt>rcu_dereference()</tt> and later
|
||||
still into <tt>READ_ONCE()</tt>.
|
||||
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.
|
||||
|
Reference in New Issue
Block a user