diff options
-rw-r--r-- | kernel/rcutree.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 074cb2d974bf..2015bce749f9 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -1396,6 +1396,9 @@ static void rcu_gp_cleanup(struct rcu_state *rsp) | |||
1396 | rcu_for_each_node_breadth_first(rsp, rnp) { | 1396 | rcu_for_each_node_breadth_first(rsp, rnp) { |
1397 | raw_spin_lock_irq(&rnp->lock); | 1397 | raw_spin_lock_irq(&rnp->lock); |
1398 | rnp->completed = rsp->gpnum; | 1398 | rnp->completed = rsp->gpnum; |
1399 | rdp = this_cpu_ptr(rsp->rda); | ||
1400 | if (rnp == rdp->mynode) | ||
1401 | __rcu_process_gp_end(rsp, rnp, rdp); | ||
1399 | nocb += rcu_nocb_gp_cleanup(rsp, rnp); | 1402 | nocb += rcu_nocb_gp_cleanup(rsp, rnp); |
1400 | raw_spin_unlock_irq(&rnp->lock); | 1403 | raw_spin_unlock_irq(&rnp->lock); |
1401 | cond_resched(); | 1404 | cond_resched(); |
@@ -1408,6 +1411,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp) | |||
1408 | trace_rcu_grace_period(rsp->name, rsp->completed, "end"); | 1411 | trace_rcu_grace_period(rsp->name, rsp->completed, "end"); |
1409 | rsp->fqs_state = RCU_GP_IDLE; | 1412 | rsp->fqs_state = RCU_GP_IDLE; |
1410 | rdp = this_cpu_ptr(rsp->rda); | 1413 | rdp = this_cpu_ptr(rsp->rda); |
1414 | rcu_advance_cbs(rsp, rnp, rdp); /* Reduce false positives below. */ | ||
1411 | if (cpu_needs_another_gp(rsp, rdp)) | 1415 | if (cpu_needs_another_gp(rsp, rdp)) |
1412 | rsp->gp_flags = 1; | 1416 | rsp->gp_flags = 1; |
1413 | raw_spin_unlock_irq(&rnp->lock); | 1417 | raw_spin_unlock_irq(&rnp->lock); |
@@ -1497,6 +1501,15 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) | |||
1497 | struct rcu_data *rdp = this_cpu_ptr(rsp->rda); | 1501 | struct rcu_data *rdp = this_cpu_ptr(rsp->rda); |
1498 | struct rcu_node *rnp = rcu_get_root(rsp); | 1502 | struct rcu_node *rnp = rcu_get_root(rsp); |
1499 | 1503 | ||
1504 | /* | ||
1505 | * If there is no grace period in progress right now, any | ||
1506 | * callbacks we have up to this point will be satisfied by the | ||
1507 | * next grace period. Also, advancing the callbacks reduces the | ||
1508 | * probability of false positives from cpu_needs_another_gp() | ||
1509 | * resulting in pointless grace periods. So, advance callbacks! | ||
1510 | */ | ||
1511 | rcu_advance_cbs(rsp, rnp, rdp); | ||
1512 | |||
1500 | if (!rsp->gp_kthread || | 1513 | if (!rsp->gp_kthread || |
1501 | !cpu_needs_another_gp(rsp, rdp)) { | 1514 | !cpu_needs_another_gp(rsp, rdp)) { |
1502 | /* | 1515 | /* |
@@ -1509,14 +1522,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) | |||
1509 | return; | 1522 | return; |
1510 | } | 1523 | } |
1511 | 1524 | ||
1512 | /* | ||
1513 | * Because there is no grace period in progress right now, | ||
1514 | * any callbacks we have up to this point will be satisfied | ||
1515 | * by the next grace period. So this is a good place to | ||
1516 | * assign a grace period number to recently posted callbacks. | ||
1517 | */ | ||
1518 | rcu_accelerate_cbs(rsp, rnp, rdp); | ||
1519 | |||
1520 | rsp->gp_flags = RCU_GP_FLAG_INIT; | 1525 | rsp->gp_flags = RCU_GP_FLAG_INIT; |
1521 | raw_spin_unlock(&rnp->lock); /* Interrupts remain disabled. */ | 1526 | raw_spin_unlock(&rnp->lock); /* Interrupts remain disabled. */ |
1522 | 1527 | ||