doc: Update dyntick-idle design documentation for NMI/irq consolidation
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
parent
e68bbb266d
commit
3af3999b9a
@ -1182,8 +1182,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;
|
||||
@ -1191,15 +1191,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
|
||||
@ -1231,14 +1247,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>
|
||||
|
Loading…
Reference in New Issue
Block a user