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

[Xen-devel] [PATCH] xen, tools/python/xen: pincpu support vcpus, add vcpu to cpu map



The following patch updates the dom0 pincpu operation to read the VCPU
value from the xend interface rather than hard-coding the exec_domain to
0.  This prevented pinning VCPUS other than 0 to a particular cpu.  I
added the number of VCPUS to the main xm list output and also included a
new sub-option to xm list to display the VCPU to CPU mapping.  While
working on the pincpu code, I fixed an out-of-bounds indexing for the
pincpu operation that wasn't previously exposed since the
vcpu/exec_domain value was hard-coded to 0.

Here is some sample output of what the new sub-option looks like.

(hungerforce) root # xm list
Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)  Console
Domain-0           0      507    0      2   r----     30.4
debian_sarge_1     3      128    1      1   -b---     10.3     9603
debian_sarge_2     2      128    1      4   -b---      2.4     9602
(hungerforce) root # xm list --vcpus
Name              Id  VCPU  CPU
Domain-0           0     0    0
Domain-0           0     1    1
debian_sarge_1     3     0    1
debian_sarge_2     2     0    1
debian_sarge_2     2     1    0
debian_sarge_2     2     2    1
debian_sarge_2     2     3    0
(hungerforce) root # xm list -v 2
Name              Id  VCPU  CPU
debian_sarge_2     2     0    1
debian_sarge_2     2     1    0
debian_sarge_2     2     2    1
debian_sarge_2     2     3    0
(hungerforce) root # xm list -v 3
Name              Id  VCPU  CPU
debian_sarge_1     3     0    1
(hungerforce) root # xm pincpu 3 0 0
(hungerforce) root # xm list -v 3
Name              Id  VCPU  CPU
debian_sarge_1     3     0    0
(hungerforce) root # xm pincpu 3 1 1
Error: (22, 'Invalid argument')
(hungerforce) root # xm pincpu 3 33 0
Error: (22, 'Invalid argument')

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

diffstat output:
 tools/libxc/xc.h                          |    3 +
 tools/libxc/xc_domain.c                   |    6 ++-
 tools/python/xen/lowlevel/xc/xc.c         |   56 +++++++++++++++++-------------
 tools/python/xen/xend/XendClient.py       |    3 +
 tools/python/xen/xend/XendDomain.py       |   11 +++--
 tools/python/xen/xend/XendDomainInfo.py   |    3 +
 tools/python/xen/xend/server/SrvDomain.py |    1 
 tools/python/xen/xend/server/SrvUsbif.py  |    1 
 tools/python/xen/xm/main.py               |   45 ++++++++++++++++++------
 xen/common/dom0_ops.c                     |   12 ++++++
 xen/include/public/dom0_ops.h             |    2 +
 11 files changed, 101 insertions(+), 42 deletions(-)

Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx>
---
diff -urN a/tools/libxc/xc_domain.c c/tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c   2005-04-12 22:09:12.000000000 -0500
+++ c/tools/libxc/xc_domain.c   2005-04-13 12:21:01.000000000 -0500
@@ -64,12 +64,13 @@
 
 int xc_domain_pincpu(int xc_handle,
                      u32 domid, 
+                     int vcpu,
                      int cpu)
 {
     dom0_op_t op;
     op.cmd = DOM0_PINCPUDOMAIN;
     op.u.pincpudomain.domain = (domid_t)domid;
-    op.u.pincpudomain.exec_domain = 0;
+    op.u.pincpudomain.exec_domain = vcpu;
     op.u.pincpudomain.cpu  = cpu;
     return do_dom0_op(xc_handle, &op);
 }
@@ -112,6 +113,9 @@
         info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT);
         info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
         info->cpu_time = op.u.getdomaininfo.cpu_time;
+        info->vcpus = op.u.getdomaininfo.n_vcpu;
+        memcpy(info->vcpu_to_cpu, &op.u.getdomaininfo.vcpu_to_cpu, 
+               MAX_VIRT_CPUS*sizeof(u32));
 
         next_domid = (u16)op.u.getdomaininfo.domain + 1;
         info++;
diff -urN a/tools/libxc/xc.h c/tools/libxc/xc.h
--- a/tools/libxc/xc.h  2005-04-12 22:09:09.000000000 -0500
+++ c/tools/libxc/xc.h  2005-04-13 12:21:01.000000000 -0500
@@ -78,6 +78,7 @@
 typedef struct {
     u32           domid;
     unsigned int  cpu;
+    unsigned int  vcpus;
     unsigned int  dying:1, crashed:1, shutdown:1, 
                   paused:1, blocked:1, running:1;
     unsigned int  shutdown_reason; /* only meaningful if shutdown==1 */
@@ -85,6 +86,7 @@
     unsigned long shared_info_frame;
     u64           cpu_time;
     unsigned long max_memkb;
+    u32           vcpu_to_cpu[MAX_VIRT_CPUS];
 } xc_dominfo_t;
 
 typedef dom0_getdomaininfo_t xc_domaininfo_t;
@@ -128,6 +130,7 @@
                       u32 domid);
 int xc_domain_pincpu(int xc_handle,
                      u32 domid,
+                     int vcpu,
                      int cpu);
 /**
  * This function will return information about one or more domains.
diff -urN a/tools/python/xen/lowlevel/xc/xc.c 
c/tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c 2005-04-12 22:09:06.000000000 -0500
+++ c/tools/python/xen/lowlevel/xc/xc.c 2005-04-13 12:21:01.000000000 -0500
@@ -128,15 +128,16 @@
     XcObject *xc = (XcObject *)self;
 
     u32 dom;
+    int vcpu = 0;
     int cpu = -1;
 
-    static char *kwd_list[] = { "dom", "cpu", NULL };
+    static char *kwd_list[] = { "dom", "vcpu", "cpu", NULL };
 
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
-                                      &dom, &cpu) )
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list, 
+                                      &dom, &vcpu, &cpu) )
         return NULL;
 
-    if ( xc_domain_pincpu(xc->xc_handle, dom, cpu) != 0 )
+    if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, cpu) != 0 )
         return PyErr_SetFromErrno(xc_error);
     
     Py_INCREF(zero);
@@ -148,10 +149,10 @@
                                      PyObject *kwds)
 {
     XcObject *xc = (XcObject *)self;
-    PyObject *list;
+    PyObject *list, *vcpu_list, *info_dict;
 
     u32 first_dom = 0;
-    int max_doms = 1024, nr_doms, i;
+    int max_doms = 1024, nr_doms, i, j;
     xc_dominfo_t *info;
 
     static char *kwd_list[] = { "first_dom", "max_doms", NULL };
@@ -168,23 +169,28 @@
     list = PyList_New(nr_doms);
     for ( i = 0 ; i < nr_doms; i++ )
     {
-        PyList_SetItem(
-            list, i, 
-            Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
-                          ",s:l,s:L,s:l,s:i}",
-                          "dom",       info[i].domid,
-                          "cpu",       info[i].cpu,
-                          "dying",     info[i].dying,
-                          "crashed",   info[i].crashed,
-                          "shutdown",  info[i].shutdown,
-                          "paused",    info[i].paused,
-                          "blocked",   info[i].blocked,
-                          "running",   info[i].running,
-                          "mem_kb",    info[i].nr_pages*4,
-                          "cpu_time",  info[i].cpu_time,
-                          "maxmem_kb", info[i].max_memkb,
-                          "shutdown_reason", info[i].shutdown_reason
-                ));
+        vcpu_list = PyList_New(MAX_VIRT_CPUS);
+        for ( j = 0; j < MAX_VIRT_CPUS; j++ )
+            PyList_SetItem( vcpu_list, j, Py_BuildValue("i", 
info[i].vcpu_to_cpu[j]));
+                 
+        info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
+                                  ",s:l,s:L,s:l,s:i}",
+                                  "dom",       info[i].domid,
+                                  "cpu",       info[i].cpu,
+                                  "vcpus",     info[i].vcpus,
+                                  "dying",     info[i].dying,
+                                  "crashed",   info[i].crashed,
+                                  "shutdown",  info[i].shutdown,
+                                  "paused",    info[i].paused,
+                                  "blocked",   info[i].blocked,
+                                  "running",   info[i].running,
+                                  "mem_kb",    info[i].nr_pages*4,
+                                  "cpu_time",  info[i].cpu_time,
+                                  "maxmem_kb", info[i].max_memkb,
+                                  "shutdown_reason", info[i].shutdown_reason);
+        PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list );
+        PyList_SetItem( list, i, info_dict);
+ 
     }
 
     free(info);
@@ -895,6 +901,7 @@
       "         domain-id space was reached.\n"
       " dom      [int]: Identifier of domain to which this info pertains\n"
       " cpu      [int]:  CPU to which this domain is bound\n"
+      " vcpus    [int]:  Number of Virtual CPUS in this domain\n"
       " dying    [int]:  Bool - is the domain dying?\n"
       " crashed  [int]:  Bool - has the domain crashed?\n"
       " shutdown [int]:  Bool - has the domain shut itself down?\n"
@@ -905,7 +912,8 @@
       " maxmem_kb [int]: Maximum memory limit, in kilobytes\n"
       " cpu_time [long]: CPU time consumed, in nanoseconds\n"
       " shutdown_reason [int]: Numeric code from guest OS, explaining "
-      "reason why it shut itself down.\n" },
+      "reason why it shut itself down.\n" 
+      " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" },
 
     { "linux_save", 
       (PyCFunction)pyxc_linux_save, 
diff -urN a/tools/python/xen/xend/server/SrvDomain.py 
c/tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py 2005-04-12 22:09:10.000000000 
-0500
+++ c/tools/python/xen/xend/server/SrvDomain.py 2005-04-13 12:21:01.000000000 
-0500
@@ -92,6 +92,7 @@
     def op_pincpu(self, op, req):
         fn = FormFn(self.xd.domain_pincpu,
                     [['dom', 'str'],
+                     ['vcpu', 'int'],
                      ['cpu', 'int']])
         val = fn(req.args, {'dom': self.dom.id})
         return val
diff -urN a/tools/python/xen/xend/server/SrvUsbif.py 
c/tools/python/xen/xend/server/SrvUsbif.py
--- a/tools/python/xen/xend/server/SrvUsbif.py  2005-04-12 22:09:14.000000000 
-0500
+++ c/tools/python/xen/xend/server/SrvUsbif.py  2005-04-13 12:21:01.000000000 
-0500
@@ -107,6 +107,7 @@
     def op_pincpu(self, op, req):
         fn = FormFn(self.xd.domain_pincpu,
                     [['dom', 'str'],
+                     ['vcpu', 'int'],
                      ['cpu', 'int']])
         val = fn(req.args, {'dom': self.dom.id})
         return val
diff -urN a/tools/python/xen/xend/XendClient.py 
c/tools/python/xen/xend/XendClient.py
--- a/tools/python/xen/xend/XendClient.py       2005-04-12 22:09:04.000000000 
-0500
+++ c/tools/python/xen/xend/XendClient.py       2005-04-13 12:21:01.000000000 
-0500
@@ -246,9 +246,10 @@
                               'live'       : live,
                               'resource'   : resource })
 
-    def xend_domain_pincpu(self, id, cpu):
+    def xend_domain_pincpu(self, id, vcpu, cpu):
         return self.xendPost(self.domainurl(id),
                              {'op'      : 'pincpu',
+                              'vcpu'    : vcpu,
                               'cpu'     : cpu })
 
     def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, 
warpu):
diff -urN a/tools/python/xen/xend/XendDomainInfo.py 
c/tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   2005-04-12 22:09:06.000000000 
-0500
+++ c/tools/python/xen/xend/XendDomainInfo.py   2005-04-13 12:21:01.000000000 
-0500
@@ -372,6 +372,9 @@
                 sxpr.append(['shutdown_reason', reason])
             sxpr.append(['cpu', self.info['cpu']])
             sxpr.append(['cpu_time', self.info['cpu_time']/1e9])    
+            sxpr.append(['vcpus', self.info['vcpus']])
+            sxpr.append(['vcpu_to_cpu', ''.join(map(lambda x: str(x),
+                        self.info['vcpu_to_cpu'][0:self.info['vcpus']]))])
             
         if self.start_time:
             up_time =  time.time() - self.start_time  
diff -urN a/tools/python/xen/xend/XendDomain.py 
c/tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       2005-04-12 22:09:06.000000000 
-0500
+++ c/tools/python/xen/xend/XendDomain.py       2005-04-13 12:21:01.000000000 
-0500
@@ -610,15 +610,16 @@
         xmigrate = XendMigrate.instance()
         return xmigrate.save_begin(dominfo, dst)
     
-    def domain_pincpu(self, id, cpu):
-        """Pin a domain to a cpu.
+    def domain_pincpu(self, id, vcpu, cpu):
+        """Pin a vcpu in a domain to a cpu.
 
-        @param id: domain
-        @param cpu: cpu number
+        @param id:   domain
+        @param vcpu: vcpu number
+        @param cpu:  cpu number
         """
         dominfo = self.domain_lookup(id)
         try:
-            return xc.domain_pincpu(int(dominfo.id), cpu)
+            return xc.domain_pincpu(int(dominfo.id), vcpu, cpu)
         except Exception, ex:
             raise XendError(str(ex))
 
diff -urN a/tools/python/xen/xm/main.py c/tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       2005-04-12 22:09:11.000000000 -0500
+++ c/tools/python/xen/xm/main.py       2005-04-14 10:08:25.171199816 -0500
@@ -340,8 +340,8 @@
     name = "list"
     info = """List information about domains."""
 
-    short_options = 'l'
-    long_options = ['long']
+    short_options = 'lv'
+    long_options = ['long','vcpus']
 
     def help(self, args):
         if help:
@@ -350,11 +350,13 @@
             Either all domains or the domains given.
 
             -l, --long   Get more detailed information.
+            -v, --vcpus  Show VCPU to CPU mapping.
             """
             return
         
     def main(self, args):
         use_long = 0
+        show_vcpus = 0
         (options, params) = getopt(args[1:],
                                    self.short_options,
                                    self.long_options)
@@ -362,6 +364,8 @@
         for (k, v) in options:
             if k in ['-l', '--long']:
                 use_long = 1
+            if k in ['-v', '--vcpus']:
+                show_vcpus = 1
                 
         if n == 0:
             doms = server.xend_domains()
@@ -371,11 +375,13 @@
             
         if use_long:
             self.long_list(doms)
+        elif show_vcpus:
+            self.show_vcpus(doms)
         else:
             self.brief_list(doms)
 
     def brief_list(self, doms):
-        print 'Name              Id  Mem(MB)  CPU  State  Time(s)  Console'
+        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)  
Console'
         for dom in doms:
             info = server.xend_domain(dom)
             d = {}
@@ -383,6 +389,7 @@
             d['name'] = sxp.child_value(info, 'name', '??')
             d['mem'] = int(sxp.child_value(info, 'memory', '0'))
             d['cpu'] = int(sxp.child_value(info, 'cpu', '0'))
+            d['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
             d['state'] = sxp.child_value(info, 'state', '??')
             d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
             console = sxp.child(info, 'console')
@@ -390,9 +397,24 @@
                 d['port'] = sxp.child_value(console, 'console_port')
             else:
                 d['port'] = ''
-            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3d  %(state)5s  
%(cpu_time)7.1f    %(port)4s"
+            print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3d  %(vcpus)5d   
%(state)5s  %(cpu_time)7.1f     %(port)4s"
                    % d)
 
+    def show_vcpus(self, doms):
+        print 'Name              Id  VCPU  CPU'
+        for dom in doms:
+            info = server.xend_domain(dom)
+            vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', 
'?').replace('-','')
+            count = 0
+            for cpu in vcpu_to_cpu:
+                d = {}
+                d['name'] = sxp.child_value(info, 'name', '??')
+                d['dom']  = int(sxp.child_value(info, 'id', '-1'))
+                d['vcpu'] = int(count)
+                d['cpu']  = int(cpu)
+                count = count + 1
+                print ("%(name)-16s %(dom)3d  %(vcpu)4d  %(cpu)3d" % d)
+
     def long_list(self, doms):
         for dom in doms:
             info = server.xend_domain(dom)
@@ -474,17 +496,18 @@
 class ProgPincpu(Prog):
     group = 'domain'
     name = "pincpu"
-    info = """Pin a domain to a cpu. """
+    info = """Pin a vcpu to a cpu. """
 
     def help(self, args):
-        print args[0],'DOM CPU'
-        print '\nPin domain DOM to cpu CPU.'
+        print args[0],'DOM VCPU CPU'
+        print '\nPin vcpu VCPU in domain DOM to cpu CPU.'
 
     def main(self, args):
-        if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
-        dom = args[1]
-        cpu = int(args[2])
-        server.xend_domain_pincpu(dom, cpu)
+        if len(args) != 4: self.err("%s: Invalid argument(s)" % args[0])
+        dom  = args[1]
+        vcpu = int(args[2])
+        cpu  = int(args[3])
+        server.xend_domain_pincpu(dom, vcpu, cpu)
 
 xm.prog(ProgPincpu)
 
diff -urN a/xen/common/dom0_ops.c c/xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c     2005-04-12 22:09:06.000000000 -0500
+++ c/xen/common/dom0_ops.c     2005-04-13 13:22:42.000000000 -0500
@@ -242,6 +242,13 @@
             break;
         }
         
+        if ( (op->u.pincpudomain.exec_domain >= MAX_VIRT_CPUS) ||
+             !d->exec_domain[op->u.pincpudomain.exec_domain] )
+        {
+            ret = -EINVAL;
+            break;
+        }
+
         ed = d->exec_domain[op->u.pincpudomain.exec_domain];
         if ( ed == NULL )
         {
@@ -321,6 +328,10 @@
             break;
         }
         
+        memset(&op->u.getdomaininfo.vcpu_to_cpu,-1,MAX_VIRT_CPUS*sizeof(u8));
+        for_each_exec_domain ( d, ed )
+            op->u.getdomaininfo.vcpu_to_cpu[ed->eid] = ed->processor;
+
         ed = d->exec_domain[op->u.getdomaininfo.exec_domain];
 
         op->u.getdomaininfo.flags =
@@ -338,6 +349,7 @@
         op->u.getdomaininfo.tot_pages   = d->tot_pages;
         op->u.getdomaininfo.max_pages   = d->max_pages;
         op->u.getdomaininfo.cpu_time    = ed->cpu_time;
+        op->u.getdomaininfo.n_vcpu      = d->shared_info->n_vcpu;
         op->u.getdomaininfo.shared_info_frame = 
             __pa(d->shared_info) >> PAGE_SHIFT;
 
diff -urN a/xen/include/public/dom0_ops.h c/xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     2005-04-12 22:09:12.000000000 -0500
+++ c/xen/include/public/dom0_ops.h     2005-04-13 12:21:01.000000000 -0500
@@ -92,6 +92,8 @@
     memory_t max_pages;
     memory_t shared_info_frame;       /* MFN of shared_info struct */
     u64      cpu_time;
+    u32      n_vcpu;
+    u32      vcpu_to_cpu[MAX_VIRT_CPUS];
 } dom0_getdomaininfo_t;
 
 #define DOM0_SETDOMAININFO      13

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


 


Rackspace

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