diff options
Diffstat (limited to 'kernel/rcu/tree.c')
| -rw-r--r-- | kernel/rcu/tree.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 4ea28e820f4a..c080c6ed66af 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -3926,6 +3926,7 @@ static void rcu_migrate_callbacks(int cpu, struct rcu_state *rsp) | |||
| 3926 | struct rcu_data *my_rdp; | 3926 | struct rcu_data *my_rdp; |
| 3927 | struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); | 3927 | struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); |
| 3928 | struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rdp & rnp. */ | 3928 | struct rcu_node *rnp = rdp->mynode; /* Outgoing CPU's rdp & rnp. */ |
| 3929 | struct rcu_node *rnp_root = rcu_get_root(rdp->rsp); | ||
| 3929 | 3930 | ||
| 3930 | if (rcu_is_nocb_cpu(cpu) || rcu_segcblist_empty(&rdp->cblist)) | 3931 | if (rcu_is_nocb_cpu(cpu) || rcu_segcblist_empty(&rdp->cblist)) |
| 3931 | return; /* No callbacks to migrate. */ | 3932 | return; /* No callbacks to migrate. */ |
| @@ -3936,7 +3937,11 @@ static void rcu_migrate_callbacks(int cpu, struct rcu_state *rsp) | |||
| 3936 | local_irq_restore(flags); | 3937 | local_irq_restore(flags); |
| 3937 | return; | 3938 | return; |
| 3938 | } | 3939 | } |
| 3939 | raw_spin_lock(&rsp->orphan_lock); /* irqs already disabled. */ | 3940 | raw_spin_lock_rcu_node(rnp_root); /* irqs already disabled. */ |
| 3941 | rcu_advance_cbs(rsp, rnp_root, rdp); /* Leverage recent GPs. */ | ||
| 3942 | raw_spin_unlock_rcu_node(rnp_root); | ||
| 3943 | |||
| 3944 | raw_spin_lock(&rsp->orphan_lock); | ||
| 3940 | rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp); | 3945 | rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp); |
| 3941 | rcu_adopt_orphan_cbs(rsp, flags); | 3946 | rcu_adopt_orphan_cbs(rsp, flags); |
| 3942 | raw_spin_unlock_irqrestore(&rsp->orphan_lock, flags); | 3947 | raw_spin_unlock_irqrestore(&rsp->orphan_lock, flags); |
