diff options
| -rw-r--r-- | kernel/rcu/tree.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index bcd635e42841..3f93033d3c61 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -1305,10 +1305,16 @@ rcu_start_future_gp(struct rcu_node *rnp, struct rcu_data *rdp, | |||
| 1305 | * believe that a grace period is in progress, then we must wait | 1305 | * believe that a grace period is in progress, then we must wait |
| 1306 | * for the one following, which is in "c". Because our request | 1306 | * for the one following, which is in "c". Because our request |
| 1307 | * will be noticed at the end of the current grace period, we don't | 1307 | * will be noticed at the end of the current grace period, we don't |
| 1308 | * need to explicitly start one. | 1308 | * need to explicitly start one. We only do the lockless check |
| 1309 | * of rnp_root's fields if the current rcu_node structure thinks | ||
| 1310 | * there is no grace period in flight, and because we hold rnp->lock, | ||
| 1311 | * the only possible change is when rnp_root's two fields are | ||
| 1312 | * equal, in which case rnp_root->gpnum might be concurrently | ||
| 1313 | * incremented. But that is OK, as it will just result in our | ||
| 1314 | * doing some extra useless work. | ||
| 1309 | */ | 1315 | */ |
| 1310 | if (rnp->gpnum != rnp->completed || | 1316 | if (rnp->gpnum != rnp->completed || |
| 1311 | ACCESS_ONCE(rnp->gpnum) != ACCESS_ONCE(rnp->completed)) { | 1317 | ACCESS_ONCE(rnp_root->gpnum) != ACCESS_ONCE(rnp_root->completed)) { |
| 1312 | rnp->need_future_gp[c & 0x1]++; | 1318 | rnp->need_future_gp[c & 0x1]++; |
| 1313 | trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleaf")); | 1319 | trace_rcu_future_gp(rnp, rdp, c, TPS("Startedleaf")); |
| 1314 | goto out; | 1320 | goto out; |
