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

[Xen-changelog] I updated the vcpu_to_cpu string creation to include a field separator,



# HG changeset patch
# User iap10@xxxxxxxxxxxxxxxxxxxxx
# Node ID 88c2d410979f572a074c14e3423c9e1de63e57bb
# Parent  32fb371cc283f4e146f2a23241a2287510fb78b2



I updated the vcpu_to_cpu string creation to include a field separator,
which gets rid of the -1 -> # hack and works for cpus > 9.

I ran into some issues with stale vcpu_to_cpu lists when running the
hotplug subprogram.  I would take a vcpu offline, and then issue the
command to bring it back and the vcpu_to_cpu list would not have changed
to indicate the the vcpu actually went down.  If I injected a xm list -v
(which always showed the correct mapping) then subsequent hotplug
commands would see the state change and fire off the hotplug request.  I
don't know that not sending the event when not changing state saves that
much work so I took the state check out and now just send the hotplug
event directly.

> Also the whole hotplug stuff is still missing interrupt re-routing
> when a vcpu is taken down.  To do this, we need an evtchn operation to
> change the vcpu affinity of a port by changing notify_vcpu_id.

I don't fully understand all of the mappings that are happening, so this
part of the patch might be way off.  In any case, I've added a new
evtchn op to set the notify_vcpu_id field of a channel.  I updated the
HOTPLUG_CPU code to use the new routines when bringing cpus up and down.
When taking down a cpu, I route the IPI irq channels to CPU 0, and when
the cpu comes up, it re-routes the channels back to the awakened CPU.

From: Ryan Harper <ryanh@xxxxxxxxxx>
Signed-off-by: ian@xxxxxxxxxxxxx

diff -r 32fb371cc283 -r 88c2d410979f xen/common/event_channel.c
--- a/xen/common/event_channel.c        Wed Jul  6 18:57:54 2005
+++ b/xen/common/event_channel.c        Wed Jul  6 22:23:18 2005
@@ -579,6 +579,29 @@
     return rc;
 }
 
+static long evtchn_rebind(evtchn_rebind_t *bind) 
+{
+    struct domain *d    = current->domain;
+    int            port = bind->port;
+    int            vcpu = bind->vcpu;
+    struct evtchn *chn;
+    long             rc = 0;
+
+    spin_lock(&d->evtchn_lock);
+
+    if ( !port_is_valid(d, port) )
+    {
+        rc = -EINVAL;
+        goto out;
+    }
+
+    chn = evtchn_from_port(d, port);
+    chn->notify_vcpu_id = vcpu;
+
+ out:
+    spin_unlock(&d->evtchn_lock);
+    return rc;
+}
 
 long do_event_channel_op(evtchn_op_t *uop)
 {
@@ -633,6 +656,12 @@
 
     case EVTCHNOP_status:
         rc = evtchn_status(&op.u.status);
+        if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
+            rc = -EFAULT;
+        break;
+
+    case EVTCHNOP_rebind:
+        rc = evtchn_rebind(&op.u.rebind);
         if ( (rc == 0) && (copy_to_user(uop, &op, sizeof(op)) != 0) )
             rc = -EFAULT;
         break;
diff -r 32fb371cc283 -r 88c2d410979f 
linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c  Wed Jul  6 18:57:54 2005
+++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c  Wed Jul  6 22:23:18 2005
@@ -271,6 +271,38 @@
     return irq;
 }
 
+void rebind_evtchn_from_ipi(int cpu, int newcpu, int ipi)
+{
+    evtchn_op_t op;
+    int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
+
+    spin_lock(&irq_mapping_update_lock);
+
+    op.cmd          = EVTCHNOP_rebind;
+    op.u.rebind.port = evtchn;
+    op.u.rebind.vcpu = newcpu;
+    if ( HYPERVISOR_event_channel_op(&op) != 0 )
+       printk(KERN_INFO "Failed to rebind IPI%d to CPU%d\n",ipi,newcpu);
+
+    spin_unlock(&irq_mapping_update_lock);
+}
+
+void rebind_evtchn_from_irq(int cpu, int newcpu, int irq)
+{
+    evtchn_op_t op;
+    int evtchn = irq_to_evtchn[irq];
+
+    spin_lock(&irq_mapping_update_lock);
+
+    op.cmd          = EVTCHNOP_rebind;
+    op.u.rebind.port = evtchn;
+    op.u.rebind.vcpu = newcpu;
+    if ( HYPERVISOR_event_channel_op(&op) != 0 )
+       printk(KERN_INFO "Failed to rebind IRQ%d to CPU%d\n",irq,newcpu);
+
+    spin_unlock(&irq_mapping_update_lock);
+}
+
 void unbind_ipi_on_cpu_from_irq(int cpu, int ipi)
 {
     evtchn_op_t op;
diff -r 32fb371cc283 -r 88c2d410979f tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Jul  6 18:57:54 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Jul  6 22:23:18 2005
@@ -423,8 +423,10 @@
             sxpr.append(['cpu_time', self.info['cpu_time']/1e9])    
             sxpr.append(['vcpus', self.info['vcpus']])
             sxpr.append(['cpumap', self.info['cpumap']])
-            sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x),
-                        self.info['vcpu_to_cpu'][0:self.info['vcpus']]))])
+            # build a string, using '|' to seperate items, show only up
+            # to number of vcpus in domain, and trim the trailing '|'
+            sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x)+'|',
+                        self.info['vcpu_to_cpu'][0:self.info['vcpus']]))[:-1]])
             
         if self.start_time:
             up_time =  time.time() - self.start_time  
diff -r 32fb371cc283 -r 88c2d410979f xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h        Wed Jul  6 18:57:54 2005
+++ b/xen/include/public/event_channel.h        Wed Jul  6 22:23:18 2005
@@ -158,6 +158,13 @@
     } u;
 } evtchn_status_t;
 
+#define EVTCHNOP_rebind        8
+typedef struct {
+    /* IN parameters. */
+    u32 port;                         /*  0 */
+    u32 vcpu;                         /*  4 */
+} evtchn_rebind_t; /* 8 bytes */
+
 typedef struct evtchn_op {
     u32 cmd; /* EVTCHNOP_* */
     union {
@@ -169,6 +176,7 @@
         evtchn_close_t            close;
         evtchn_send_t             send;
         evtchn_status_t           status;
+        evtchn_rebind_t           rebind;
     } u;
 } evtchn_op_t;
 
diff -r 32fb371cc283 -r 88c2d410979f 
linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    Wed Jul  6 
18:57:54 2005
+++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    Wed Jul  6 
22:23:18 2005
@@ -103,6 +103,11 @@
 DEFINE_PER_CPU(int, cpu_state) = { 0 };
 #endif
 
+static DEFINE_PER_CPU(int, resched_irq);
+static DEFINE_PER_CPU(int, callfunc_irq);
+static char resched_name[NR_CPUS][15];
+static char callfunc_name[NR_CPUS][15];
+
 #if 0
 /*
  * Currently trivial. Write the real->protected mode
@@ -1328,6 +1333,10 @@
        while (!cpu_online(cpu))
                cpu_relax();
 
+   /* re-route bound IRQs 0 to cpu */
+   rebind_evtchn_from_irq(0, cpu,  per_cpu(resched_irq, cpu));
+   rebind_evtchn_from_irq(0, cpu, per_cpu(callfunc_irq, cpu));
+
        fixup_irqs(cpu_online_map);
        /* counter the disable in fixup_irqs() */
        local_irq_enable();
@@ -1357,6 +1366,11 @@
 
        cpu_clear(cpu, map);
        fixup_irqs(map);
+
+   /* re-route IRQs from dead vcpu to another */
+   rebind_evtchn_from_irq(cpu, 0,  per_cpu(resched_irq, cpu));
+   rebind_evtchn_from_irq(cpu, 0, per_cpu(callfunc_irq, cpu));
+
        /* It's now safe to remove this processor from the online map */
        cpu_clear(cpu, cpu_online_map);
 
@@ -1514,11 +1528,6 @@
 extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *);
 extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *);
 
-static DEFINE_PER_CPU(int, resched_irq);
-static DEFINE_PER_CPU(int, callfunc_irq);
-static char resched_name[NR_CPUS][15];
-static char callfunc_name[NR_CPUS][15];
-
 void __init smp_intr_init(void)
 {
        int cpu = smp_processor_id();
diff -r 32fb371cc283 -r 88c2d410979f tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Wed Jul  6 18:57:54 2005
+++ b/tools/python/xen/xm/main.py       Wed Jul  6 22:23:18 2005
@@ -410,8 +410,7 @@
         print 'Name              Id  VCPU  CPU  CPUMAP'
         for dom in doms:
             info = server.xend_domain(dom)
-            # XXX this is quite broken for cpu's > 9
-            vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', 
'?').replace('-1','#')
+            vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', '-1').split('|')
             cpumap = sxp.child_value(info, 'cpumap', [])
             mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1
             count = 0
@@ -420,10 +419,7 @@
                 d['name']   = sxp.child_value(info, 'name', '??')
                 d['dom']    = int(sxp.child_value(info, 'id', '-1'))
                 d['vcpu']   = int(count)
-                if cpu == "#":
-                    d['cpu']    = int("-1")
-                else:
-                    d['cpu']    = int(cpu)
+                d['cpu']    = int(cpu)
                 d['cpumap'] = int(cpumap[count])&mask
                 count = count + 1
                 print ("%(name)-16s %(dom)3d  %(vcpu)4d  %(cpu)3d  
0x%(cpumap)x" % d)
@@ -593,15 +589,7 @@
         state = int(args[3])
         dom = server.xend_domain(name)
         id = sxp.child_value(dom, 'id')
-        vcpu_to_cpu = sxp.child_value(dom, 'vcpu_to_cpu', '-1')
-        # only send state change if states differ 
-        try:
-            # (down going up) or (up going down)
-            if (vcpu_to_cpu[vcpu] == "-1" and state == 1) or \
-               (vcpu_to_cpu[vcpu] != "-1" and state == 0):
-                server.xend_domain_vcpu_hotplug(id, vcpu, state)
-        except IndexError:
-            print "Invalid VCPU(%d)"%(vcpu)
+        server.xend_domain_vcpu_hotplug(id, vcpu, state)
 
 xm.prog(ProgVcpuhotplug)
 

_______________________________________________
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®.