Loading Documentation/RCU/Design/Data-Structures/Data-Structures.html +32 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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 Loading
Documentation/RCU/Design/Data-Structures/Data-Structures.html +32 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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