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

[Xen-devel] [PATCH] 1/2 VCPU creation and allocation



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


 


Rackspace

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