ia64/xen-unstable

changeset 8611:1ccc28e075ba

Some refactoring of domain creation/destruction.

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>
author kaf24@firebug.cl.cam.ac.uk
date Sat Jan 14 23:16:43 2006 +0100 (2006-01-14)
parents 334dc7e6a23f
children d783bdd14f2e
files 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
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Sat Jan 14 22:17:33 2006 +0100
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Sat Jan 14 23:16:43 2006 +0100
     1.3 @@ -67,10 +67,11 @@ unsigned long map_domain_page0(struct do
     1.4  extern unsigned long dom_fw_setup(struct domain *, char *, int);
     1.5  
     1.6  /* this belongs in include/asm, but there doesn't seem to be a suitable place */
     1.7 -void free_perdomain_pt(struct domain *d)
     1.8 +void arch_domain_destroy(struct domain *d)
     1.9  {
    1.10 -	printf("free_perdomain_pt: not implemented\n");
    1.11 +	printf("arch_domain_destroy: not implemented\n");
    1.12  	//free_page((unsigned long)d->mm.perdomain_pt);
    1.13 +	free_xenheap_page(d->shared_info);
    1.14  }
    1.15  
    1.16  static void default_idle(void)
    1.17 @@ -192,9 +193,8 @@ static void init_switch_stack(struct vcp
    1.18  	memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
    1.19  }
    1.20  
    1.21 -int arch_do_createdomain(struct vcpu *v)
    1.22 +int arch_domain_create(struct domain *d)
    1.23  {
    1.24 -	struct domain *d = v->domain;
    1.25  	struct thread_info *ti = alloc_thread_info(v);
    1.26  
    1.27  	/* Clear thread_info to clear some important fields, like preempt_count */
    1.28 @@ -255,7 +255,7 @@ int arch_do_createdomain(struct vcpu *v)
    1.29  		printk("Can't allocate pgd for domain %d\n",d->domain_id);
    1.30  		return -ENOMEM;
    1.31  	}
    1.32 -	printf ("arch_do_create_domain: domain=%p\n", d);
    1.33 +	printf ("arch_domain_create: domain=%p\n", d);
    1.34  
    1.35  	return 0;
    1.36  }
     2.1 --- a/xen/arch/ia64/xen/xensetup.c	Sat Jan 14 22:17:33 2006 +0100
     2.2 +++ b/xen/arch/ia64/xen/xensetup.c	Sat Jan 14 23:16:43 2006 +0100
     2.3 @@ -281,7 +281,7 @@ void start_kernel(void)
     2.4  printk("About to call scheduler_init()\n");
     2.5      scheduler_init();
     2.6      idle_vcpu[0] = (struct vcpu*) ia64_r13;
     2.7 -    idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
     2.8 +    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     2.9      BUG_ON(idle_domain == NULL);
    2.10  
    2.11      late_setup_arch(&cmdline);
    2.12 @@ -339,14 +339,14 @@ printk("About to call sort_main_extable(
    2.13  
    2.14  
    2.15      /* Create initial domain 0. */
    2.16 -printk("About to call do_createdomain()\n");
    2.17 -    dom0 = do_createdomain(0, 0);
    2.18 +printk("About to call domain_create()\n");
    2.19 +    dom0 = domain_create(0, 0);
    2.20  
    2.21  #ifdef CLONE_DOMAIN0
    2.22      {
    2.23      int i;
    2.24      for (i = 0; i < CLONE_DOMAIN0; i++) {
    2.25 -	clones[i] = do_createdomain(i+1, 0);
    2.26 +	clones[i] = domain_create(i+1, 0);
    2.27          if ( clones[i] == NULL )
    2.28              panic("Error creating domain0 clone %d\n",i);
    2.29      }
     3.1 --- a/xen/arch/x86/domain.c	Sat Jan 14 22:17:33 2006 +0100
     3.2 +++ b/xen/arch/x86/domain.c	Sat Jan 14 23:16:43 2006 +0100
     3.3 @@ -218,41 +218,35 @@ struct vcpu *alloc_vcpu_struct(struct do
     3.4      v->arch.flags = TF_kernel_mode;
     3.5  
     3.6      if ( is_idle_domain(d) )
     3.7 -        percpu_ctxt[vcpu_id].curr_vcpu = v;
     3.8 -
     3.9 -    if ( (v->vcpu_id = vcpu_id) != 0 )
    3.10      {
    3.11 -        v->arch.schedule_tail  = d->vcpu[0]->arch.schedule_tail;
    3.12 -        v->arch.perdomain_ptes =
    3.13 -            d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
    3.14 +        percpu_ctxt[vcpu_id].curr_vcpu = v;
    3.15 +        v->arch.schedule_tail = continue_idle_domain;
    3.16      }
    3.17 +    else
    3.18 +    {
    3.19 +        v->arch.schedule_tail = continue_nonidle_domain;
    3.20 +    }
    3.21 +
    3.22 +    v->arch.perdomain_ptes =
    3.23 +        d->arch.mm_perdomain_pt + (vcpu_id << GDT_LDT_VCPU_SHIFT);
    3.24 +
    3.25 +    v->arch.guest_vtable  = __linear_l2_table;
    3.26 +    v->arch.shadow_vtable = __shadow_linear_l2_table;
    3.27 +#if defined(__x86_64__)
    3.28 +    v->arch.guest_vl3table = __linear_l3_table;
    3.29 +    v->arch.guest_vl4table = __linear_l4_table;
    3.30 +#endif
    3.31  
    3.32      return v;
    3.33  }
    3.34  
    3.35  void free_vcpu_struct(struct vcpu *v)
    3.36  {
    3.37 -    BUG_ON(v->next_in_list != NULL);
    3.38 -    if ( v->vcpu_id != 0 )
    3.39 -        v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL;
    3.40      xfree(v);
    3.41  }
    3.42  
    3.43 -void free_perdomain_pt(struct domain *d)
    3.44 +int arch_domain_create(struct domain *d)
    3.45  {
    3.46 -    free_xenheap_pages(
    3.47 -        d->arch.mm_perdomain_pt,
    3.48 -        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
    3.49 -
    3.50 -#ifdef __x86_64__
    3.51 -    free_xenheap_page(d->arch.mm_perdomain_l2);
    3.52 -    free_xenheap_page(d->arch.mm_perdomain_l3);
    3.53 -#endif
    3.54 -}
    3.55 -
    3.56 -int arch_do_createdomain(struct vcpu *v)
    3.57 -{
    3.58 -    struct domain *d = v->domain;
    3.59      l1_pgentry_t gdt_l1e;
    3.60      int vcpuid, pdpt_order, rc;
    3.61  #ifdef __x86_64__
    3.62 @@ -263,9 +257,7 @@ int arch_do_createdomain(struct vcpu *v)
    3.63      d->arch.mm_perdomain_pt = alloc_xenheap_pages(pdpt_order);
    3.64      if ( d->arch.mm_perdomain_pt == NULL )
    3.65          goto fail_nomem;
    3.66 -
    3.67      memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE << pdpt_order);
    3.68 -    v->arch.perdomain_ptes = d->arch.mm_perdomain_pt;
    3.69  
    3.70      /*
    3.71       * Map Xen segments into every VCPU's GDT, irrespective of whether every
    3.72 @@ -279,18 +271,12 @@ int arch_do_createdomain(struct vcpu *v)
    3.73          d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
    3.74                                   FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
    3.75  
    3.76 -    v->arch.guest_vtable  = __linear_l2_table;
    3.77 -    v->arch.shadow_vtable = __shadow_linear_l2_table;
    3.78 -
    3.79  #if defined(__i386__)
    3.80  
    3.81      mapcache_init(d);
    3.82  
    3.83  #else /* __x86_64__ */
    3.84  
    3.85 -    v->arch.guest_vl3table = __linear_l3_table;
    3.86 -    v->arch.guest_vl4table = __linear_l4_table;
    3.87 -
    3.88      d->arch.mm_perdomain_l2 = alloc_xenheap_page();
    3.89      d->arch.mm_perdomain_l3 = alloc_xenheap_page();
    3.90      if ( (d->arch.mm_perdomain_l2 == NULL) ||
    3.91 @@ -327,13 +313,9 @@ int arch_do_createdomain(struct vcpu *v)
    3.92              goto fail_nomem;
    3.93  
    3.94          memset(d->shared_info, 0, PAGE_SIZE);
    3.95 -        v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
    3.96          SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
    3.97      }
    3.98  
    3.99 -    v->arch.schedule_tail = is_idle_domain(d) ?
   3.100 -        continue_idle_domain : continue_nonidle_domain;
   3.101 -
   3.102      return 0;
   3.103  
   3.104   fail_nomem:
   3.105 @@ -346,6 +328,20 @@ int arch_do_createdomain(struct vcpu *v)
   3.106      return -ENOMEM;
   3.107  }
   3.108  
   3.109 +void arch_domain_destroy(struct domain *d)
   3.110 +{
   3.111 +    free_xenheap_pages(
   3.112 +        d->arch.mm_perdomain_pt,
   3.113 +        get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
   3.114 +
   3.115 +#ifdef __x86_64__
   3.116 +    free_xenheap_page(d->arch.mm_perdomain_l2);
   3.117 +    free_xenheap_page(d->arch.mm_perdomain_l3);
   3.118 +#endif
   3.119 +
   3.120 +    free_xenheap_page(d->shared_info);
   3.121 +}
   3.122 +
   3.123  /* This is called by arch_final_setup_guest and do_boot_vcpu */
   3.124  int arch_set_info_guest(
   3.125      struct vcpu *v, struct vcpu_guest_context *c)
     4.1 --- a/xen/arch/x86/setup.c	Sat Jan 14 22:17:33 2006 +0100
     4.2 +++ b/xen/arch/x86/setup.c	Sat Jan 14 23:16:43 2006 +0100
     4.3 @@ -385,7 +385,7 @@ void __init __start_xen(multiboot_info_t
     4.4  
     4.5      scheduler_init();
     4.6  
     4.7 -    idle_domain = do_createdomain(IDLE_DOMAIN_ID, 0);
     4.8 +    idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
     4.9      BUG_ON(idle_domain == NULL);
    4.10  
    4.11      set_current(idle_domain->vcpu[0]);
    4.12 @@ -487,7 +487,7 @@ void __init __start_xen(multiboot_info_t
    4.13      acm_init(&initrdidx, mbi, initial_images_start);
    4.14  
    4.15      /* Create initial domain 0. */
    4.16 -    dom0 = do_createdomain(0, 0);
    4.17 +    dom0 = domain_create(0, 0);
    4.18      if ( dom0 == NULL )
    4.19          panic("Error creating domain 0\n");
    4.20  
     5.1 --- a/xen/common/dom0_ops.c	Sat Jan 14 22:17:33 2006 +0100
     5.2 +++ b/xen/common/dom0_ops.c	Sat Jan 14 23:16:43 2006 +0100
     5.3 @@ -208,7 +208,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     5.4                  pro = i;
     5.5  
     5.6          ret = -ENOMEM;
     5.7 -        if ( (d = do_createdomain(dom, pro)) == NULL )
     5.8 +        if ( (d = domain_create(dom, pro)) == NULL )
     5.9              break;
    5.10  
    5.11          memcpy(d->handle, op->u.createdomain.handle,
     6.1 --- a/xen/common/domain.c	Sat Jan 14 22:17:33 2006 +0100
     6.2 +++ b/xen/common/domain.c	Sat Jan 14 23:16:43 2006 +0100
     6.3 @@ -29,7 +29,7 @@ struct domain *domain_list;
     6.4  
     6.5  struct domain *dom0;
     6.6  
     6.7 -struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
     6.8 +struct domain *domain_create(domid_t dom_id, unsigned int cpu)
     6.9  {
    6.10      struct domain *d, **pd;
    6.11      struct vcpu *v;
    6.12 @@ -46,25 +46,27 @@ struct domain *do_createdomain(domid_t d
    6.13      INIT_LIST_HEAD(&d->page_list);
    6.14      INIT_LIST_HEAD(&d->xenpage_list);
    6.15  
    6.16 -    if ( !is_idle_domain(d) )
    6.17 -        set_bit(_DOMF_ctrl_pause, &d->domain_flags);
    6.18 +    rangeset_domain_initialise(d);
    6.19  
    6.20 -    if ( !is_idle_domain(d) &&
    6.21 -         ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) )
    6.22 -        goto fail1;
    6.23 -    
    6.24 +    if ( !is_idle_domain(d) )
    6.25 +    {
    6.26 +        set_bit(_DOMF_ctrl_pause, &d->domain_flags);
    6.27 +        if ( evtchn_init(d) != 0 )
    6.28 +            goto fail1;
    6.29 +        if ( grant_table_create(d) != 0 )
    6.30 +            goto fail2;
    6.31 +    }
    6.32 +
    6.33 +    if ( arch_domain_create(d) != 0 )
    6.34 +        goto fail3;
    6.35 +
    6.36      if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
    6.37 -        goto fail2;
    6.38 -
    6.39 -    rangeset_domain_initialise(d);
    6.40 +        goto fail4;
    6.41  
    6.42      d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex);
    6.43      d->irq_caps   = rangeset_new(d, "Interrupts", 0);
    6.44 -
    6.45 -    if ( (d->iomem_caps == NULL) ||
    6.46 -         (d->irq_caps == NULL) ||
    6.47 -         (arch_do_createdomain(v) != 0) )
    6.48 -        goto fail3;
    6.49 +    if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) )
    6.50 +        goto fail5;
    6.51  
    6.52      if ( !is_idle_domain(d) )
    6.53      {
    6.54 @@ -82,12 +84,18 @@ struct domain *do_createdomain(domid_t d
    6.55  
    6.56      return d;
    6.57  
    6.58 + fail5:
    6.59 +    free_vcpu(v);
    6.60 + fail4:
    6.61 +    arch_domain_destroy(d);
    6.62   fail3:
    6.63 -    rangeset_domain_destroy(d);
    6.64 +    if ( !is_idle_domain(d) )
    6.65 +        grant_table_destroy(d);
    6.66   fail2:
    6.67 -    grant_table_destroy(d);
    6.68 +    if ( !is_idle_domain(d) )
    6.69 +        evtchn_destroy(d);
    6.70   fail1:
    6.71 -    evtchn_destroy(d);
    6.72 +    rangeset_domain_destroy(d);
    6.73      free_domain(d);
    6.74      return NULL;
    6.75  }
    6.76 @@ -256,16 +264,16 @@ void domain_pause_for_debugger(void)
    6.77  
    6.78  
    6.79  /* Release resources belonging to task @p. */
    6.80 -void domain_destruct(struct domain *d)
    6.81 +void domain_destroy(struct domain *d)
    6.82  {
    6.83      struct domain **pd;
    6.84      atomic_t      old, new;
    6.85  
    6.86      BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
    6.87  
    6.88 -    /* May be already destructed, or get_domain() can race us. */
    6.89 +    /* May be already destroyed, or get_domain() can race us. */
    6.90      _atomic_set(old, 0);
    6.91 -    _atomic_set(new, DOMAIN_DESTRUCTED);
    6.92 +    _atomic_set(new, DOMAIN_DESTROYED);
    6.93      old = atomic_compareandswap(old, new, &d->refcnt);
    6.94      if ( _atomic_read(old) != 0 )
    6.95          return;
    6.96 @@ -287,8 +295,7 @@ void domain_destruct(struct domain *d)
    6.97      evtchn_destroy(d);
    6.98      grant_table_destroy(d);
    6.99  
   6.100 -    free_perdomain_pt(d);
   6.101 -    free_xenheap_page(d->shared_info);
   6.102 +    arch_domain_destroy(d);
   6.103  
   6.104      free_domain(d);
   6.105  
     7.1 --- a/xen/common/schedule.c	Sat Jan 14 22:17:33 2006 +0100
     7.2 +++ b/xen/common/schedule.c	Sat Jan 14 23:16:43 2006 +0100
     7.3 @@ -100,6 +100,7 @@ struct vcpu *alloc_vcpu(
     7.4      v->vcpu_id = vcpu_id;
     7.5      v->processor = cpu_id;
     7.6      atomic_set(&v->pausecnt, 0);
     7.7 +    v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
     7.8  
     7.9      v->cpu_affinity = is_idle_domain(d) ?
    7.10          cpumask_of_cpu(cpu_id) : CPU_MASK_ALL;
    7.11 @@ -117,14 +118,20 @@ struct vcpu *alloc_vcpu(
    7.12  
    7.13      if ( vcpu_id != 0 )
    7.14      {
    7.15 -        v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
    7.16          d->vcpu[v->vcpu_id-1]->next_in_list = v;
    7.17 -        set_bit(_VCPUF_down, &v->vcpu_flags);
    7.18 +        if ( !is_idle_domain(d) )
    7.19 +            set_bit(_VCPUF_down, &v->vcpu_flags);
    7.20      }
    7.21  
    7.22      return v;
    7.23  }
    7.24  
    7.25 +void free_vcpu(struct vcpu *v)
    7.26 +{
    7.27 +    /* NB. Rest of destruction is done in free_domain(). */
    7.28 +    sched_rem_domain(v);
    7.29 +}
    7.30 +
    7.31  struct domain *alloc_domain(void)
    7.32  {
    7.33      struct domain *d;
     8.1 --- a/xen/include/asm-ia64/domain.h	Sat Jan 14 22:17:33 2006 +0100
     8.2 +++ b/xen/include/asm-ia64/domain.h	Sat Jan 14 23:16:43 2006 +0100
     8.3 @@ -10,8 +10,6 @@
     8.4  #include <asm/vmx_platform.h>
     8.5  #include <xen/list.h>
     8.6  
     8.7 -extern int arch_do_createdomain(struct vcpu *);
     8.8 -
     8.9  extern void domain_relinquish_resources(struct domain *);
    8.10  
    8.11  struct arch_domain {
     9.1 --- a/xen/include/xen/domain.h	Sat Jan 14 22:17:33 2006 +0100
     9.2 +++ b/xen/include/xen/domain.h	Sat Jan 14 23:16:43 2006 +0100
     9.3 @@ -13,13 +13,13 @@ struct vcpu *alloc_vcpu_struct(struct do
     9.4  
     9.5  extern void free_vcpu_struct(struct vcpu *v);
     9.6  
     9.7 -extern int arch_do_createdomain(struct vcpu *v);
     9.8 +extern int arch_domain_create(struct domain *d);
     9.9 +
    9.10 +extern void arch_domain_destroy(struct domain *d);
    9.11  
    9.12  extern int arch_set_info_guest(
    9.13      struct vcpu *v, struct vcpu_guest_context *c);
    9.14  
    9.15 -extern void free_perdomain_pt(struct domain *d);
    9.16 -
    9.17  extern void domain_relinquish_resources(struct domain *d);
    9.18  
    9.19  extern void dump_pageframe_info(struct domain *d);
    10.1 --- a/xen/include/xen/sched.h	Sat Jan 14 22:17:33 2006 +0100
    10.2 +++ b/xen/include/xen/sched.h	Sat Jan 14 23:16:43 2006 +0100
    10.3 @@ -181,17 +181,18 @@ extern struct vcpu *idle_vcpu[NR_CPUS];
    10.4  
    10.5  struct vcpu *alloc_vcpu(
    10.6      struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
    10.7 +void free_vcpu(struct vcpu *v);
    10.8  
    10.9  struct domain *alloc_domain(void);
   10.10  void free_domain(struct domain *d);
   10.11  
   10.12 -#define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */
   10.13 +#define DOMAIN_DESTROYED (1<<31) /* assumes atomic_t is >= 32 bits */
   10.14  #define put_domain(_d) \
   10.15 -  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destruct(_d)
   10.16 +  if ( atomic_dec_and_test(&(_d)->refcnt) ) domain_destroy(_d)
   10.17  
   10.18  /*
   10.19   * Use this when you don't have an existing reference to @d. It returns
   10.20 - * FALSE if @d is being destructed.
   10.21 + * FALSE if @d is being destroyed.
   10.22   */
   10.23  static always_inline int get_domain(struct domain *d)
   10.24  {
   10.25 @@ -199,7 +200,7 @@ static always_inline int get_domain(stru
   10.26      do
   10.27      {
   10.28          old = seen;
   10.29 -        if ( unlikely(_atomic_read(old) & DOMAIN_DESTRUCTED) )
   10.30 +        if ( unlikely(_atomic_read(old) & DOMAIN_DESTROYED) )
   10.31              return 0;
   10.32          _atomic_set(new, _atomic_read(old) + 1);
   10.33          seen = atomic_compareandswap(old, new, &d->refcnt);
   10.34 @@ -210,15 +211,15 @@ static always_inline int get_domain(stru
   10.35  
   10.36  /*
   10.37   * Use this when you already have, or are borrowing, a reference to @d.
   10.38 - * In this case we know that @d cannot be destructed under our feet.
   10.39 + * In this case we know that @d cannot be destroyed under our feet.
   10.40   */
   10.41  static inline void get_knownalive_domain(struct domain *d)
   10.42  {
   10.43      atomic_inc(&d->refcnt);
   10.44 -    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTRUCTED));
   10.45 +    ASSERT(!(atomic_read(&d->refcnt) & DOMAIN_DESTROYED));
   10.46  }
   10.47  
   10.48 -extern struct domain *do_createdomain(
   10.49 +extern struct domain *domain_create(
   10.50      domid_t dom_id, unsigned int cpu);
   10.51  extern int construct_dom0(
   10.52      struct domain *d,
   10.53 @@ -228,7 +229,7 @@ extern int construct_dom0(
   10.54  extern int set_info_guest(struct domain *d, dom0_setvcpucontext_t *);
   10.55  
   10.56  struct domain *find_domain_by_id(domid_t dom);
   10.57 -extern void domain_destruct(struct domain *d);
   10.58 +extern void domain_destroy(struct domain *d);
   10.59  extern void domain_kill(struct domain *d);
   10.60  extern void domain_shutdown(struct domain *d, u8 reason);
   10.61  extern void domain_pause_for_debugger(void);