[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] rcu: Migrate RCU work when taking a CPU offline.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1274274397 -3600
# Node ID bc2364ad816d1979b21a869316abdaa6e6dfc033
# Parent  a3cf0d9a1b188d65c84186536a7c004790235af6
rcu: Migrate RCU work when taking a CPU offline.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/common/rcupdate.c |   39 ++++++++++++++++++++++++++++++++++++---
 1 files changed, 36 insertions(+), 3 deletions(-)

diff -r a3cf0d9a1b18 -r bc2364ad816d xen/common/rcupdate.c
--- a/xen/common/rcupdate.c     Wed May 19 12:53:44 2010 +0100
+++ b/xen/common/rcupdate.c     Wed May 19 14:06:37 2010 +0100
@@ -322,6 +322,36 @@ void rcu_check_callbacks(int cpu)
     raise_softirq(RCU_SOFTIRQ);
 }
 
+static void rcu_move_batch(struct rcu_data *this_rdp, struct rcu_head *list,
+                           struct rcu_head **tail)
+{
+    local_irq_disable();
+    *this_rdp->nxttail = list;
+    if (list)
+        this_rdp->nxttail = tail;
+    local_irq_enable();
+}
+
+static void rcu_offline_cpu(struct rcu_data *this_rdp,
+                            struct rcu_ctrlblk *rcp, struct rcu_data *rdp)
+{
+    /* If the cpu going offline owns the grace period we can block
+     * indefinitely waiting for it, so flush it here.
+     */
+    spin_lock(&rcp->lock);
+    if (rcp->cur != rcp->completed)
+        cpu_quiet(rdp->cpu, rcp);
+    spin_unlock(&rcp->lock);
+
+    rcu_move_batch(this_rdp, rdp->donelist, rdp->donetail);
+    rcu_move_batch(this_rdp, rdp->curlist, rdp->curtail);
+    rcu_move_batch(this_rdp, rdp->nxtlist, rdp->nxttail);
+
+    local_irq_disable();
+    this_rdp->qlen += rdp->qlen;
+    local_irq_enable();
+}
+
 static void rcu_init_percpu_data(int cpu, struct rcu_ctrlblk *rcp,
                                  struct rcu_data *rdp)
 {
@@ -339,14 +369,17 @@ static int cpu_callback(
     struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
     unsigned int cpu = (unsigned long)hcpu;
+    struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
 
     switch ( action )
     {
-    case CPU_UP_PREPARE: {
-        struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
+    case CPU_UP_PREPARE:
         rcu_init_percpu_data(cpu, &rcu_ctrlblk, rdp);
         break;
-    }
+    case CPU_UP_CANCELED:
+    case CPU_DEAD:
+        rcu_offline_cpu(&this_cpu(rcu_data), &rcu_ctrlblk, rdp);
+        break;
     default:
         break;
     }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.