Remove the free_vcpu() interface I added in the preceding
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 14 Jan 2006 22:40:09 +0000 (23:40 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 14 Jan 2006 22:40:09 +0000 (23:40 +0100)
changeset. It makes no sense, since an allocated VCPU
cannot be freed at any arbitrary point because individual
VCPUs are not refcounted.

Instead extend free_domain() slightly so it really does do
the reverse of alloc_vcpu() for every allocated VCPU.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/common/domain.c
xen/common/schedule.c
xen/include/xen/sched.h

index de4f6c3f79f463914eba20418681b631dfb75cd6..bc6eebe41c17dc362bfb7bad5d7e1b9f895bcbab 100644 (file)
@@ -66,7 +66,7 @@ struct domain *domain_create(domid_t dom_id, unsigned int cpu)
     d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
     d->irq_caps   = rangeset_new(d, "Interrupts", 0);
     if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
-        goto fail5;
+        goto fail4; /* NB. alloc_vcpu() is undone in free_domain() */
 
     if ( !is_idle_domain(d) )
     {
@@ -84,8 +84,6 @@ struct domain *domain_create(domid_t dom_id, unsigned int cpu)
 
     return d;
 
- fail5:
-    free_vcpu(v);
  fail4:
     arch_domain_destroy(d);
  fail3:
index f2815d7d9ffc59813cb425ee6163cc3076578d35..94b40559da540d142c897bf5c204996ae1dd8bc4 100644 (file)
@@ -73,15 +73,29 @@ static struct scheduler ops;
 /* Per-CPU periodic timer sends an event to the currently-executing domain. */
 static struct timer t_timer[NR_CPUS]; 
 
+struct domain *alloc_domain(void)
+{
+    struct domain *d;
+
+    if ( (d = xmalloc(struct domain)) != NULL )
+        memset(d, 0, sizeof(*d));
+
+    return d;
+}
+
 void free_domain(struct domain *d)
 {
+    struct vcpu *v;
     int i;
 
+    for_each_vcpu ( d, v )
+        sched_rem_domain(v);
+
     SCHED_OP(free_task, d);
 
     for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- )
-        if ( d->vcpu[i] != NULL )
-            free_vcpu_struct(d->vcpu[i]);
+        if ( (v = d->vcpu[i]) != NULL )
+            free_vcpu_struct(v);
 
     xfree(d);
 }
@@ -105,46 +119,24 @@ struct vcpu *alloc_vcpu(
     v->cpu_affinity = is_idle_domain(d) ?
         cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
 
-    d->vcpu[vcpu_id] = v;
+    if ( (vcpu_id != 0) && !is_idle_domain(d) )
+        set_bit(_VCPUF_down, &v->vcpu_flags);
 
     if ( SCHED_OP(alloc_task, v) < 0 )
     {
-        d->vcpu[vcpu_id] = NULL;
         free_vcpu_struct(v);
         return NULL;
     }
 
-    sched_add_domain(v);
-
+    d->vcpu[vcpu_id] = v;
     if ( vcpu_id != 0 )
-    {
         d->vcpu[v->vcpu_id-1]->next_in_list = v;
-        if ( !is_idle_domain(d) )
-            set_bit(_VCPUF_down, &v->vcpu_flags);
-    }
-
-    return v;
-}
-
-void free_vcpu(struct vcpu *v)
-{
-    /* NB. Rest of destruction is done in free_domain(). */
-    sched_rem_domain(v);
-}
-
-struct domain *alloc_domain(void)
-{
-    struct domain *d;
 
-    if ( (d = xmalloc(struct domain)) != NULL )
-        memset(d, 0, sizeof(*d));
+    sched_add_domain(v);
 
-    return d;
+    return v;
 }
 
-/*
- * Add and remove a domain
- */
 void sched_add_domain(struct vcpu *v) 
 {
     /* Initialise the per-domain timer. */
index e6b63ac324d74ede4f878ed8da32c36d1e40c24b..7005177f4c5c53f054834c3670740da7095b2f5e 100644 (file)
@@ -181,7 +181,6 @@ extern struct vcpu *idle_vcpu[NR_CPUS];
 
 struct vcpu *alloc_vcpu(
     struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
-void free_vcpu(struct vcpu *v);
 
 struct domain *alloc_domain(void);
 void free_domain(struct domain *d);