aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcu/tree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-06-26 15:23:46 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-07-25 16:04:47 -0400
commitb1a2d79fe7d210c114003362d93d529912d244df (patch)
treef739fab6c1a267b7da1d1e611cab4ad9b4a97ddc /kernel/rcu/tree.c
parent95335c0355834c16cc11f041a981ee6782dba2e9 (diff)
rcu: Make NOCB CPUs migrate CBs directly from outgoing CPU
RCU's CPU-hotplug callback-migration code first moves the outgoing CPU's callbacks to ->orphan_done and ->orphan_pend, and only then moves them to the NOCB callback list. This commit avoids the extra step (and simplifies the code) by moving the callbacks directly from the outgoing CPU's callback list to the NOCB callback list. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcu/tree.c')
-rw-r--r--kernel/rcu/tree.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index aeea697d6f9f..4ea28e820f4a 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3899,11 +3899,6 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp, unsigned long flags)
3899 3899
3900 lockdep_assert_held(&rsp->orphan_lock); 3900 lockdep_assert_held(&rsp->orphan_lock);
3901 3901
3902 /* No-CBs CPUs are handled specially. */
3903 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU) ||
3904 rcu_nocb_adopt_orphan_cbs(rsp, rdp, flags))
3905 return;
3906
3907 /* Do the accounting first. */ 3902 /* Do the accounting first. */
3908 if (rsp->orphan_done.len_lazy != rsp->orphan_done.len) 3903 if (rsp->orphan_done.len_lazy != rsp->orphan_done.len)
3909 rcu_idle_count_callbacks_posted(); 3904 rcu_idle_count_callbacks_posted();
@@ -3928,13 +3923,20 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp, unsigned long flags)
3928static void rcu_migrate_callbacks(int cpu, struct rcu_state *rsp) 3923static void rcu_migrate_callbacks(int cpu, struct rcu_state *rsp)
3929{ 3924{
3930 unsigned long flags; 3925 unsigned long flags;
3926 struct rcu_data *my_rdp;
3931 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); 3927 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
3932 struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rdp & rnp. */ 3928 struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rdp & rnp. */
3933 3929
3934 if (rcu_is_nocb_cpu(cpu) || rcu_segcblist_empty(&rdp->cblist)) 3930 if (rcu_is_nocb_cpu(cpu) || rcu_segcblist_empty(&rdp->cblist))
3935 return; /* No callbacks to migrate. */ 3931 return; /* No callbacks to migrate. */
3936 3932
3937 raw_spin_lock_irqsave(&rsp->orphan_lock, flags); 3933 local_irq_save(flags);
3934 my_rdp = this_cpu_ptr(rsp->rda);
3935 if (rcu_nocb_adopt_orphan_cbs(my_rdp, rdp, flags)) {
3936 local_irq_restore(flags);
3937 return;
3938 }
3939 raw_spin_lock(&rsp->orphan_lock); /* irqs already disabled. */
3938 rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp); 3940 rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp);
3939 rcu_adopt_orphan_cbs(rsp, flags); 3941 rcu_adopt_orphan_cbs(rsp, flags);
3940 raw_spin_unlock_irqrestore(&rsp->orphan_lock, flags); 3942 raw_spin_unlock_irqrestore(&rsp->orphan_lock, flags);