Some refactoring of domain creation/destruction.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 14 Jan 2006 22:16:43 +0000 (23:16 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sat, 14 Jan 2006 22:16:43 +0000 (23:16 +0100)
Interface name changes:
1. do_createdomain -> domain_create

2. domain_destruct -> domain_destroy

Arch-specific changes:
1. arch_do_createdomain -> arch_domain_create
This function now takes a domain pointer, not a VCPU
pointer! Initialisation of VCPU0 must happen in
alloc_vcpu_struct().

2. free_perdomain_pt -> arch_domain_destroy
This function must undo the work of arch_domain_create

TODO: arch_domain_create() refactoring is not completed
for ia64.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/xensetup.c
xen/arch/x86/domain.c
xen/arch/x86/setup.c
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/schedule.c
xen/include/asm-ia64/domain.h
xen/include/xen/domain.h
xen/include/xen/sched.h

index 99b1646614da928525f46faa241c561ba417bdbf..f8e7a0ffaf2852d0377a6c6c5154f1da9ee45cf5 100644 (file)
@@ -67,10 +67,11 @@ unsigned long map_domain_page0(struct domain *);
 extern unsigned long dom_fw_setup(struct domain *, char *, int);
 
 /* this belongs in include/asm, but there doesn't seem to be a suitable place */
-void free_perdomain_pt(struct domain *d)
+void arch_domain_destroy(struct domain *d)
 {
-       printf("free_perdomain_pt: not implemented\n");
+       printf("arch_domain_destroy: not implemented\n");
        //free_page((unsigned long)d->mm.perdomain_pt);
+       free_xenheap_page(d->shared_info);
 }
 
 static void default_idle(void)
@@ -192,9 +193,8 @@ static void init_switch_stack(struct vcpu *v)
        memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
 }
 
-int arch_do_createdomain(struct vcpu *v)
+int arch_domain_create(struct domain *d)
 {
-       struct domain *d = v->domain;
        struct thread_info *ti = alloc_thread_info(v);
 
        /* Clear thread_info to clear some important fields, like preempt_count */
@@ -255,7 +255,7 @@ int arch_do_createdomain(struct vcpu *v)
                printk("Can't allocate pgd for domain %d\n",d->domain_id);
                return -ENOMEM;
        }
-       printf ("arch_do_create_domain: domain=%p\n", d);
+       printf ("arch_domain_create: domain=%p\n", d);
 
        return 0;
 }
index 1b9dc72b75aa5ddfc4a62ade89d751c8cbe62b8a..12a9fd4820e90c65071d8f6dda420880cb1a052a 100644 (file)
@@ -281,7 +281,7 @@ void start_kernel(void)
 printk("About to call scheduler_init()\n");
     scheduler_init();
     idle_vcpu[0] = (struct vcpu*) ia64_r13;
-    idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
+    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     BUG_ON(idle_domain == NULL);
 
     late_setup_arch(&cmdline);
@@ -339,14 +339,14 @@ printk("About to call sort_main_extable()\n");
 
 
     /* Create initial domain 0. */
-printk("About to call do_createdomain()\n");
-    dom0 = do_createdomain(0, 0);
+printk("About to call domain_create()\n");
+    dom0 = domain_create(0, 0);
 
 #ifdef CLONE_DOMAIN0
     {
     int i;
     for (i = 0; i < CLONE_DOMAIN0; i++) {
-       clones[i] = do_createdomain(i+1, 0);
+       clones[i] = domain_create(i+1, 0);
         if ( clones[i] == NULL )
             panic("Error creating domain0 clone %d\n",i);
     }
index db764760b14299e39640875ccb6b43d3a01afd14..b38147211adc19de7e17a6064b10fdbbdec0c685 100644 (file)
@@ -218,41 +218,35 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
     v->arch.flags = TF_kernel_mode;
 
     if ( is_idle_domain(d) )
+    {
         percpu_ctxt[vcpu_id].curr_vcpu = v;
-
-    if ( (v->vcpu_id = vcpu_id) != 0 )
+        v->arch.schedule_tail = continue_idle_domain;
+    }
+    else
     {
-        v->arch.schedule_tail  = d->vcpu[0]->arch.schedule_tail;
-        v->arch.perdomain_ptes =
-            d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
+        v->arch.schedule_tail = continue_nonidle_domain;
     }
 
+    v->arch.perdomain_ptes =
+        d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
+
+    v->arch.guest_vtable  = __linear_l2_table;
+    v->arch.shadow_vtable = __shadow_linear_l2_table;
+#if defined(__x86_64__)
+    v->arch.guest_vl3table = __linear_l3_table;
+    v->arch.guest_vl4table = __linear_l4_table;
+#endif
+
     return v;
 }
 
 void free_vcpu_struct(struct vcpu *v)
 {
-    BUG_ON(v->next_in_list != NULL);
-    if ( v->vcpu_id != 0 )
-        v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
     xfree(v);
 }
 
-void free_perdomain_pt(struct domain *d)
-{
-    free_xenheap_pages(
-        d->arch.mm_perdomain_pt,
-        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
-
-#ifdef __x86_64__
-    free_xenheap_page(d->arch.mm_perdomain_l2);
-    free_xenheap_page(d->arch.mm_perdomain_l3);
-#endif
-}
-
-int arch_do_createdomain(struct vcpu *v)
+int arch_domain_create(struct domain *d)
 {
-    struct domain *d = v->domain;
     l1_pgentry_t gdt_l1e;
     int vcpuid, pdpt_order, rc;
 #ifdef __x86_64__
@@ -263,9 +257,7 @@ int arch_do_createdomain(struct vcpu *v)
     d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
     if ( d->arch.mm_perdomain_pt == NULL )
         goto fail_nomem;
-
     memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order);
-    v->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
 
     /*
      * Map Xen segments into every VCPU's GDT, irrespective of whether every
@@ -279,18 +271,12 @@ int arch_do_createdomain(struct vcpu *v)
         d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
                                  FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
 
-    v->arch.guest_vtable  = __linear_l2_table;
-    v->arch.shadow_vtable = __shadow_linear_l2_table;
-
 #if defined(__i386__)
 
     mapcache_init(d);
 
 #else /* __x86_64__ */
 
-    v->arch.guest_vl3table = __linear_l3_table;
-    v->arch.guest_vl4table = __linear_l4_table;
-
     d->arch.mm_perdomain_l2 = alloc_xenheap_page();
     d->arch.mm_perdomain_l3 = alloc_xenheap_page();
     if ( (d->arch.mm_perdomain_l2 == NULL) ||
@@ -327,13 +313,9 @@ int arch_do_createdomain(struct vcpu *v)
             goto fail_nomem;
 
         memset(d->shared_info, 0, PAGE_SIZE);
-        v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
         SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
     }
 
-    v->arch.schedule_tail = is_idle_domain(d) ?
-        continue_idle_domain : continue_nonidle_domain;
-
     return 0;
 
  fail_nomem:
@@ -346,6 +328,20 @@ int arch_do_createdomain(struct vcpu *v)
     return -ENOMEM;
 }
 
+void arch_domain_destroy(struct domain *d)
+{
+    free_xenheap_pages(
+        d->arch.mm_perdomain_pt,
+        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
+
+#ifdef __x86_64__
+    free_xenheap_page(d->arch.mm_perdomain_l2);
+    free_xenheap_page(d->arch.mm_perdomain_l3);
+#endif
+
+    free_xenheap_page(d->shared_info);
+}
+
 /* This is called by arch_final_setup_guest and do_boot_vcpu */
 int arch_set_info_guest(
     struct vcpu *v, struct vcpu_guest_context *c)
index 39bf4a523dd43cd74adc4238d1a68c92fc5d8c90..fc92f39bfae4bdd6aa9fdd376c94cad9b2a177c8 100644 (file)
@@ -385,7 +385,7 @@ void __init __start_xen(multiboot_info_t *mbi)
 
     scheduler_init();
 
-    idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
+    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     BUG_ON(idle_domain == NULL);
 
     set_current(idle_domain->vcpu[0]);
@@ -487,7 +487,7 @@ void __init __start_xen(multiboot_info_t *mbi)
     acm_init(&initrdidx, mbi, initial_images_start);
 
     /* Create initial domain 0. */
-    dom0 = do_createdomain(0, 0);
+    dom0 = domain_create(0, 0);
     if ( dom0 == NULL )
         panic("Error creating domain 0\n");
 
index 5b92dc75d3134014080f571319bfc4057cfbfbc7..3a339652016adb06ba07bbfe1cfe350aa09b9a2f 100644 (file)
@@ -208,7 +208,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
                 pro = i;
 
         ret = -ENOMEM;
-        if ( (d = do_createdomain(dom, pro)) == NULL )
+        if ( (d = domain_create(dom, pro)) == NULL )
             break;
 
         memcpy(d->handle, op->u.createdomain.handle,
index b0af3ebaf2a7458755e52f5cb2d7adda140f5ed9..de4f6c3f79f463914eba20418681b631dfb75cd6 100644 (file)
@@ -29,7 +29,7 @@ struct domain *domain_list;
 
 struct domain *dom0;
 
-struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
+struct domain *domain_create(domid_t dom_id, unsigned int cpu)
 {
     struct domain *d, **pd;
     struct vcpu *v;
@@ -46,25 +46,27 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
     INIT_LIST_HEAD(&d->page_list);
     INIT_LIST_HEAD(&d->xenpage_list);
 
+    rangeset_domain_initialise(d);
+
     if ( !is_idle_domain(d) )
+    {
         set_bit(_DOMF_ctrl_pause, &d->domain_flags);
+        if ( evtchn_init(d) != 0 )
+            goto fail1;
+        if ( grant_table_create(d) != 0 )
+            goto fail2;
+    }
 
-    if ( !is_idle_domain(d) &&
-         ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
-        goto fail1;
-    
-    if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
-        goto fail2;
+    if ( arch_domain_create(d) != 0 )
+        goto fail3;
 
-    rangeset_domain_initialise(d);
+    if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
+        goto fail4;
 
     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) ||
-         (arch_do_createdomain(v) != 0) )
-        goto fail3;
+    if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
+        goto fail5;
 
     if ( !is_idle_domain(d) )
     {
@@ -82,12 +84,18 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
 
     return d;
 
+ fail5:
+    free_vcpu(v);
+ fail4:
+    arch_domain_destroy(d);
  fail3:
-    rangeset_domain_destroy(d);
+    if ( !is_idle_domain(d) )
+        grant_table_destroy(d);
  fail2:
-    grant_table_destroy(d);
+    if ( !is_idle_domain(d) )
+        evtchn_destroy(d);
  fail1:
-    evtchn_destroy(d);
+    rangeset_domain_destroy(d);
     free_domain(d);
     return NULL;
 }
@@ -256,16 +264,16 @@ void domain_pause_for_debugger(void)
 
 
 /* Release resources belonging to task @p. */
-void domain_destruct(struct domain *d)
+void domain_destroy(struct domain *d)
 {
     struct domain **pd;
     atomic_t      old, new;
 
     BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
 
-    /* May be already destructed, or get_domain() can race us. */
+    /* May be already destroyed, or get_domain() can race us. */
     _atomic_set(old, 0);
-    _atomic_set(new, DOMAIN_DESTRUCTED);
+    _atomic_set(new, DOMAIN_DESTROYED);
     old = atomic_compareandswap(old, new, &d->refcnt);
     if ( _atomic_read(old) != 0 )
         return;
@@ -287,8 +295,7 @@ void domain_destruct(struct domain *d)
     evtchn_destroy(d);
     grant_table_destroy(d);
 
-    free_perdomain_pt(d);
-    free_xenheap_page(d->shared_info);
+    arch_domain_destroy(d);
 
     free_domain(d);
 
index f6668d359359578fab9b419d98bd4bc7016435bb..f2815d7d9ffc59813cb425ee6163cc3076578d35 100644 (file)
@@ -100,6 +100,7 @@ struct vcpu *alloc_vcpu(
     v->vcpu_id = vcpu_id;
     v->processor = cpu_id;
     atomic_set(&v->pausecnt, 0);
+    v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
 
     v->cpu_affinity = is_idle_domain(d) ?
         cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
@@ -117,14 +118,20 @@ struct vcpu *alloc_vcpu(
 
     if ( vcpu_id != 0 )
     {
-        v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
         d->vcpu[v->vcpu_id-1]->next_in_list = v;
-        set_bit(_VCPUF_down, &v->vcpu_flags);
+        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;
index 863def1ff5e4b6a8895da68de0163c3614d1c935..3aac1909630c9e1fb098212b98bb4a8981462f95 100644 (file)
@@ -10,8 +10,6 @@
 #include <asm/vmx_platform.h>
 #include <xen/list.h>
 
-extern int arch_do_createdomain(struct vcpu *);
-
 extern void domain_relinquish_resources(struct domain *);
 
 struct arch_domain {
index 4ebf0ca28669e4655a3a47bccfcc335d2749656c..4fee8e74cb39474913bd610685570150c9f1554a 100644 (file)
@@ -13,13 +13,13 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id);
 
 extern void free_vcpu_struct(struct vcpu *v);
 
-extern int arch_do_createdomain(struct vcpu *v);
+extern int arch_domain_create(struct domain *d);
+
+extern void arch_domain_destroy(struct domain *d);
 
 extern int arch_set_info_guest(
     struct vcpu *v, struct vcpu_guest_context *c);
 
-extern void free_perdomain_pt(struct domain *d);
-
 extern void domain_relinquish_resources(struct domain *d);
 
 extern void dump_pageframe_info(struct domain *d);
index df7611a70b2781d35f20b88edeb7bf28538e13ae..e6b63ac324d74ede4f878ed8da32c36d1e40c24b 100644 (file)
@@ -181,17 +181,18 @@ 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);
 
-#define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
+#define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
 #define put_domain(_d) \
-  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destruct(_d)
+  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
 
 /*
  * Use this when you don't have an existing reference to @d. It returns
- * FALSE if @d is being destructed.
+ * FALSE if @d is being destroyed.
  */
 static always_inline int get_domain(struct domain *d)
 {
@@ -199,7 +200,7 @@ static always_inline int get_domain(struct domain *d)
     do
     {
         old = seen;
-        if ( unlikely(_atomic_read(old) & DOMAIN_DESTRUCTED) )
+        if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
             return 0;
         _atomic_set(new, _atomic_read(old) + 1);
         seen = atomic_compareandswap(old, new, &d->refcnt);
@@ -210,15 +211,15 @@ static always_inline int get_domain(struct domain *d)
 
 /*
  * Use this when you already have, or are borrowing, a reference to @d.
- * In this case we know that @d cannot be destructed under our feet.
+ * In this case we know that @d cannot be destroyed under our feet.
  */
 static inline void get_knownalive_domain(struct domain *d)
 {
     atomic_inc(&d->refcnt);
-    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED));
+    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
 }
 
-extern struct domain *do_createdomain(
+extern struct domain *domain_create(
     domid_t dom_id, unsigned int cpu);
 extern int construct_dom0(
     struct domain *d,
@@ -228,7 +229,7 @@ extern int construct_dom0(
 extern int set_info_guest(struct domain *d, dom0_setvcpucontext_t *);
 
 struct domain *find_domain_by_id(domid_t dom);
-extern void domain_destruct(struct domain *d);
+extern void domain_destroy(struct domain *d);
 extern void domain_kill(struct domain *d);
 extern void domain_shutdown(struct domain *d, u8 reason);
 extern void domain_pause_for_debugger(void);