New dom0_op, set_max_vcpus, and VCPUOP_create split from
VCPUOP_initialize.
--
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_domain.c | 22 ++++++++++++
tools/libxc/xenctrl.h | 25 ++++++++++++++
tools/python/xen/lowlevel/xc/xc.c | 56 ++++++++++++++++++++++++++++++++
tools/python/xen/xend/XendDomainInfo.py | 6 +++
xen/arch/x86/domain_build.c | 7 ++++
xen/common/dom0_ops.c | 14 ++++++++
xen/common/domain.c | 45 +++++++++++++++++--------
xen/include/public/dom0_ops.h | 8 ++++
xen/include/public/vcpu.h | 11 +++++-
xen/include/xen/domain.h | 2 +
xen/include/xen/sched.h | 2 +
11 files changed, 182 insertions(+), 16 deletions(-)
Signed-off-by: Ryan Harper <ryanh@xxxxxxxxxx>
---
diff -r b7dce4fe2488 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Mon Oct 10 10:37:10 2005
+++ b/tools/libxc/xc_domain.c Mon Oct 10 09:01:25 2005
@@ -8,6 +8,7 @@
#include "xc_private.h"
#include <xen/memory.h>
+#include <xen/vcpu.h>
int xc_domain_create(int xc_handle,
u32 ssidref,
@@ -329,6 +330,27 @@
return err;
}
+int xc_set_max_vcpus(int xc_handle, u32 domid, unsigned int max_vcpus)
+{
+ dom0_op_t op;
+ op.cmd = DOM0_SET_MAX_VCPUS;
+ op.u.set_max_vcpus.domain = (domid_t)domid;
+ op.u.set_max_vcpus.max_vcpus = (u8)max_vcpus;
+ return do_dom0_op(xc_handle, &op);
+}
+
+int xc_vcpu_create(int xc_handle, u32 domid, unsigned int vcpuid)
+{
+ privcmd_hypercall_t hypercall;
+
+ hypercall.op = __HYPERVISOR_vcpu_op;
+ hypercall.arg[0] = (unsigned long)VCPUOP_create;
+ hypercall.arg[1] = (unsigned long)vcpuid;
+ hypercall.arg[2] = (unsigned long)domid;
+
+ return do_xen_hypercall(xc_handle, &hypercall);
+}
+
/*
* Local variables:
* mode: C
diff -r b7dce4fe2488 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Mon Oct 10 10:37:10 2005
+++ b/tools/libxc/xenctrl.h Mon Oct 10 09:01:25 2005
@@ -152,6 +152,31 @@
u32 ssidref,
u32 *pdomid);
+/*
+ * This function sets the maximum number of vcpus a domain is allow to use.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain id in which vcpus are to be created
+ * @parm max_vcpus the max number of vcpus a domain is allow to use.
+ * @return 0 on success, -1 on failure.
+ */
+int xc_set_max_vcpus(int xc_handle,
+ u32 domid,
+ unsigned int max_vcpus);
+
+/*
+ * This function creates an additional vcpus for a domain. Note that
+ * the maximum vcpus needs to be increased (default is 1) before
+ * requesting additional vcpus.
+ *
+ * @parm xc_handle a handle to an open hypervisor interface
+ * @parm domid the domain id in which vcpus are to be created
+ * @parm vcpuid the vcpuid of the new vcpu.
+ * @return 0 on success, -1 on failure.
+ */
+int xc_vcpu_create(int xc_handle,
+ u32 domid,
+ unsigned int vcpuid);
int xc_domain_dumpcore(int xc_handle,
u32 domid,
diff -r b7dce4fe2488 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon Oct 10 10:37:10 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Oct 10 09:01:25 2005
@@ -91,6 +91,46 @@
return PyErr_SetFromErrno(xc_error);
return PyInt_FromLong(dom);
+}
+
+static PyObject *pyxc_vcpu_create(PyObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ XcObject *xc = (XcObject *)self;
+
+ u32 dom, vcpu;
+
+ static char *kwd_list[] = { "dom", "vcpu", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, &dom, &vcpu)
)
+ return NULL;
+
+ if ( xc_vcpu_create(xc->xc_handle, dom, vcpu) != 0 )
+ return PyErr_SetFromErrno(xc_error);
+
+ Py_INCREF(zero);
+ return zero;
+}
+
+static PyObject *pyxc_set_max_vcpus(PyObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ XcObject *xc = (XcObject *)self;
+
+ u32 dom, max_vcpu;
+
+ static char *kwd_list[] = { "dom", "max_vcpu", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, &dom,
&max_vcpu) )
+ return NULL;
+
+ if ( xc_set_max_vcpus(xc->xc_handle, dom, max_vcpu) != 0 )
+ return PyErr_SetFromErrno(xc_error);
+
+ Py_INCREF(zero);
+ return zero;
}
static PyObject *pyxc_domain_pause(PyObject *self,
@@ -783,6 +823,22 @@
" dom [int, 0]: Domain identifier to use (allocated if
zero).\n"
"Returns: [int] new domain identifier; -1 on error.\n" },
+ { "vcpu_create",
+ (PyCFunction)pyxc_vcpu_create,
+ METH_VARARGS | METH_KEYWORDS, "\n"
+ "Create a new vcpu in domain.\n"
+ " dom [int, 0]: Domain identifier to use.\n"
+ " vcpu [int, 0]: Vcpu identifier to create.\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
+
+ { "set_max_vcpus",
+ (PyCFunction)pyxc_set_max_vcpus,
+ METH_VARARGS | METH_KEYWORDS, "\n"
+ "Set the maximum number of vcpus allowed in a domain.\n"
+ " dom [int, 0]: Domain identifier to use.\n"
+ " max_vcpus [int, 0]: Max number of vcpus allowed.\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
+
{ "domain_dumpcore",
(PyCFunction)pyxc_domain_dumpcore,
METH_VARARGS | METH_KEYWORDS, "\n"
diff -r b7dce4fe2488 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon Oct 10 10:37:10 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Oct 10 09:01:25 2005
@@ -1018,6 +1018,12 @@
self.image.handleBootloading()
xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
+
+ # set the max, and allocate additional vcpus
+ xc.set_max_vcpus(self.domid, self.info['vcpus']);
+ for v in range(1,int(self.info['vcpus'])):
+ xc.vcpu_create(self.domid, v)
+
# XXX Merge with configure_maxmem?
m = self.image.getDomainMemory(self.info['memory_KiB'])
xc.domain_setmaxmem(self.domid, m)
diff -r b7dce4fe2488 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Mon Oct 10 10:37:10 2005
+++ b/xen/arch/x86/domain_build.c Mon Oct 10 09:01:25 2005
@@ -14,6 +14,7 @@
#include <xen/event.h>
#include <xen/elf.h>
#include <xen/kernel.h>
+#include <xen/domain.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -559,6 +560,12 @@
d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
d->shared_info->n_vcpu = num_online_cpus();
+ /* up max_vcpus and create extra vcpus */
+ d->max_vcpus = num_online_cpus();
+ if ( (d->shared_info->n_vcpu > 1) )
+ for ( i = 1; i < d->shared_info->n_vcpu; i++ )
+ boot_vcpu(d, i);
+
/* Set up monitor table */
update_pagetables(v);
diff -r b7dce4fe2488 xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c Mon Oct 10 10:37:10 2005
+++ b/xen/common/dom0_ops.c Mon Oct 10 09:01:25 2005
@@ -521,6 +521,20 @@
}
break;
+ case DOM0_SET_MAX_VCPUS:
+ {
+ struct domain *d;
+ ret = -ESRCH;
+ d = find_domain_by_id(op->u.set_max_vcpus.domain);
+ if ( d != NULL )
+ {
+ d->max_vcpus = op->u.set_max_vcpus.max_vcpus;
+ put_domain(d);
+ ret = 0;
+ }
+ }
+ break;
+
#ifdef PERF_COUNTERS
case DOM0_PERFCCONTROL:
{
diff -r b7dce4fe2488 xen/common/domain.c
--- a/xen/common/domain.c Mon Oct 10 10:37:10 2005
+++ b/xen/common/domain.c Mon Oct 10 09:01:25 2005
@@ -44,6 +44,10 @@
d->domain_id = dom_id;
v->processor = cpu;
+ /* default max_vcpus is set to 1, further vcpu allocation is prevented
+ * without updating via priviledged MAX_VCPUS VCPU_OP. */
+ d->max_vcpus = 1;
+
spin_lock_init(&d->big_lock);
spin_lock_init(&d->page_alloc_lock);
@@ -368,10 +372,9 @@
return rc;
}
-int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt)
-{
- struct vcpu *v;
- int rc;
+int boot_vcpu(struct domain *d, int vcpuid)
+{
+ struct vcpu *v;
ASSERT(d->vcpu[vcpuid] == NULL);
@@ -387,20 +390,11 @@
arch_do_boot_vcpu(v);
- if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
- goto out;
-
sched_add_domain(v);
set_bit(_VCPUF_down, &v->vcpu_flags);
- clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
return 0;
-
- out:
- arch_free_vcpu_struct(d->vcpu[vcpuid]);
- d->vcpu[vcpuid] = NULL;
- return rc;
}
long do_vcpu_op(int cmd, int vcpuid, void *arg)
@@ -408,16 +402,33 @@
struct domain *d = current->domain;
struct vcpu *v;
struct vcpu_guest_context *ctxt;
+ domid_t domid;
long rc = 0;
if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
return -EINVAL;
- if ( ((v = d->vcpu[vcpuid]) == NULL) && (cmd != VCPUOP_initialise) )
+ if ( ((v = d->vcpu[vcpuid]) == NULL) && (cmd != VCPUOP_create) )
return -ENOENT;
switch ( cmd )
{
+ case VCPUOP_create:
+ /* get correct domain pointer if we are creating vcpus. */
+ domid = (domid_t)(unsigned long)arg;
+ if ( (d = find_domain_by_id(domid)) == NULL )
+ return -ESRCH;
+
+ rc = -EINVAL;
+ if ( vcpuid < d->max_vcpus ) {
+ LOCK_BIGLOCK(d);
+ rc = (d->vcpu[vcpuid] == NULL) ? boot_vcpu(d, vcpuid) : -EEXIST;
+ UNLOCK_BIGLOCK(d);
+ }
+
+ put_domain(d);
+ break;
+
case VCPUOP_initialise:
if ( (ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
{
@@ -433,7 +444,11 @@
}
LOCK_BIGLOCK(d);
- rc = (d->vcpu[vcpuid] == NULL) ? boot_vcpu(d, vcpuid, ctxt) : -EEXIST;
+ clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags);
+ if ( (rc = arch_set_info_guest(v, ctxt)) != 0 ) {
+ arch_free_vcpu_struct(d->vcpu[vcpuid]);
+ d->vcpu[vcpuid] = NULL;
+ }
UNLOCK_BIGLOCK(d);
xfree(ctxt);
diff -r b7dce4fe2488 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h Mon Oct 10 10:37:10 2005
+++ b/xen/include/public/dom0_ops.h Mon Oct 10 09:01:25 2005
@@ -386,6 +386,13 @@
int is_ram;
} *memory_map;
} dom0_physical_memory_map_t;
+
+#define DOM0_SET_MAX_VCPUS 41
+typedef struct {
+ domid_t domain; /* domain to be affected */
+ u8 max_vcpus; /* new max_vcpus value */
+} dom0_set_max_vcpus_t;
+
typedef struct {
u32 cmd;
@@ -422,6 +429,7 @@
dom0_getdomaininfolist_t getdomaininfolist;
dom0_platform_quirk_t platform_quirk;
dom0_physical_memory_map_t physical_memory_map;
+ dom0_set_max_vcpus_t set_max_vcpus;
} u;
} dom0_op_t;
diff -r b7dce4fe2488 xen/include/public/vcpu.h
--- a/xen/include/public/vcpu.h Mon Oct 10 10:37:10 2005
+++ b/xen/include/public/vcpu.h Mon Oct 10 09:01:25 2005
@@ -1,7 +1,7 @@
/******************************************************************************
* vcpu.h
*
- * VCPU initialisation, query, and hotplug.
+ * VCPU creation, initialisation, query, and hotplug.
*
* Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx>
*/
@@ -51,4 +51,13 @@
/* Returns 1 if the given VCPU is up. */
#define VCPUOP_is_up 3
+/*
+ * Allocate vcpu structures and prepare for ctxt initialization. A newly
+ * created VCPU needs to be initialized with VCPUOP_initialize
+ * before being brought up by VCPUOP_up.
+ *
+ * @extra_arg == domid of domain to create vcpus in
+ */
+#define VCPUOP_create 4
+
#endif /* __XEN_PUBLIC_VCPU_H__ */
diff -r b7dce4fe2488 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h Mon Oct 10 10:37:10 2005
+++ b/xen/include/xen/domain.h Mon Oct 10 09:01:25 2005
@@ -1,6 +1,8 @@
#ifndef __XEN_DOMAIN_H__
#define __XEN_DOMAIN_H__
+
+extern int boot_vcpu(struct domain *d, int vcpuid);
/*
* Arch-specifics.
diff -r b7dce4fe2488 xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Mon Oct 10 10:37:10 2005
+++ b/xen/include/xen/sched.h Mon Oct 10 09:01:25 2005
@@ -130,6 +130,8 @@
atomic_t refcnt;
+ /* max num vcpus allowed */
+ u8 max_vcpus;
struct vcpu *vcpu[MAX_VIRT_CPUS];
/* Bitmask of CPUs which are holding onto this domain's state. */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|