doc: Update data-structure documentation for ->gp_seq
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
parent
e44e73ca47
commit
b1e1f21f5b
@ -380,31 +380,26 @@ and therefore need no protection.
|
|||||||
as follows:
|
as follows:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
1 unsigned long gpnum;
|
1 unsigned long gp_seq;
|
||||||
2 unsigned long completed;
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>RCU grace periods are numbered, and
|
<p>RCU grace periods are numbered, and
|
||||||
the <tt>->gpnum</tt> field contains the number of the grace
|
the <tt>->gp_seq</tt> field contains the current grace-period
|
||||||
period that started most recently.
|
sequence number.
|
||||||
The <tt>->completed</tt> field contains the number of the
|
The bottom two bits are the state of the current grace period,
|
||||||
grace period that completed most recently.
|
which can be zero for not yet started or one for in progress.
|
||||||
If the two fields are equal, the RCU grace period that most recently
|
In other words, if the bottom two bits of <tt>->gp_seq</tt> are
|
||||||
started has already completed, and therefore the corresponding
|
zero, the corresponding flavor of RCU is idle.
|
||||||
flavor of RCU is idle.
|
Any other value in the bottom two bits indicates that something is broken.
|
||||||
If <tt>->gpnum</tt> is one greater than <tt>->completed</tt>,
|
This field is protected by the root <tt>rcu_node</tt> structure's
|
||||||
then <tt>->gpnum</tt> gives the number of the current RCU
|
|
||||||
grace period, which has not yet completed.
|
|
||||||
Any other combination of values indicates that something is broken.
|
|
||||||
These two fields are protected by the root <tt>rcu_node</tt>'s
|
|
||||||
<tt>->lock</tt> field.
|
<tt>->lock</tt> field.
|
||||||
|
|
||||||
</p><p>There are <tt>->gpnum</tt> and <tt>->completed</tt> fields
|
</p><p>There are <tt>->gp_seq</tt> fields
|
||||||
in the <tt>rcu_node</tt> and <tt>rcu_data</tt> structures
|
in the <tt>rcu_node</tt> and <tt>rcu_data</tt> structures
|
||||||
as well.
|
as well.
|
||||||
The fields in the <tt>rcu_state</tt> structure represent the
|
The fields in the <tt>rcu_state</tt> structure represent the
|
||||||
most current values, and those of the other structures are compared
|
most current value, and those of the other structures are compared
|
||||||
in order to detect the start of a new grace period in a distributed
|
in order to detect the beginnings and ends of grace periods in a distributed
|
||||||
fashion.
|
fashion.
|
||||||
The values flow from <tt>rcu_state</tt> to <tt>rcu_node</tt>
|
The values flow from <tt>rcu_state</tt> to <tt>rcu_node</tt>
|
||||||
(down the tree from the root to the leaves) to <tt>rcu_data</tt>.
|
(down the tree from the root to the leaves) to <tt>rcu_data</tt>.
|
||||||
@ -512,27 +507,47 @@ than to be heisenbugged out of existence.
|
|||||||
as follows:
|
as follows:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
1 unsigned long gpnum;
|
1 unsigned long gp_seq;
|
||||||
2 unsigned long completed;
|
2 unsigned long gp_seq_needed;
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>These fields are the counterparts of the fields of the same name in
|
<p>The <tt>rcu_node</tt> structures' <tt>->gp_seq</tt> fields are
|
||||||
the <tt>rcu_state</tt> structure.
|
the counterparts of the field of the same name in the <tt>rcu_state</tt>
|
||||||
They each may lag up to one behind their <tt>rcu_state</tt>
|
structure.
|
||||||
counterparts.
|
They each may lag up to one step behind their <tt>rcu_state</tt>
|
||||||
If a given <tt>rcu_node</tt> structure's <tt>->gpnum</tt> and
|
counterpart.
|
||||||
<tt>->complete</tt> fields are equal, then this <tt>rcu_node</tt>
|
If the bottom two bits of a given <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->gp_seq</tt> field is zero, then this <tt>rcu_node</tt>
|
||||||
structure believes that RCU is idle.
|
structure believes that RCU is idle.
|
||||||
Otherwise, as with the <tt>rcu_state</tt> structure,
|
</p><p>The <tt>>gp_seq</tt> field of each <tt>rcu_node</tt>
|
||||||
the <tt>->gpnum</tt> field will be one greater than the
|
structure is updated at the beginning and the end
|
||||||
<tt>->complete</tt> fields, with <tt>->gpnum</tt>
|
of each grace period.
|
||||||
indicating which grace period this <tt>rcu_node</tt> believes
|
|
||||||
is still being waited for.
|
|
||||||
|
|
||||||
</p><p>The <tt>>gpnum</tt> field of each <tt>rcu_node</tt>
|
<p>The <tt>->gp_seq_needed</tt> fields record the
|
||||||
structure is updated at the beginning
|
furthest-in-the-future grace period request seen by the corresponding
|
||||||
of each grace period, and the <tt>->completed</tt> fields are
|
<tt>rcu_node</tt> structure. The request is considered fulfilled when
|
||||||
updated at the end of each grace period.
|
the value of the <tt>->gp_seq</tt> field equals or exceeds that of
|
||||||
|
the <tt>->gp_seq_needed</tt> field.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
Suppose that this <tt>rcu_node</tt> structure doesn't see
|
||||||
|
a request for a very long time.
|
||||||
|
Won't wrapping of the <tt>->gp_seq</tt> field cause
|
||||||
|
problems?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
No, because if the <tt>->gp_seq_needed</tt> field lags behind the
|
||||||
|
<tt>->gp_seq</tt> field, the <tt>->gp_seq_needed</tt> field
|
||||||
|
will be updated at the end of the grace period.
|
||||||
|
Modulo-arithmetic comparisons therefore will always get the
|
||||||
|
correct answer, even with wrapping.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
<h5>Quiescent-State Tracking</h5>
|
<h5>Quiescent-State Tracking</h5>
|
||||||
|
|
||||||
@ -626,9 +641,8 @@ normal and expedited grace periods, respectively.
|
|||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p><font color="ffffff">So the locking is absolutely required in
|
<p><font color="ffffff">So the locking is absolutely required in
|
||||||
order to coordinate
|
order to coordinate clearing of the bits with updating of the
|
||||||
clearing of the bits with the grace-period numbers in
|
grace-period sequence number in <tt>->gp_seq</tt>.
|
||||||
<tt>->gpnum</tt> and <tt>->completed</tt>.
|
|
||||||
</font></td></tr>
|
</font></td></tr>
|
||||||
<tr><td> </td></tr>
|
<tr><td> </td></tr>
|
||||||
</table>
|
</table>
|
||||||
@ -1038,15 +1052,15 @@ out any <tt>rcu_data</tt> structure for which this flag is not set.
|
|||||||
as follows:
|
as follows:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
1 unsigned long completed;
|
1 unsigned long gp_seq;
|
||||||
2 unsigned long gpnum;
|
2 unsigned long gp_seq_needed;
|
||||||
3 bool cpu_no_qs;
|
3 bool cpu_no_qs;
|
||||||
4 bool core_needs_qs;
|
4 bool core_needs_qs;
|
||||||
5 bool gpwrap;
|
5 bool gpwrap;
|
||||||
6 unsigned long rcu_qs_ctr_snap;
|
6 unsigned long rcu_qs_ctr_snap;
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>The <tt>completed</tt> and <tt>gpnum</tt>
|
<p>The <tt>->gp_seq</tt> and <tt>->gp_seq_needed</tt>
|
||||||
fields are the counterparts of the fields of the same name
|
fields are the counterparts of the fields of the same name
|
||||||
in the <tt>rcu_state</tt> and <tt>rcu_node</tt> structures.
|
in the <tt>rcu_state</tt> and <tt>rcu_node</tt> structures.
|
||||||
They may each lag up to one behind their <tt>rcu_node</tt>
|
They may each lag up to one behind their <tt>rcu_node</tt>
|
||||||
@ -1054,15 +1068,9 @@ counterparts, but in <tt>CONFIG_NO_HZ_IDLE</tt> and
|
|||||||
<tt>CONFIG_NO_HZ_FULL</tt> kernels can lag
|
<tt>CONFIG_NO_HZ_FULL</tt> kernels can lag
|
||||||
arbitrarily far behind for CPUs in dyntick-idle mode (but these counters
|
arbitrarily far behind for CPUs in dyntick-idle mode (but these counters
|
||||||
will catch up upon exit from dyntick-idle mode).
|
will catch up upon exit from dyntick-idle mode).
|
||||||
If a given <tt>rcu_data</tt> structure's <tt>->gpnum</tt> and
|
If the lower two bits of a given <tt>rcu_data</tt> structure's
|
||||||
<tt>->complete</tt> fields are equal, then this <tt>rcu_data</tt>
|
<tt>->gp_seq</tt> are zero, then this <tt>rcu_data</tt>
|
||||||
structure believes that RCU is idle.
|
structure believes that RCU is idle.
|
||||||
Otherwise, as with the <tt>rcu_state</tt> and <tt>rcu_node</tt>
|
|
||||||
structure,
|
|
||||||
the <tt>->gpnum</tt> field will be one greater than the
|
|
||||||
<tt>->complete</tt> fields, with <tt>->gpnum</tt>
|
|
||||||
indicating which grace period this <tt>rcu_data</tt> believes
|
|
||||||
is still being waited for.
|
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr><th> </th></tr>
|
<tr><th> </th></tr>
|
||||||
@ -1070,13 +1078,13 @@ is still being waited for.
|
|||||||
<tr><td>
|
<tr><td>
|
||||||
All this replication of the grace period numbers can only cause
|
All this replication of the grace period numbers can only cause
|
||||||
massive confusion.
|
massive confusion.
|
||||||
Why not just keep a global pair of counters and be done with it???
|
Why not just keep a global sequence number and be done with it???
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><th align="left">Answer:</th></tr>
|
<tr><th align="left">Answer:</th></tr>
|
||||||
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
Because if there was only a single global pair of grace-period
|
Because if there was only a single global sequence
|
||||||
numbers, there would need to be a single global lock to allow
|
numbers, there would need to be a single global lock to allow
|
||||||
safely accessing and updating them.
|
safely accessing and updating it.
|
||||||
And if we are not going to have a single global lock, we need
|
And if we are not going to have a single global lock, we need
|
||||||
to carefully manage the numbers on a per-node basis.
|
to carefully manage the numbers on a per-node basis.
|
||||||
Recall from the answer to a previous Quick Quiz that the consequences
|
Recall from the answer to a previous Quick Quiz that the consequences
|
||||||
@ -1091,8 +1099,8 @@ CPU has not yet passed through a quiescent state,
|
|||||||
while the <tt>->core_needs_qs</tt> flag indicates that the
|
while the <tt>->core_needs_qs</tt> flag indicates that the
|
||||||
RCU core needs a quiescent state from the corresponding CPU.
|
RCU core needs a quiescent state from the corresponding CPU.
|
||||||
The <tt>->gpwrap</tt> field indicates that the corresponding
|
The <tt>->gpwrap</tt> field indicates that the corresponding
|
||||||
CPU has remained idle for so long that the <tt>completed</tt>
|
CPU has remained idle for so long that the
|
||||||
and <tt>gpnum</tt> counters are in danger of overflow, which
|
<tt>gp_seq</tt> counter is in danger of overflow, which
|
||||||
will cause the CPU to disregard the values of its counters on
|
will cause the CPU to disregard the values of its counters on
|
||||||
its next exit from idle.
|
its next exit from idle.
|
||||||
Finally, the <tt>rcu_qs_ctr_snap</tt> field is used to detect
|
Finally, the <tt>rcu_qs_ctr_snap</tt> field is used to detect
|
||||||
@ -1130,10 +1138,10 @@ The CPU advances the callbacks in its <tt>rcu_data</tt> structure
|
|||||||
whenever it notices that another RCU grace period has completed.
|
whenever it notices that another RCU grace period has completed.
|
||||||
The CPU detects the completion of an RCU grace period by noticing
|
The CPU detects the completion of an RCU grace period by noticing
|
||||||
that the value of its <tt>rcu_data</tt> structure's
|
that the value of its <tt>rcu_data</tt> structure's
|
||||||
<tt>->completed</tt> field differs from that of its leaf
|
<tt>->gp_seq</tt> field differs from that of its leaf
|
||||||
<tt>rcu_node</tt> structure.
|
<tt>rcu_node</tt> structure.
|
||||||
Recall that each <tt>rcu_node</tt> structure's
|
Recall that each <tt>rcu_node</tt> structure's
|
||||||
<tt>->completed</tt> field is updated at the end of each
|
<tt>->gp_seq</tt> field is updated at the beginnings and ends of each
|
||||||
grace period.
|
grace period.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
Loading…
Reference in New Issue
Block a user