aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/rcu/tree.c14
-rw-r--r--kernel/rcu/tree.h2
-rw-r--r--kernel/rcu/tree_plugin.h31
3 files changed, 19 insertions, 28 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);
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index aec53c4d4aec..574513cf49b4 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -493,7 +493,7 @@ static void rcu_nocb_gp_cleanup(struct swait_queue_head *sq);
493static void rcu_init_one_nocb(struct rcu_node *rnp); 493static void rcu_init_one_nocb(struct rcu_node *rnp);
494static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, 494static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
495 bool lazy, unsigned long flags); 495 bool lazy, unsigned long flags);
496static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, 496static bool rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp,
497 struct rcu_data *rdp, 497 struct rcu_data *rdp,
498 unsigned long flags); 498 unsigned long flags);
499static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp); 499static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp);
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 908b309d60d7..ff7d5ee49816 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -1961,30 +1961,19 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
1961 * Adopt orphaned callbacks on a no-CBs CPU, or return 0 if this is 1961 * Adopt orphaned callbacks on a no-CBs CPU, or return 0 if this is
1962 * not a no-CBs CPU. 1962 * not a no-CBs CPU.
1963 */ 1963 */
1964static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, 1964static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp,
1965 struct rcu_data *rdp, 1965 struct rcu_data *rdp,
1966 unsigned long flags) 1966 unsigned long flags)
1967{ 1967{
1968 long ql = rsp->orphan_done.len; 1968 RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_nocb_adopt_orphan_cbs() invoked with irqs enabled!!!");
1969 long qll = rsp->orphan_done.len_lazy;
1970
1971 /* If this is not a no-CBs CPU, tell the caller to do it the old way. */
1972 if (!rcu_is_nocb_cpu(smp_processor_id())) 1969 if (!rcu_is_nocb_cpu(smp_processor_id()))
1973 return false; 1970 return false; /* Not NOCBs CPU, caller must migrate CBs. */
1974 1971 __call_rcu_nocb_enqueue(my_rdp, rcu_segcblist_head(&rdp->cblist),
1975 /* First, enqueue the donelist, if any. This preserves CB ordering. */ 1972 rcu_segcblist_tail(&rdp->cblist),
1976 if (rsp->orphan_done.head) { 1973 rcu_segcblist_n_cbs(&rdp->cblist),
1977 __call_rcu_nocb_enqueue(rdp, rcu_cblist_head(&rsp->orphan_done), 1974 rcu_segcblist_n_lazy_cbs(&rdp->cblist), flags);
1978 rcu_cblist_tail(&rsp->orphan_done), 1975 rcu_segcblist_init(&rdp->cblist);
1979 ql, qll, flags); 1976 rcu_segcblist_disable(&rdp->cblist);
1980 }
1981 if (rsp->orphan_pend.head) {
1982 __call_rcu_nocb_enqueue(rdp, rcu_cblist_head(&rsp->orphan_pend),
1983 rcu_cblist_tail(&rsp->orphan_pend),
1984 ql, qll, flags);
1985 }
1986 rcu_cblist_init(&rsp->orphan_done);
1987 rcu_cblist_init(&rsp->orphan_pend);
1988 return true; 1977 return true;
1989} 1978}
1990 1979
@@ -2459,7 +2448,7 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
2459 return false; 2448 return false;
2460} 2449}
2461 2450
2462static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, 2451static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_data *my_rdp,
2463 struct rcu_data *rdp, 2452 struct rcu_data *rdp,
2464 unsigned long flags) 2453 unsigned long flags)
2465{ 2454{