|
@@ -1305,10 +1305,16 @@ rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp,
|
|
|
* believe that a grace period is in progress, then we must wait
|
|
* believe that a grace period is in progress, then we must wait
|
|
|
* for the one following, which is in "c". Because our request
|
|
* for the one following, which is in "c". Because our request
|
|
|
* will be noticed at the end of the current grace period, we don't
|
|
* will be noticed at the end of the current grace period, we don't
|
|
|
- * need to explicitly start one.
|
|
|
|
|
|
|
+ * need to explicitly start one. We only do the lockless check
|
|
|
|
|
+ * of rnp_root's fields if the current rcu_node structure thinks
|
|
|
|
|
+ * there is no grace period in flight, and because we hold rnp->lock,
|
|
|
|
|
+ * the only possible change is when rnp_root's two fields are
|
|
|
|
|
+ * equal, in which case rnp_root->gpnum might be concurrently
|
|
|
|
|
+ * incremented. But that is OK, as it will just result in our
|
|
|
|
|
+ * doing some extra useless work.
|
|
|
*/
|
|
*/
|
|
|
if (rnp->gpnum != rnp->completed ||
|
|
if (rnp->gpnum != rnp->completed ||
|
|
|
- ACCESS_ONCE(rnp->gpnum) != ACCESS_ONCE(rnp->completed)) {
|
|
|
|
|
|
|
+ ACCESS_ONCE(rnp_root->gpnum) != ACCESS_ONCE(rnp_root->completed)) {
|
|
|
rnp->need_future_gp[c & 0x1]++;
|
|
rnp->need_future_gp[c & 0x1]++;
|
|
|
trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleaf"));
|
|
trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleaf"));
|
|
|
goto out;
|
|
goto out;
|