diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-08-08 21:27:52 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-09-23 12:16:10 -0400 |
commit | f7be82093952ee4a74ffc8c729b2811f908cd9a4 (patch) | |
tree | 7462d2551c370edcf614e36cdefd008e2689b529 | |
parent | 272b98c6455f00884f0350f775c5342358ebb73f (diff) |
rcu: Improve grace-period start logic
This commit improves grace-period start logic by checking ->gp_flags
under the lock and by issuing a warning if a grace period is already
in progress.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r-- | kernel/rcutree.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 32618b3fe4e6..d679a522c0a2 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -1297,7 +1297,7 @@ static void note_gp_changes(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | /* | 1299 | /* |
1300 | * Initialize a new grace period. | 1300 | * Initialize a new grace period. Return 0 if no grace period required. |
1301 | */ | 1301 | */ |
1302 | static int rcu_gp_init(struct rcu_state *rsp) | 1302 | static int rcu_gp_init(struct rcu_state *rsp) |
1303 | { | 1303 | { |
@@ -1306,10 +1306,18 @@ static int rcu_gp_init(struct rcu_state *rsp) | |||
1306 | 1306 | ||
1307 | rcu_bind_gp_kthread(); | 1307 | rcu_bind_gp_kthread(); |
1308 | raw_spin_lock_irq(&rnp->lock); | 1308 | raw_spin_lock_irq(&rnp->lock); |
1309 | if (rsp->gp_flags == 0) { | ||
1310 | /* Spurious wakeup, tell caller to go back to sleep. */ | ||
1311 | raw_spin_unlock_irq(&rnp->lock); | ||
1312 | return 0; | ||
1313 | } | ||
1309 | rsp->gp_flags = 0; /* Clear all flags: New grace period. */ | 1314 | rsp->gp_flags = 0; /* Clear all flags: New grace period. */ |
1310 | 1315 | ||
1311 | if (rcu_gp_in_progress(rsp)) { | 1316 | if (WARN_ON_ONCE(rcu_gp_in_progress(rsp))) { |
1312 | /* Grace period already in progress, don't start another. */ | 1317 | /* |
1318 | * Grace period already in progress, don't start another. | ||
1319 | * Not supposed to be able to happen. | ||
1320 | */ | ||
1313 | raw_spin_unlock_irq(&rnp->lock); | 1321 | raw_spin_unlock_irq(&rnp->lock); |
1314 | return 0; | 1322 | return 0; |
1315 | } | 1323 | } |
@@ -1474,8 +1482,7 @@ static int __noreturn rcu_gp_kthread(void *arg) | |||
1474 | wait_event_interruptible(rsp->gp_wq, | 1482 | wait_event_interruptible(rsp->gp_wq, |
1475 | rsp->gp_flags & | 1483 | rsp->gp_flags & |
1476 | RCU_GP_FLAG_INIT); | 1484 | RCU_GP_FLAG_INIT); |
1477 | if ((rsp->gp_flags & RCU_GP_FLAG_INIT) && | 1485 | if (rcu_gp_init(rsp)) |
1478 | rcu_gp_init(rsp)) | ||
1479 | break; | 1486 | break; |
1480 | cond_resched(); | 1487 | cond_resched(); |
1481 | flush_signals(current); | 1488 | flush_signals(current); |