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

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

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] 1/2 VCPU creation and allocation
From: Ryan Harper <ryanh@xxxxxxxxxx>
Date: Mon, 10 Oct 2005 10:18:42 -0500
Delivery-date: Mon, 10 Oct 2005 15:16:10 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.6+20040907i
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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] 1/2 VCPU creation and allocation, Ryan Harper <=