diff options
Diffstat (limited to 'kernel/rcu/tree.c')
| -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 9bb5dff50815..f431114bc06a 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -3684,8 +3684,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp) | |||
| 3684 | */ | 3684 | */ |
| 3685 | rnp = rdp->mynode; | 3685 | rnp = rdp->mynode; |
| 3686 | raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */ | 3686 | raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */ |
| 3687 | if (!rdp->beenonline) | ||
| 3688 | WRITE_ONCE(rsp->ncpus, READ_ONCE(rsp->ncpus) + 1); | ||
| 3689 | rdp->beenonline = true; /* We have now been online. */ | 3687 | rdp->beenonline = true; /* We have now been online. */ |
| 3690 | rdp->gpnum = rnp->completed; /* Make CPU later note any new GP. */ | 3688 | rdp->gpnum = rnp->completed; /* Make CPU later note any new GP. */ |
| 3691 | rdp->completed = rnp->completed; | 3689 | rdp->completed = rnp->completed; |
| @@ -3789,6 +3787,8 @@ void rcu_cpu_starting(unsigned int cpu) | |||
| 3789 | { | 3787 | { |
| 3790 | unsigned long flags; | 3788 | unsigned long flags; |
| 3791 | unsigned long mask; | 3789 | unsigned long mask; |
| 3790 | int nbits; | ||
| 3791 | unsigned long oldmask; | ||
| 3792 | struct rcu_data *rdp; | 3792 | struct rcu_data *rdp; |
| 3793 | struct rcu_node *rnp; | 3793 | struct rcu_node *rnp; |
| 3794 | struct rcu_state *rsp; | 3794 | struct rcu_state *rsp; |
| @@ -3799,9 +3799,15 @@ void rcu_cpu_starting(unsigned int cpu) | |||
| 3799 | mask = rdp->grpmask; | 3799 | mask = rdp->grpmask; |
| 3800 | raw_spin_lock_irqsave_rcu_node(rnp, flags); | 3800 | raw_spin_lock_irqsave_rcu_node(rnp, flags); |
| 3801 | rnp->qsmaskinitnext |= mask; | 3801 | rnp->qsmaskinitnext |= mask; |
| 3802 | oldmask = rnp->expmaskinitnext; | ||
| 3802 | rnp->expmaskinitnext |= mask; | 3803 | rnp->expmaskinitnext |= mask; |
| 3804 | oldmask ^= rnp->expmaskinitnext; | ||
| 3805 | nbits = bitmap_weight(&oldmask, BITS_PER_LONG); | ||
| 3806 | /* Allow lockless access for expedited grace periods. */ | ||
| 3807 | smp_store_release(&rsp->ncpus, rsp->ncpus + nbits); /* ^^^ */ | ||
| 3803 | raw_spin_unlock_irqrestore_rcu_node(rnp, flags); | 3808 | raw_spin_unlock_irqrestore_rcu_node(rnp, flags); |
| 3804 | } | 3809 | } |
| 3810 | smp_mb(); /* Ensure RCU read-side usage follows above initialization. */ | ||
| 3805 | } | 3811 | } |
| 3806 | 3812 | ||
| 3807 | #ifdef CONFIG_HOTPLUG_CPU | 3813 | #ifdef CONFIG_HOTPLUG_CPU |
