ia64/xen-unstable

changeset 14642:4b13fc910acf

xen: Split domain_flags into discrete first-class fields in the
domain structure. This makes them quicker to access, and simplifies
domain pause and checking of runnable status.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Mar 29 15:14:26 2007 +0100 (2007-03-29)
parents 31f20aaac818
children 7b17dd28500c
files xen/arch/ia64/xen/mm.c xen/arch/powerpc/mm.c xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/mm.c xen/arch/x86/mm/hap/hap.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/entry.S xen/common/domain.c xen/common/domctl.c xen/common/event_channel.c xen/common/grant_table.c xen/common/keyhandler.c xen/common/memory.c xen/common/page_alloc.c xen/common/schedule.c xen/include/xen/sched.h xen/include/xen/spinlock.h
line diff
     1.1 --- a/xen/arch/ia64/xen/mm.c	Thu Mar 29 13:29:24 2007 +0100
     1.2 +++ b/xen/arch/ia64/xen/mm.c	Thu Mar 29 15:14:26 2007 +0100
     1.3 @@ -400,7 +400,7 @@ share_xen_page_with_guest(struct page_in
     1.4      ASSERT(page->count_info == 0);
     1.5  
     1.6      /* Only add to the allocation list if the domain isn't dying. */
     1.7 -    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
     1.8 +    if ( !d->is_dying )
     1.9      {
    1.10          page->count_info |= PGC_allocated | 1;
    1.11          if ( unlikely(d->xenheap_pages++ == 0) )
    1.12 @@ -1935,8 +1935,7 @@ void put_page_type(struct page_info *pag
    1.13           * page-table pages if we detect a referential loop.
    1.14           * See domain.c:relinquish_list().
    1.15           */
    1.16 -        ASSERT((x & PGT_validated) ||
    1.17 -               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
    1.18 +        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
    1.19  
    1.20          if ( unlikely((nx & PGT_count_mask) == 0) )
    1.21          {
     2.1 --- a/xen/arch/powerpc/mm.c	Thu Mar 29 13:29:24 2007 +0100
     2.2 +++ b/xen/arch/powerpc/mm.c	Thu Mar 29 15:14:26 2007 +0100
     2.3 @@ -106,7 +106,7 @@ void share_xen_page_with_guest(
     2.4      ASSERT(page->count_info == 0);
     2.5  
     2.6      /* Only add to the allocation list if the domain isn't dying. */
     2.7 -    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
     2.8 +    if ( !d->is_dying )
     2.9      {
    2.10          page->count_info |= PGC_allocated | 1;
    2.11          if ( unlikely(d->xenheap_pages++ == 0) )
    2.12 @@ -218,8 +218,7 @@ void put_page_type(struct page_info *pag
    2.13           * page-table pages if we detect a referential loop.
    2.14           * See domain.c:relinquish_list().
    2.15           */
    2.16 -        ASSERT((x & PGT_validated) || 
    2.17 -               test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags));
    2.18 +        ASSERT((x & PGT_validated) || page_get_owner(page)->is_dying);
    2.19  
    2.20          if ( unlikely((nx & PGT_count_mask) == 0) )
    2.21          {
    2.22 @@ -402,7 +401,7 @@ int allocate_rma(struct domain *d, unsig
    2.23  void free_rma_check(struct page_info *page)
    2.24  {
    2.25      if (test_bit(_PGC_page_RMA, &page->count_info)) {
    2.26 -        if (!test_bit(_DOMF_dying, &page_get_owner(page)->domain_flags)) {
    2.27 +        if (!page_get_owner(page)->is_dying) {
    2.28              panic("Attempt to free an RMA page: 0x%lx\n", page_to_mfn(page));
    2.29          } else {
    2.30              clear_bit(_PGC_page_RMA, &page->count_info);
    2.31 @@ -439,8 +438,7 @@ ulong pfn2mfn(struct domain *d, ulong pf
    2.32              mfn = d->arch.p2m[pfn];
    2.33          }
    2.34  #ifdef DEBUG
    2.35 -        if (t != PFN_TYPE_NONE &&
    2.36 -            (d->domain_flags & DOMF_dying) &&
    2.37 +        if (t != PFN_TYPE_NONE && d->is_dying &&
    2.38              page_get_owner(mfn_to_page(mfn)) != d) {
    2.39              printk("%s: page type: %d owner Dom[%d]:%p expected Dom[%d]:%p\n",
    2.40                     __func__, t,
     3.1 --- a/xen/arch/x86/domain.c	Thu Mar 29 13:29:24 2007 +0100
     3.2 +++ b/xen/arch/x86/domain.c	Thu Mar 29 15:14:26 2007 +0100
     3.3 @@ -274,7 +274,7 @@ int switch_native(struct domain *d)
     3.4      if ( !IS_COMPAT(d) )
     3.5          return 0;
     3.6  
     3.7 -    clear_bit(_DOMF_compat, &d->domain_flags);
     3.8 +    d->is_compat = 0;
     3.9      release_arg_xlat_area(d);
    3.10  
    3.11      /* switch gdt */
    3.12 @@ -306,7 +306,7 @@ int switch_compat(struct domain *d)
    3.13      if ( IS_COMPAT(d) )
    3.14          return 0;
    3.15  
    3.16 -    set_bit(_DOMF_compat, &d->domain_flags);
    3.17 +    d->is_compat = 1;
    3.18  
    3.19      /* switch gdt */
    3.20      gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
     4.1 --- a/xen/arch/x86/domain_build.c	Thu Mar 29 13:29:24 2007 +0100
     4.2 +++ b/xen/arch/x86/domain_build.c	Thu Mar 29 15:14:26 2007 +0100
     4.3 @@ -324,7 +324,7 @@ int construct_dom0(struct domain *d,
     4.4      {
     4.5          l1_pgentry_t gdt_l1e;
     4.6  
     4.7 -        set_bit(_DOMF_compat, &d->domain_flags);
     4.8 +        d->is_compat = 1;
     4.9          v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
    4.10  
    4.11          if ( nr_pages != (unsigned int)nr_pages )
     5.1 --- a/xen/arch/x86/mm.c	Thu Mar 29 13:29:24 2007 +0100
     5.2 +++ b/xen/arch/x86/mm.c	Thu Mar 29 15:14:26 2007 +0100
     5.3 @@ -271,7 +271,7 @@ void share_xen_page_with_guest(
     5.4      ASSERT(page->count_info == 0);
     5.5  
     5.6      /* Only add to the allocation list if the domain isn't dying. */
     5.7 -    if ( !test_bit(_DOMF_dying, &d->domain_flags) )
     5.8 +    if ( !d->is_dying )
     5.9      {
    5.10          page->count_info |= PGC_allocated | 1;
    5.11          if ( unlikely(d->xenheap_pages++ == 0) )
    5.12 @@ -806,8 +806,7 @@ void put_page_from_l1e(l1_pgentry_t l1e,
    5.13       * (Note that the undestroyable active grants are not a security hole in
    5.14       * Xen. All active grants can safely be cleaned up when the domain dies.)
    5.15       */
    5.16 -    if ( (l1e_get_flags(l1e) & _PAGE_GNTTAB) &&
    5.17 -         !(d->domain_flags & (DOMF_shutdown|DOMF_dying)) )
    5.18 +    if ( (l1e_get_flags(l1e) & _PAGE_GNTTAB) && !d->is_shutdown && !d->is_dying )
    5.19      {
    5.20          MEM_LOG("Attempt to implicitly unmap a granted PTE %" PRIpte,
    5.21                  l1e_get_intpte(l1e));
    5.22 @@ -2054,9 +2053,12 @@ int do_mmuext_op(
    5.23              /* A page is dirtied when its pin status is set. */
    5.24              mark_dirty(d, mfn);
    5.25             
    5.26 -            /* We can race domain destruction (domain_relinquish_resources). */
    5.27 +            /*
    5.28 +             * We can race domain destruction (domain_relinquish_resources).
    5.29 +             * NB. The dying-flag test must happen /after/ setting PGT_pinned.
    5.30 +             */
    5.31              if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) &&
    5.32 -                 test_bit(_DOMF_dying, &FOREIGNDOM->domain_flags) &&
    5.33 +                 this_cpu(percpu_mm_info).foreign->is_dying &&
    5.34                   test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
    5.35                  put_page_and_type(page);
    5.36  
     6.1 --- a/xen/arch/x86/mm/hap/hap.c	Thu Mar 29 13:29:24 2007 +0100
     6.2 +++ b/xen/arch/x86/mm/hap/hap.c	Thu Mar 29 15:14:26 2007 +0100
     6.3 @@ -451,7 +451,7 @@ void hap_teardown(struct domain *d)
     6.4      mfn_t mfn;
     6.5      HERE_I_AM;
     6.6  
     6.7 -    ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
     6.8 +    ASSERT(d->is_dying);
     6.9      ASSERT(d != current->domain);
    6.10  
    6.11      if ( !hap_locked_by_me(d) )
     7.1 --- a/xen/arch/x86/mm/shadow/common.c	Thu Mar 29 13:29:24 2007 +0100
     7.2 +++ b/xen/arch/x86/mm/shadow/common.c	Thu Mar 29 15:14:26 2007 +0100
     7.3 @@ -2461,7 +2461,7 @@ void shadow_teardown(struct domain *d)
     7.4      struct list_head *entry, *n;
     7.5      struct page_info *pg;
     7.6  
     7.7 -    ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
     7.8 +    ASSERT(d->is_dying);
     7.9      ASSERT(d != current->domain);
    7.10  
    7.11      if ( !shadow_locked_by_me(d) )
    7.12 @@ -2992,7 +2992,7 @@ int shadow_domctl(struct domain *d,
    7.13          return -EINVAL;
    7.14      }
    7.15  
    7.16 -    if ( unlikely(test_bit(_DOMF_dying, &d->domain_flags)) )
    7.17 +    if ( unlikely(d->is_dying) )
    7.18      {
    7.19          gdprintk(XENLOG_INFO, "Ignoring shadow op on dying domain %u\n",
    7.20                   d->domain_id);
     8.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Mar 29 13:29:24 2007 +0100
     8.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Mar 29 15:14:26 2007 +0100
     8.3 @@ -2821,9 +2821,9 @@ static int sh_page_fault(struct vcpu *v,
     8.4      {
     8.5          /* Couldn't get the sl1e!  Since we know the guest entries
     8.6           * are OK, this can only have been caused by a failed
     8.7 -         * shadow_set_l*e(), which will have crashed the guest.  
     8.8 +         * shadow_set_l*e(), which will have crashed the guest.
     8.9           * Get out of the fault handler immediately. */
    8.10 -        ASSERT(test_bit(_DOMF_dying, &d->domain_flags));
    8.11 +        ASSERT(d->is_shutdown);
    8.12          unmap_walk(v, &gw); 
    8.13          shadow_unlock(d);
    8.14          return 0;
     9.1 --- a/xen/arch/x86/x86_64/asm-offsets.c	Thu Mar 29 13:29:24 2007 +0100
     9.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c	Thu Mar 29 15:14:26 2007 +0100
     9.3 @@ -92,8 +92,7 @@ void __dummy__(void)
     9.4      OFFSET(VCPU_vmx_cr2, struct vcpu, arch.hvm_vmx.cpu_cr2);
     9.5      BLANK();
     9.6  
     9.7 -    OFFSET(DOMAIN_domain_flags, struct domain, domain_flags);
     9.8 -    DEFINE(_DOMF_compat, _DOMF_compat);
     9.9 +    OFFSET(DOMAIN_is_compat, struct domain, is_compat);
    9.10      BLANK();
    9.11  
    9.12      OFFSET(VMCB_rax, struct vmcb_struct, rax);
    10.1 --- a/xen/arch/x86/x86_64/entry.S	Thu Mar 29 13:29:24 2007 +0100
    10.2 +++ b/xen/arch/x86/x86_64/entry.S	Thu Mar 29 15:14:26 2007 +0100
    10.3 @@ -234,8 +234,8 @@ ENTRY(int80_direct_trap)
    10.4          jz    int80_slow_path
    10.5  
    10.6          movq  VCPU_domain(%rbx),%rax
    10.7 -        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
    10.8 -        jc    compat_int80_direct_trap
    10.9 +        testb $1,DOMAIN_is_compat(%rax)
   10.10 +        jnz   compat_int80_direct_trap
   10.11  
   10.12          call  create_bounce_frame
   10.13          jmp   restore_all_guest
   10.14 @@ -353,16 +353,12 @@ ENTRY(domain_crash_synchronous)
   10.15          GET_GUEST_REGS(%rax)
   10.16          movq  %rax,%rsp
   10.17          # create_bounce_frame() temporarily clobbers CS.RPL. Fix up.
   10.18 -#ifdef CONFIG_COMPAT
   10.19          movq  CPUINFO_current_vcpu(%rax),%rax
   10.20          movq  VCPU_domain(%rax),%rax
   10.21 -        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
   10.22 -        setnc %al
   10.23 +        testb $1,DOMAIN_is_compat(%rax)
   10.24 +        setz  %al
   10.25          leal  (%rax,%rax,2),%eax
   10.26          orb   %al,UREGS_cs(%rsp)
   10.27 -#else
   10.28 -        orb   $3,UREGS_cs(%rsp)
   10.29 -#endif
   10.30          # printk(domain_crash_synchronous_string)
   10.31          leaq  domain_crash_synchronous_string(%rip),%rdi
   10.32          xorl  %eax,%eax
   10.33 @@ -375,14 +371,10 @@ ENTRY(ret_from_intr)
   10.34          GET_CURRENT(%rbx)
   10.35          testb $3,UREGS_cs(%rsp)
   10.36          jz    restore_all_xen
   10.37 -#ifndef CONFIG_COMPAT
   10.38 -        jmp   test_all_events
   10.39 -#else
   10.40          movq  VCPU_domain(%rbx),%rax
   10.41 -        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
   10.42 -        jnc   test_all_events
   10.43 +        testb $1,DOMAIN_is_compat(%rax)
   10.44 +        jz    test_all_events
   10.45          jmp   compat_test_all_events
   10.46 -#endif
   10.47  
   10.48          ALIGN
   10.49  /* No special register assumptions. */
   10.50 @@ -401,11 +393,9 @@ 1:      movq  %rsp,%rdi
   10.51          testb $3,UREGS_cs(%rsp)
   10.52          jz    restore_all_xen
   10.53          leaq  VCPU_trap_bounce(%rbx),%rdx
   10.54 -#ifdef CONFIG_COMPAT
   10.55          movq  VCPU_domain(%rbx),%rax
   10.56 -        btl   $_DOMF_compat,DOMAIN_domain_flags(%rax)
   10.57 -        jc    compat_post_handle_exception
   10.58 -#endif
   10.59 +        testb $1,DOMAIN_is_compat(%rax)
   10.60 +        jnz   compat_post_handle_exception
   10.61          testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
   10.62          jz    test_all_events
   10.63          call  create_bounce_frame
    11.1 --- a/xen/common/domain.c	Thu Mar 29 13:29:24 2007 +0100
    11.2 +++ b/xen/common/domain.c	Thu Mar 29 15:14:26 2007 +0100
    11.3 @@ -59,7 +59,6 @@ struct domain *alloc_domain(domid_t domi
    11.4      atomic_set(&d->refcnt, 1);
    11.5      spin_lock_init(&d->big_lock);
    11.6      spin_lock_init(&d->page_alloc_lock);
    11.7 -    spin_lock_init(&d->pause_lock);
    11.8      INIT_LIST_HEAD(&d->page_list);
    11.9      INIT_LIST_HEAD(&d->xenpage_list);
   11.10  
   11.11 @@ -161,9 +160,12 @@ struct domain *domain_create(domid_t dom
   11.12  
   11.13      if ( !is_idle_domain(d) )
   11.14      {
   11.15 -        set_bit(_DOMF_ctrl_pause, &d->domain_flags);
   11.16 +        d->is_paused_by_controller = 1;
   11.17 +        atomic_inc(&d->pause_count);
   11.18 +
   11.19          if ( evtchn_init(d) != 0 )
   11.20              goto fail1;
   11.21 +
   11.22          if ( grant_table_create(d) != 0 )
   11.23              goto fail2;
   11.24      }
   11.25 @@ -262,9 +264,13 @@ void domain_kill(struct domain *d)
   11.26  {
   11.27      domain_pause(d);
   11.28  
   11.29 -    if ( test_and_set_bit(_DOMF_dying, &d->domain_flags) )
   11.30 +    /* Already dying? Then bail. */
   11.31 +    if ( xchg(&d->is_dying, 1) )
   11.32          return;
   11.33  
   11.34 +    /* Tear down state /after/ setting the dying flag. */
   11.35 +    smp_wmb();
   11.36 +
   11.37      gnttab_release_mappings(d);
   11.38      domain_relinquish_resources(d);
   11.39      put_domain(d);
   11.40 @@ -278,7 +284,7 @@ void domain_kill(struct domain *d)
   11.41  
   11.42  void __domain_crash(struct domain *d)
   11.43  {
   11.44 -    if ( test_bit(_DOMF_shutdown, &d->domain_flags) )
   11.45 +    if ( d->is_shutdown )
   11.46      {
   11.47          /* Print nothing: the domain is already shutting down. */
   11.48      }
   11.49 @@ -327,7 +333,7 @@ void domain_shutdown(struct domain *d, u
   11.50      if ( d->domain_id == 0 )
   11.51          dom0_shutdown(reason);
   11.52  
   11.53 -    if ( !test_and_set_bit(_DOMF_shutdown, &d->domain_flags) )
   11.54 +    if ( !xchg(&d->is_shutdown, 1) )
   11.55          d->shutdown_code = reason;
   11.56  
   11.57      for_each_vcpu ( d, v )
   11.58 @@ -341,7 +347,9 @@ void domain_pause_for_debugger(void)
   11.59      struct domain *d = current->domain;
   11.60      struct vcpu *v;
   11.61  
   11.62 -    set_bit(_DOMF_ctrl_pause, &d->domain_flags);
   11.63 +    atomic_inc(&d->pause_count);
   11.64 +    if ( xchg(&d->is_paused_by_controller, 1) )
   11.65 +        domain_unpause(d); /* race-free atomic_dec(&d->pause_count) */
   11.66  
   11.67      for_each_vcpu ( d, v )
   11.68          vcpu_sleep_nosync(v);
   11.69 @@ -374,7 +382,7 @@ void domain_destroy(struct domain *d)
   11.70      struct domain **pd;
   11.71      atomic_t      old, new;
   11.72  
   11.73 -    BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
   11.74 +    BUG_ON(!d->is_dying);
   11.75  
   11.76      /* May be already destroyed, or get_domain() can race us. */
   11.77      _atomic_set(old, 0);
   11.78 @@ -442,10 +450,7 @@ void domain_pause(struct domain *d)
   11.79  
   11.80      ASSERT(d != current->domain);
   11.81  
   11.82 -    spin_lock(&d->pause_lock);
   11.83 -    if ( d->pause_count++ == 0 )
   11.84 -        set_bit(_DOMF_paused, &d->domain_flags);
   11.85 -    spin_unlock(&d->pause_lock);
   11.86 +    atomic_inc(&d->pause_count);
   11.87  
   11.88      for_each_vcpu( d, v )
   11.89          vcpu_sleep_sync(v);
   11.90 @@ -454,43 +459,25 @@ void domain_pause(struct domain *d)
   11.91  void domain_unpause(struct domain *d)
   11.92  {
   11.93      struct vcpu *v;
   11.94 -    int wake;
   11.95  
   11.96      ASSERT(d != current->domain);
   11.97  
   11.98 -    spin_lock(&d->pause_lock);
   11.99 -    wake = (--d->pause_count == 0);
  11.100 -    if ( wake )
  11.101 -        clear_bit(_DOMF_paused, &d->domain_flags);
  11.102 -    spin_unlock(&d->pause_lock);
  11.103 -
  11.104 -    if ( wake )
  11.105 +    if ( atomic_dec_and_test(&d->pause_count) )
  11.106          for_each_vcpu( d, v )
  11.107              vcpu_wake(v);
  11.108  }
  11.109  
  11.110  void domain_pause_by_systemcontroller(struct domain *d)
  11.111  {
  11.112 -    struct vcpu *v;
  11.113 -
  11.114 -    BUG_ON(current->domain == d);
  11.115 -
  11.116 -    if ( !test_and_set_bit(_DOMF_ctrl_pause, &d->domain_flags) )
  11.117 -    {
  11.118 -        for_each_vcpu ( d, v )
  11.119 -            vcpu_sleep_sync(v);
  11.120 -    }
  11.121 +    domain_pause(d);
  11.122 +    if ( xchg(&d->is_paused_by_controller, 1) )
  11.123 +        domain_unpause(d);
  11.124  }
  11.125  
  11.126  void domain_unpause_by_systemcontroller(struct domain *d)
  11.127  {
  11.128 -    struct vcpu *v;
  11.129 -
  11.130 -    if ( test_and_clear_bit(_DOMF_ctrl_pause, &d->domain_flags) )
  11.131 -    {
  11.132 -        for_each_vcpu ( d, v )
  11.133 -            vcpu_wake(v);
  11.134 -    }
  11.135 +    if ( xchg(&d->is_paused_by_controller, 0) )
  11.136 +        domain_unpause(d);
  11.137  }
  11.138  
  11.139  int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt)
    12.1 --- a/xen/common/domctl.c	Thu Mar 29 13:29:24 2007 +0100
    12.2 +++ b/xen/common/domctl.c	Thu Mar 29 15:14:26 2007 +0100
    12.3 @@ -114,9 +114,9 @@ void getdomaininfo(struct domain *d, str
    12.4      info->cpu_time = cpu_time;
    12.5  
    12.6      info->flags = flags |
    12.7 -        ((d->domain_flags & DOMF_dying)      ? XEN_DOMINF_dying    : 0) |
    12.8 -        ((d->domain_flags & DOMF_shutdown)   ? XEN_DOMINF_shutdown : 0) |
    12.9 -        ((d->domain_flags & DOMF_ctrl_pause) ? XEN_DOMINF_paused   : 0) |
   12.10 +        (d->is_dying                ? XEN_DOMINF_dying    : 0) |
   12.11 +        (d->is_shutdown             ? XEN_DOMINF_shutdown : 0) |
   12.12 +        (d->is_paused_by_controller ? XEN_DOMINF_paused   : 0) |
   12.13          d->shutdown_code << XEN_DOMINF_shutdownshift;
   12.14  
   12.15      if ( is_hvm_domain(d) )
   12.16 @@ -288,7 +288,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   12.17          if ( d != NULL )
   12.18          {
   12.19              ret = 0;
   12.20 -            if ( test_and_clear_bit(_DOMF_shutdown, &d->domain_flags) )
   12.21 +            if ( xchg(&d->is_shutdown, 0) )
   12.22                  for_each_vcpu ( d, v )
   12.23                      vcpu_wake(v);
   12.24              rcu_unlock_domain(d);
    13.1 --- a/xen/common/event_channel.c	Thu Mar 29 13:29:24 2007 +0100
    13.2 +++ b/xen/common/event_channel.c	Thu Mar 29 15:14:26 2007 +0100
    13.3 @@ -529,8 +529,7 @@ void evtchn_set_pending(struct vcpu *v, 
    13.4      }
    13.5      
    13.6      /* Check if some VCPU might be polling for this event. */
    13.7 -    if ( unlikely(test_bit(_DOMF_polling, &d->domain_flags)) &&
    13.8 -         likely(test_and_clear_bit(_DOMF_polling, &d->domain_flags)) )
    13.9 +    if ( unlikely(d->is_polling) && likely(xchg(&d->is_polling, 0)) )
   13.10      {
   13.11          for_each_vcpu ( d, v )
   13.12              if ( test_and_clear_bit(_VCPUF_polling, &v->vcpu_flags) )
    14.1 --- a/xen/common/grant_table.c	Thu Mar 29 13:29:24 2007 +0100
    14.2 +++ b/xen/common/grant_table.c	Thu Mar 29 15:14:26 2007 +0100
    14.3 @@ -311,7 +311,7 @@ static void
    14.4                      get_page_and_type(mfn_to_page(frame), rd,
    14.5                                        PGT_writable_page))) )
    14.6      {
    14.7 -        if ( !test_bit(_DOMF_dying, &rd->domain_flags) )
    14.8 +        if ( !rd->is_dying )
    14.9              gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame);
   14.10          rc = GNTST_general_error;
   14.11          goto undo_out;
   14.12 @@ -865,16 +865,16 @@ gnttab_transfer(
   14.13           * headroom.  Also, a domain mustn't have PGC_allocated
   14.14           * pages when it is dying.
   14.15           */
   14.16 -        if ( unlikely(test_bit(_DOMF_dying, &e->domain_flags)) ||
   14.17 +        if ( unlikely(e->is_dying) ||
   14.18               unlikely(e->tot_pages >= e->max_pages) ||
   14.19               unlikely(!gnttab_prepare_for_transfer(e, d, gop.ref)) )
   14.20          {
   14.21 -            if ( !test_bit(_DOMF_dying, &e->domain_flags) )
   14.22 +            if ( !e->is_dying )
   14.23                  gdprintk(XENLOG_INFO, "gnttab_transfer: "
   14.24                          "Transferee has no reservation "
   14.25                          "headroom (%d,%d) or provided a bad grant ref (%08x) "
   14.26 -                        "or is dying (%lx)\n",
   14.27 -                        e->tot_pages, e->max_pages, gop.ref, e->domain_flags);
   14.28 +                        "or is dying (%d)\n",
   14.29 +                        e->tot_pages, e->max_pages, gop.ref, e->is_dying);
   14.30              spin_unlock(&e->page_alloc_lock);
   14.31              rcu_unlock_domain(e);
   14.32              page->count_info &= ~(PGC_count_mask|PGC_allocated);
   14.33 @@ -1094,7 +1094,7 @@ static void
   14.34                   "source frame %lx invalid.\n", s_frame);
   14.35      if ( !get_page(mfn_to_page(s_frame), sd) )
   14.36      {
   14.37 -        if ( !test_bit(_DOMF_dying, &sd->domain_flags) )
   14.38 +        if ( !sd->is_dying )
   14.39              gdprintk(XENLOG_WARNING, "Could not get src frame %lx\n", s_frame);
   14.40          rc = GNTST_general_error;
   14.41          goto error_out;
   14.42 @@ -1117,7 +1117,7 @@ static void
   14.43                   "destination frame %lx invalid.\n", d_frame);
   14.44      if ( !get_page_and_type(mfn_to_page(d_frame), dd, PGT_writable_page) )
   14.45      {
   14.46 -        if ( !test_bit(_DOMF_dying, &dd->domain_flags) )
   14.47 +        if ( !dd->is_dying )
   14.48              gdprintk(XENLOG_WARNING, "Could not get dst frame %lx\n", d_frame);
   14.49          rc = GNTST_general_error;
   14.50          goto error_out;
   14.51 @@ -1352,7 +1352,7 @@ gnttab_release_mappings(
   14.52      struct active_grant_entry *act;
   14.53      struct grant_entry   *sha;
   14.54  
   14.55 -    BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags));
   14.56 +    BUG_ON(!d->is_dying);
   14.57  
   14.58      for ( handle = 0; handle < gt->maptrack_limit; handle++ )
   14.59      {
    15.1 --- a/xen/common/keyhandler.c	Thu Mar 29 13:29:24 2007 +0100
    15.2 +++ b/xen/common/keyhandler.c	Thu Mar 29 15:14:26 2007 +0100
    15.3 @@ -164,9 +164,9 @@ static void dump_domains(unsigned char k
    15.4      {
    15.5          printk("General information for domain %u:\n", d->domain_id);
    15.6          cpuset_print(tmpstr, sizeof(tmpstr), d->domain_dirty_cpumask);
    15.7 -        printk("    flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d "
    15.8 +        printk("    refcnt=%d nr_pages=%d xenheap_pages=%d "
    15.9                 "dirty_cpus=%s\n",
   15.10 -               d->domain_flags, atomic_read(&d->refcnt),
   15.11 +               atomic_read(&d->refcnt),
   15.12                 d->tot_pages, d->xenheap_pages, tmpstr);
   15.13          printk("    handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
   15.14                 "%02x%02x-%02x%02x%02x%02x%02x%02x vm_assist=%08lx\n",
    16.1 --- a/xen/common/memory.c	Thu Mar 29 13:29:24 2007 +0100
    16.2 +++ b/xen/common/memory.c	Thu Mar 29 15:14:26 2007 +0100
    16.3 @@ -345,7 +345,7 @@ static long memory_exchange(XEN_GUEST_HA
    16.4  
    16.5      /*
    16.6       * Only support exchange on calling domain right now. Otherwise there are
    16.7 -     * tricky corner cases to consider (e.g., DOMF_dying domain).
    16.8 +     * tricky corner cases to consider (e.g., dying domain).
    16.9       */
   16.10      if ( unlikely(exch.in.domid != DOMID_SELF) )
   16.11      {
    17.1 --- a/xen/common/page_alloc.c	Thu Mar 29 13:29:24 2007 +0100
    17.2 +++ b/xen/common/page_alloc.c	Thu Mar 29 15:14:26 2007 +0100
    17.3 @@ -739,7 +739,7 @@ int assign_pages(
    17.4  
    17.5      spin_lock(&d->page_alloc_lock);
    17.6  
    17.7 -    if ( unlikely(test_bit(_DOMF_dying, &d->domain_flags)) )
    17.8 +    if ( unlikely(d->is_dying) )
    17.9      {
   17.10          gdprintk(XENLOG_INFO, "Cannot assign page to domain%d -- dying.\n",
   17.11                  d->domain_id);
   17.12 @@ -869,7 +869,7 @@ void free_domheap_pages(struct page_info
   17.13  
   17.14          spin_unlock_recursive(&d->page_alloc_lock);
   17.15  
   17.16 -        if ( likely(!test_bit(_DOMF_dying, &d->domain_flags)) )
   17.17 +        if ( likely(!d->is_dying) )
   17.18          {
   17.19              free_heap_pages(pfn_dom_zone_type(page_to_mfn(pg)), pg, order);
   17.20          }
    18.1 --- a/xen/common/schedule.c	Thu Mar 29 13:29:24 2007 +0100
    18.2 +++ b/xen/common/schedule.c	Thu Mar 29 15:14:26 2007 +0100
    18.3 @@ -313,7 +313,9 @@ static long do_poll(struct sched_poll *s
    18.4      /* These operations must occur in order. */
    18.5      set_bit(_VCPUF_blocked, &v->vcpu_flags);
    18.6      set_bit(_VCPUF_polling, &v->vcpu_flags);
    18.7 -    set_bit(_DOMF_polling, &d->domain_flags);
    18.8 +    smp_wmb();
    18.9 +    d->is_polling = 1;
   18.10 +    smp_wmb();
   18.11  
   18.12      /* Check for events /after/ setting flags: avoids wakeup waiting race. */
   18.13      for ( i = 0; i < sched_poll->nr_ports; i++ )
    19.1 --- a/xen/include/xen/sched.h	Thu Mar 29 13:29:24 2007 +0100
    19.2 +++ b/xen/include/xen/sched.h	Thu Mar 29 15:14:26 2007 +0100
    19.3 @@ -138,7 +138,6 @@ struct domain
    19.4      unsigned int     xenheap_pages;   /* # pages allocated from Xen heap    */
    19.5  
    19.6      /* Scheduling. */
    19.7 -    int              shutdown_code; /* code value from OS (if DOMF_shutdown) */
    19.8      void            *sched_priv;    /* scheduler-specific data */
    19.9  
   19.10      struct domain   *next_in_list;
   19.11 @@ -165,17 +164,26 @@ struct domain
   19.12      struct rangeset *iomem_caps;
   19.13      struct rangeset *irq_caps;
   19.14  
   19.15 -    unsigned long    domain_flags;
   19.16 -
   19.17      /* Is this an HVM guest? */
   19.18      bool_t           is_hvm;
   19.19      /* Is this guest fully privileged (aka dom0)? */
   19.20      bool_t           is_privileged;
   19.21      /* Is this guest being debugged by dom0? */
   19.22      bool_t           debugger_attached;
   19.23 +    /* Is a 'compatibility mode' guest (semantics are arch specific)? */
   19.24 +    bool_t           is_compat;
   19.25 +    /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
   19.26 +    bool_t           is_polling;
   19.27 +    /* Is this guest dying (i.e., a zombie)? */
   19.28 +    bool_t           is_dying;
   19.29 +    /* Domain is paused by controller software? */
   19.30 +    bool_t           is_paused_by_controller;
   19.31  
   19.32 -    spinlock_t       pause_lock;
   19.33 -    unsigned int     pause_count;
   19.34 +    /* Guest has shut down (inc. reason code)? */
   19.35 +    bool_t           is_shutdown;
   19.36 +    int              shutdown_code;
   19.37 +
   19.38 +    atomic_t         pause_count;
   19.39  
   19.40      unsigned long    vm_assist;
   19.41  
   19.42 @@ -452,28 +460,6 @@ extern struct domain *domain_list;
   19.43  #define _VCPUF_migrating       13
   19.44  #define VCPUF_migrating        (1UL<<_VCPUF_migrating)
   19.45  
   19.46 -/*
   19.47 - * Per-domain flags (domain_flags).
   19.48 - */
   19.49 - /* Guest shut itself down for some reason. */
   19.50 -#define _DOMF_shutdown         0
   19.51 -#define DOMF_shutdown          (1UL<<_DOMF_shutdown)
   19.52 - /* Death rattle. */
   19.53 -#define _DOMF_dying            1
   19.54 -#define DOMF_dying             (1UL<<_DOMF_dying)
   19.55 - /* Domain is paused by controller software. */
   19.56 -#define _DOMF_ctrl_pause       2
   19.57 -#define DOMF_ctrl_pause        (1UL<<_DOMF_ctrl_pause)
   19.58 - /* Are any VCPUs polling event channels (SCHEDOP_poll)? */
   19.59 -#define _DOMF_polling          3
   19.60 -#define DOMF_polling           (1UL<<_DOMF_polling)
   19.61 - /* Domain is paused by the hypervisor? */
   19.62 -#define _DOMF_paused           4
   19.63 -#define DOMF_paused            (1UL<<_DOMF_paused)
   19.64 - /* Domain is a compatibility one? */
   19.65 -#define _DOMF_compat           5
   19.66 -#define DOMF_compat            (1UL<<_DOMF_compat)
   19.67 -
   19.68  static inline int vcpu_runnable(struct vcpu *v)
   19.69  {
   19.70      return ( !(v->vcpu_flags &
   19.71 @@ -482,10 +468,7 @@ static inline int vcpu_runnable(struct v
   19.72                   VCPUF_paused |
   19.73                   VCPUF_blocked_in_xen |
   19.74                   VCPUF_migrating )) &&
   19.75 -             !(v->domain->domain_flags &
   19.76 -               ( DOMF_shutdown |
   19.77 -                 DOMF_ctrl_pause |
   19.78 -                 DOMF_paused )));
   19.79 +             (atomic_read(&v->domain->pause_count) == 0) );
   19.80  }
   19.81  
   19.82  void vcpu_pause(struct vcpu *v);
   19.83 @@ -511,8 +494,7 @@ static inline void vcpu_unblock(struct v
   19.84  #define IS_PRIV(_d) ((_d)->is_privileged)
   19.85  
   19.86  #ifdef CONFIG_COMPAT
   19.87 -#define IS_COMPAT(_d)                                       \
   19.88 -    (test_bit(_DOMF_compat, &(_d)->domain_flags))
   19.89 +#define IS_COMPAT(_d) ((_d)->is_compat)
   19.90  #else
   19.91  #define IS_COMPAT(_d) 0
   19.92  #endif
    20.1 --- a/xen/include/xen/spinlock.h	Thu Mar 29 13:29:24 2007 +0100
    20.2 +++ b/xen/include/xen/spinlock.h	Thu Mar 29 15:14:26 2007 +0100
    20.3 @@ -82,6 +82,13 @@ typedef struct { int gcc_is_buggy; } rwl
    20.4  #define write_lock(_lock)            _raw_write_lock(_lock)
    20.5  #define write_unlock(_lock)          _raw_write_unlock(_lock)
    20.6  
    20.7 +/* Ensure a lock is quiescent between two critical operations. */
    20.8 +static inline void spin_barrier(spinlock_t *lock)
    20.9 +{
   20.10 +    spin_lock(lock);
   20.11 +    spin_unlock(lock);
   20.12 +}
   20.13 +
   20.14  #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
   20.15  #define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
   20.16