diff options
Diffstat (limited to 'kernel/rcu/tree.c')
| -rw-r--r-- | kernel/rcu/tree.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index e41dd4131f7a..9fd5b628a88d 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -1614,7 +1614,6 @@ static int rcu_future_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp) | |||
| 1614 | int needmore; | 1614 | int needmore; |
| 1615 | struct rcu_data *rdp = this_cpu_ptr(rsp->rda); | 1615 | struct rcu_data *rdp = this_cpu_ptr(rsp->rda); |
| 1616 | 1616 | ||
| 1617 | rcu_nocb_gp_cleanup(rsp, rnp); | ||
| 1618 | rnp->need_future_gp[c & 0x1] = 0; | 1617 | rnp->need_future_gp[c & 0x1] = 0; |
| 1619 | needmore = rnp->need_future_gp[(c + 1) & 0x1]; | 1618 | needmore = rnp->need_future_gp[(c + 1) & 0x1]; |
| 1620 | trace_rcu_future_gp(rnp, rdp, c, | 1619 | trace_rcu_future_gp(rnp, rdp, c, |
| @@ -1635,7 +1634,7 @@ static void rcu_gp_kthread_wake(struct rcu_state *rsp) | |||
| 1635 | !READ_ONCE(rsp->gp_flags) || | 1634 | !READ_ONCE(rsp->gp_flags) || |
| 1636 | !rsp->gp_kthread) | 1635 | !rsp->gp_kthread) |
| 1637 | return; | 1636 | return; |
| 1638 | wake_up(&rsp->gp_wq); | 1637 | swake_up(&rsp->gp_wq); |
| 1639 | } | 1638 | } |
| 1640 | 1639 | ||
| 1641 | /* | 1640 | /* |
| @@ -2010,6 +2009,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp) | |||
| 2010 | int nocb = 0; | 2009 | int nocb = 0; |
| 2011 | struct rcu_data *rdp; | 2010 | struct rcu_data *rdp; |
| 2012 | struct rcu_node *rnp = rcu_get_root(rsp); | 2011 | struct rcu_node *rnp = rcu_get_root(rsp); |
| 2012 | struct swait_queue_head *sq; | ||
| 2013 | 2013 | ||
| 2014 | WRITE_ONCE(rsp->gp_activity, jiffies); | 2014 | WRITE_ONCE(rsp->gp_activity, jiffies); |
| 2015 | raw_spin_lock_irq_rcu_node(rnp); | 2015 | raw_spin_lock_irq_rcu_node(rnp); |
| @@ -2046,7 +2046,9 @@ static void rcu_gp_cleanup(struct rcu_state *rsp) | |||
| 2046 | needgp = __note_gp_changes(rsp, rnp, rdp) || needgp; | 2046 | needgp = __note_gp_changes(rsp, rnp, rdp) || needgp; |
| 2047 | /* smp_mb() provided by prior unlock-lock pair. */ | 2047 | /* smp_mb() provided by prior unlock-lock pair. */ |
| 2048 | nocb += rcu_future_gp_cleanup(rsp, rnp); | 2048 | nocb += rcu_future_gp_cleanup(rsp, rnp); |
| 2049 | sq = rcu_nocb_gp_get(rnp); | ||
| 2049 | raw_spin_unlock_irq(&rnp->lock); | 2050 | raw_spin_unlock_irq(&rnp->lock); |
| 2051 | rcu_nocb_gp_cleanup(sq); | ||
| 2050 | cond_resched_rcu_qs(); | 2052 | cond_resched_rcu_qs(); |
| 2051 | WRITE_ONCE(rsp->gp_activity, jiffies); | 2053 | WRITE_ONCE(rsp->gp_activity, jiffies); |
| 2052 | rcu_gp_slow(rsp, gp_cleanup_delay); | 2054 | rcu_gp_slow(rsp, gp_cleanup_delay); |
| @@ -2092,7 +2094,7 @@ static int __noreturn rcu_gp_kthread(void *arg) | |||
| 2092 | READ_ONCE(rsp->gpnum), | 2094 | READ_ONCE(rsp->gpnum), |
| 2093 | TPS("reqwait")); | 2095 | TPS("reqwait")); |
| 2094 | rsp->gp_state = RCU_GP_WAIT_GPS; | 2096 | rsp->gp_state = RCU_GP_WAIT_GPS; |
| 2095 | wait_event_interruptible(rsp->gp_wq, | 2097 | swait_event_interruptible(rsp->gp_wq, |
| 2096 | READ_ONCE(rsp->gp_flags) & | 2098 | READ_ONCE(rsp->gp_flags) & |
| 2097 | RCU_GP_FLAG_INIT); | 2099 | RCU_GP_FLAG_INIT); |
| 2098 | rsp->gp_state = RCU_GP_DONE_GPS; | 2100 | rsp->gp_state = RCU_GP_DONE_GPS; |
| @@ -2122,7 +2124,7 @@ static int __noreturn rcu_gp_kthread(void *arg) | |||
| 2122 | READ_ONCE(rsp->gpnum), | 2124 | READ_ONCE(rsp->gpnum), |
| 2123 | TPS("fqswait")); | 2125 | TPS("fqswait")); |
| 2124 | rsp->gp_state = RCU_GP_WAIT_FQS; | 2126 | rsp->gp_state = RCU_GP_WAIT_FQS; |
| 2125 | ret = wait_event_interruptible_timeout(rsp->gp_wq, | 2127 | ret = swait_event_interruptible_timeout(rsp->gp_wq, |
| 2126 | rcu_gp_fqs_check_wake(rsp, &gf), j); | 2128 | rcu_gp_fqs_check_wake(rsp, &gf), j); |
| 2127 | rsp->gp_state = RCU_GP_DOING_FQS; | 2129 | rsp->gp_state = RCU_GP_DOING_FQS; |
| 2128 | /* Locking provides needed memory barriers. */ | 2130 | /* Locking provides needed memory barriers. */ |
| @@ -2246,7 +2248,7 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags) | |||
| 2246 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); | 2248 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); |
| 2247 | WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS); | 2249 | WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS); |
| 2248 | raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags); | 2250 | raw_spin_unlock_irqrestore(&rcu_get_root(rsp)->lock, flags); |
| 2249 | rcu_gp_kthread_wake(rsp); | 2251 | swake_up(&rsp->gp_wq); /* Memory barrier implied by swake_up() path. */ |
| 2250 | } | 2252 | } |
| 2251 | 2253 | ||
| 2252 | /* | 2254 | /* |
| @@ -2900,7 +2902,7 @@ static void force_quiescent_state(struct rcu_state *rsp) | |||
| 2900 | } | 2902 | } |
| 2901 | WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS); | 2903 | WRITE_ONCE(rsp->gp_flags, READ_ONCE(rsp->gp_flags) | RCU_GP_FLAG_FQS); |
| 2902 | raw_spin_unlock_irqrestore(&rnp_old->lock, flags); | 2904 | raw_spin_unlock_irqrestore(&rnp_old->lock, flags); |
| 2903 | rcu_gp_kthread_wake(rsp); | 2905 | swake_up(&rsp->gp_wq); /* Memory barrier implied by swake_up() path. */ |
| 2904 | } | 2906 | } |
| 2905 | 2907 | ||
| 2906 | /* | 2908 | /* |
| @@ -3529,7 +3531,7 @@ static void __rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp, | |||
| 3529 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 3531 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
| 3530 | if (wake) { | 3532 | if (wake) { |
| 3531 | smp_mb(); /* EGP done before wake_up(). */ | 3533 | smp_mb(); /* EGP done before wake_up(). */ |
| 3532 | wake_up(&rsp->expedited_wq); | 3534 | swake_up(&rsp->expedited_wq); |
| 3533 | } | 3535 | } |
| 3534 | break; | 3536 | break; |
| 3535 | } | 3537 | } |
| @@ -3780,7 +3782,7 @@ static void synchronize_sched_expedited_wait(struct rcu_state *rsp) | |||
| 3780 | jiffies_start = jiffies; | 3782 | jiffies_start = jiffies; |
| 3781 | 3783 | ||
| 3782 | for (;;) { | 3784 | for (;;) { |
| 3783 | ret = wait_event_interruptible_timeout( | 3785 | ret = swait_event_timeout( |
| 3784 | rsp->expedited_wq, | 3786 | rsp->expedited_wq, |
| 3785 | sync_rcu_preempt_exp_done(rnp_root), | 3787 | sync_rcu_preempt_exp_done(rnp_root), |
| 3786 | jiffies_stall); | 3788 | jiffies_stall); |
| @@ -3788,7 +3790,7 @@ static void synchronize_sched_expedited_wait(struct rcu_state *rsp) | |||
| 3788 | return; | 3790 | return; |
| 3789 | if (ret < 0) { | 3791 | if (ret < 0) { |
| 3790 | /* Hit a signal, disable CPU stall warnings. */ | 3792 | /* Hit a signal, disable CPU stall warnings. */ |
| 3791 | wait_event(rsp->expedited_wq, | 3793 | swait_event(rsp->expedited_wq, |
| 3792 | sync_rcu_preempt_exp_done(rnp_root)); | 3794 | sync_rcu_preempt_exp_done(rnp_root)); |
| 3793 | return; | 3795 | return; |
| 3794 | } | 3796 | } |
| @@ -4482,8 +4484,8 @@ static void __init rcu_init_one(struct rcu_state *rsp) | |||
| 4482 | } | 4484 | } |
| 4483 | } | 4485 | } |
| 4484 | 4486 | ||
| 4485 | init_waitqueue_head(&rsp->gp_wq); | 4487 | init_swait_queue_head(&rsp->gp_wq); |
| 4486 | init_waitqueue_head(&rsp->expedited_wq); | 4488 | init_swait_queue_head(&rsp->expedited_wq); |
| 4487 | rnp = rsp->level[rcu_num_lvls - 1]; | 4489 | rnp = rsp->level[rcu_num_lvls - 1]; |
| 4488 | for_each_possible_cpu(i) { | 4490 | for_each_possible_cpu(i) { |
| 4489 | while (i > rnp->grphi) | 4491 | while (i > rnp->grphi) |
