WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH][RESUBMIT] add dom0 vcpu hotplug control

To: Christian.Limpach@xxxxxxxxxxxx
Subject: Re: [Xen-devel] [PATCH][RESUBMIT] add dom0 vcpu hotplug control
From: Ryan Harper <ryanh@xxxxxxxxxx>
Date: Wed, 22 Jun 2005 16:01:00 -0500
Cc: Ryan Harper <ryanh@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Wed, 22 Jun 2005 21:00:04 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <3d8eece205062104023b62ebe3@xxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20050607220246.GD28421@xxxxxxxxxx> <20050614163718.GB7954@xxxxxxxxxx> <3d8eece205062104023b62ebe3@xxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.6+20040907i
* Christian Limpach <christian.limpach@xxxxxxxxx> [2005-06-21 09:11]:
> On 6/14/05, Ryan Harper <ryanh@xxxxxxxxxx> wrote:
> > * Ryan Harper <ryanh@xxxxxxxxxx> [2005-06-07 17:05]:
> > > This patch adds new control messages for vcpu hotplug events.  Via the
> > > xm vcpu_hotplug sub-program, VCPUS in domains can be enabled/disabled
> > > when CONFIG_HOTPLUG_CPU is enabled in the target domain's kernel.
> > >
> > 
> > Updated this patch to use vcpu_to_cpu up/down info to control whether
> > state changes are sent when hotplugging vcpus.
> 
> I've applied both patches.  I think there's a flaw in the way how
> vcpu_to_cpu gets passed up to python, the -1 -> # hack is kind of
> gross and it won't work for cpus > 9?

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.

-- 
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253   T/L: 678-9253
ryanh@xxxxxxxxxx


diffstat output:
 linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c |   19 +++++++---
 linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c       |   32 +++++++++++++++++
 tools/python/xen/xend/XendDomainInfo.py                |    6 ++-
 tools/python/xen/xm/main.py                            |   18 +--------
 xen/common/event_channel.c                             |   29 +++++++++++++++
 xen/include/public/event_channel.h                     |   10 ++++-
 6 files changed, 91 insertions(+), 23 deletions(-)

Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx>
---
diff -urN b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c 
c/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c
--- b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    2005-06-21 
22:10:55.000000000 -0500
+++ c/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/smpboot.c    2005-06-22 
14:31:48.765503988 -0500
@@ -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 -urN b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c 
c/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c
--- b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c  2005-06-21 
22:10:53.000000000 -0500
+++ c/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c  2005-06-22 
14:31:48.767503708 -0500
@@ -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 -urN b/tools/python/xen/xend/XendDomainInfo.py 
c/tools/python/xen/xend/XendDomainInfo.py
--- b/tools/python/xen/xend/XendDomainInfo.py   2005-06-21 22:10:54.000000000 
-0500
+++ c/tools/python/xen/xend/XendDomainInfo.py   2005-06-22 14:31:48.000000000 
-0500
@@ -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 -urN b/tools/python/xen/xm/main.py c/tools/python/xen/xm/main.py
--- b/tools/python/xen/xm/main.py       2005-06-21 22:10:53.000000000 -0500
+++ c/tools/python/xen/xm/main.py       2005-06-22 14:54:50.810258798 -0500
@@ -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)
 
diff -urN b/xen/common/event_channel.c c/xen/common/event_channel.c
--- b/xen/common/event_channel.c        2005-06-21 22:10:55.000000000 -0500
+++ c/xen/common/event_channel.c        2005-06-22 14:55:20.936237917 -0500
@@ -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)
 {
@@ -637,6 +660,12 @@
             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;
+
     default:
         rc = -ENOSYS;
         break;
diff -urN b/xen/include/public/event_channel.h 
c/xen/include/public/event_channel.h
--- b/xen/include/public/event_channel.h        2005-06-21 22:10:55.000000000 
-0500
+++ c/xen/include/public/event_channel.h        2005-06-22 14:31:48.801498950 
-0500
@@ -162,6 +162,13 @@
     } PACKED u;
 } PACKED evtchn_status_t; /* 20 bytes */
 
+#define EVTCHNOP_rebind        8
+typedef struct {
+    /* IN parameters. */
+    u32 port;                         /*  0 */
+    u32 vcpu;                         /*  4 */
+} PACKED evtchn_rebind_t; /* 8 bytes */
+
 typedef struct {
     u32 cmd; /* EVTCHNOP_* */         /*  0 */
     u32 __reserved;                   /*  4 */
@@ -174,7 +181,8 @@
         evtchn_close_t            close;
         evtchn_send_t             send;
         evtchn_status_t           status;
-        u8                        __dummy[24];
+        evtchn_rebind_t           rebind;
+        u8                        __dummy[16];
     } PACKED u;
 } PACKED evtchn_op_t; /* 32 bytes */
 

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