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
|