diff options
| -rw-r--r-- | kernel/rcu/tree.c | 14 | ||||
| -rw-r--r-- | kernel/rcu/tree.h | 2 | ||||
| -rw-r--r-- | kernel/rcu/tree_plugin.h | 31 |
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) | |||
| 3928 | static void rcu_migrate_callbacks(int cpu, struct rcu_state *rsp) | 3923 | static 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); | |||
| 493 | static void rcu_init_one_nocb(struct rcu_node *rnp); | 493 | static void rcu_init_one_nocb(struct rcu_node *rnp); |
| 494 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, | 494 | static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, |
| 495 | bool lazy, unsigned long flags); | 495 | bool lazy, unsigned long flags); |
| 496 | static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, | 496 | static 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); |
| 499 | static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp); | 499 | static 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 | */ |
| 1964 | static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, | 1964 | static 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 | ||
| 2462 | static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, | 2451 | static 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 | { |
