direct-io.hg

changeset 8409:b3edbeea3e79

Fix gnttab_release_mappings -- it doesn't need to drop
page refcnts for host mappings as they are already
destroyed by put_page_from_l1e(). Also call
gnttab_release_mappings later (after destroying
page-table references) and from common code rather than
arch/x86.

Also a few other misc gnttab cleanups.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Dec 21 18:45:43 2005 +0100 (2005-12-21)
parents 48eb10d7a2d6
children a4de51a2629f
files xen/arch/x86/domain.c xen/arch/x86/setup.c xen/common/domain.c xen/common/grant_table.c xen/include/xen/grant_table.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Wed Dec 21 18:25:34 2005 +0100
     1.2 +++ b/xen/arch/x86/domain.c	Wed Dec 21 18:45:43 2005 +0100
     1.3 @@ -957,8 +957,6 @@ void domain_relinquish_resources(struct 
     1.4  
     1.5      ptwr_destroy(d);
     1.6  
     1.7 -    gnttab_release_mappings(d);
     1.8 -
     1.9      /* Drop the in-use references to page-table bases. */
    1.10      for_each_vcpu ( d, v )
    1.11      {
     2.1 --- a/xen/arch/x86/setup.c	Wed Dec 21 18:25:34 2005 +0100
     2.2 +++ b/xen/arch/x86/setup.c	Wed Dec 21 18:45:43 2005 +0100
     2.3 @@ -488,8 +488,6 @@ void __init __start_xen(multiboot_info_t
     2.4  
     2.5      start_of_day();
     2.6  
     2.7 -    grant_table_init();
     2.8 -
     2.9      shadow_mode_init();
    2.10  
    2.11      /* initialize access control security module */
     3.1 --- a/xen/common/domain.c	Wed Dec 21 18:25:34 2005 +0100
     3.2 +++ b/xen/common/domain.c	Wed Dec 21 18:45:43 2005 +0100
     3.3 @@ -118,6 +118,7 @@ void domain_kill(struct domain *d)
     3.4          for_each_vcpu(d, v)
     3.5              sched_rem_domain(v);
     3.6          domain_relinquish_resources(d);
     3.7 +        gnttab_release_mappings(d);
     3.8          put_domain(d);
     3.9  
    3.10          send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC);
     4.1 --- a/xen/common/grant_table.c	Wed Dec 21 18:25:34 2005 +0100
     4.2 +++ b/xen/common/grant_table.c	Wed Dec 21 18:45:43 2005 +0100
     4.3 @@ -614,6 +614,91 @@ gnttab_dump_table(
     4.4      return 0;
     4.5  }
     4.6  
     4.7 +/*
     4.8 + * Check that the given grant reference (rd,ref) allows 'ld' to transfer
     4.9 + * ownership of a page frame. If so, lock down the grant entry.
    4.10 + */
    4.11 +static int 
    4.12 +gnttab_prepare_for_transfer(
    4.13 +    struct domain *rd, struct domain *ld, grant_ref_t ref)
    4.14 +{
    4.15 +    grant_table_t *rgt;
    4.16 +    grant_entry_t *sha;
    4.17 +    domid_t        sdom;
    4.18 +    u16            sflags;
    4.19 +    u32            scombo, prev_scombo;
    4.20 +    int            retries = 0;
    4.21 +    unsigned long  target_pfn;
    4.22 +
    4.23 +    if ( unlikely((rgt = rd->grant_table) == NULL) ||
    4.24 +         unlikely(ref >= NR_GRANT_ENTRIES) )
    4.25 +    {
    4.26 +        DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
    4.27 +                rd->domain_id, ref);
    4.28 +        return 0;
    4.29 +    }
    4.30 +
    4.31 +    spin_lock(&rgt->lock);
    4.32 +
    4.33 +    sha = &rgt->shared[ref];
    4.34 +    
    4.35 +    sflags = sha->flags;
    4.36 +    sdom   = sha->domid;
    4.37 +
    4.38 +    for ( ; ; )
    4.39 +    {
    4.40 +        target_pfn = sha->frame;
    4.41 +
    4.42 +        if ( unlikely(target_pfn >= max_page ) )
    4.43 +        {
    4.44 +            DPRINTK("Bad pfn (%lx)\n", target_pfn);
    4.45 +            goto fail;
    4.46 +        }
    4.47 +
    4.48 +        if ( unlikely(sflags != GTF_accept_transfer) ||
    4.49 +             unlikely(sdom != ld->domain_id) )
    4.50 +        {
    4.51 +            DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
    4.52 +                    sflags, sdom, ld->domain_id);
    4.53 +            goto fail;
    4.54 +        }
    4.55 +
    4.56 +        /* Merge two 16-bit values into a 32-bit combined update. */
    4.57 +        /* NB. Endianness! */
    4.58 +        prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
    4.59 +
    4.60 +        /* NB. prev_scombo is updated in place to seen value. */
    4.61 +        if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, 
    4.62 +                                   prev_scombo | GTF_transfer_committed)) )
    4.63 +        {
    4.64 +            DPRINTK("Fault while modifying shared flags and domid.\n");
    4.65 +            goto fail;
    4.66 +        }
    4.67 +
    4.68 +        /* Did the combined update work (did we see what we expected?). */
    4.69 +        if ( likely(prev_scombo == scombo) )
    4.70 +            break;
    4.71 +
    4.72 +        if ( retries++ == 4 )
    4.73 +        {
    4.74 +            DPRINTK("Shared grant entry is unstable.\n");
    4.75 +            goto fail;
    4.76 +        }
    4.77 +
    4.78 +        /* Didn't see what we expected. Split out the seen flags & dom. */
    4.79 +        /* NB. Endianness! */
    4.80 +        sflags = (u16)prev_scombo;
    4.81 +        sdom   = (u16)(prev_scombo >> 16);
    4.82 +    }
    4.83 +
    4.84 +    spin_unlock(&rgt->lock);
    4.85 +    return 1;
    4.86 +
    4.87 + fail:
    4.88 +    spin_unlock(&rgt->lock);
    4.89 +    return 0;
    4.90 +}
    4.91 +
    4.92  static long
    4.93  gnttab_transfer(
    4.94      gnttab_transfer_t *uop, unsigned int count)
    4.95 @@ -763,87 +848,6 @@ do_grant_table_op(
    4.96  }
    4.97  
    4.98  int 
    4.99 -gnttab_prepare_for_transfer(
   4.100 -    struct domain *rd, struct domain *ld, grant_ref_t ref)
   4.101 -{
   4.102 -    grant_table_t *rgt;
   4.103 -    grant_entry_t *sha;
   4.104 -    domid_t        sdom;
   4.105 -    u16            sflags;
   4.106 -    u32            scombo, prev_scombo;
   4.107 -    int            retries = 0;
   4.108 -    unsigned long  target_pfn;
   4.109 -
   4.110 -    if ( unlikely((rgt = rd->grant_table) == NULL) ||
   4.111 -         unlikely(ref >= NR_GRANT_ENTRIES) )
   4.112 -    {
   4.113 -        DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
   4.114 -                rd->domain_id, ref);
   4.115 -        return 0;
   4.116 -    }
   4.117 -
   4.118 -    spin_lock(&rgt->lock);
   4.119 -
   4.120 -    sha = &rgt->shared[ref];
   4.121 -    
   4.122 -    sflags = sha->flags;
   4.123 -    sdom   = sha->domid;
   4.124 -
   4.125 -    for ( ; ; )
   4.126 -    {
   4.127 -        target_pfn = sha->frame;
   4.128 -
   4.129 -        if ( unlikely(target_pfn >= max_page ) )
   4.130 -        {
   4.131 -            DPRINTK("Bad pfn (%lx)\n", target_pfn);
   4.132 -            goto fail;
   4.133 -        }
   4.134 -
   4.135 -        if ( unlikely(sflags != GTF_accept_transfer) ||
   4.136 -             unlikely(sdom != ld->domain_id) )
   4.137 -        {
   4.138 -            DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
   4.139 -                    sflags, sdom, ld->domain_id);
   4.140 -            goto fail;
   4.141 -        }
   4.142 -
   4.143 -        /* Merge two 16-bit values into a 32-bit combined update. */
   4.144 -        /* NB. Endianness! */
   4.145 -        prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
   4.146 -
   4.147 -        /* NB. prev_scombo is updated in place to seen value. */
   4.148 -        if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, 
   4.149 -                                   prev_scombo | GTF_transfer_committed)) )
   4.150 -        {
   4.151 -            DPRINTK("Fault while modifying shared flags and domid.\n");
   4.152 -            goto fail;
   4.153 -        }
   4.154 -
   4.155 -        /* Did the combined update work (did we see what we expected?). */
   4.156 -        if ( likely(prev_scombo == scombo) )
   4.157 -            break;
   4.158 -
   4.159 -        if ( retries++ == 4 )
   4.160 -        {
   4.161 -            DPRINTK("Shared grant entry is unstable.\n");
   4.162 -            goto fail;
   4.163 -        }
   4.164 -
   4.165 -        /* Didn't see what we expected. Split out the seen flags & dom. */
   4.166 -        /* NB. Endianness! */
   4.167 -        sflags = (u16)prev_scombo;
   4.168 -        sdom   = (u16)(prev_scombo >> 16);
   4.169 -    }
   4.170 -
   4.171 -    spin_unlock(&rgt->lock);
   4.172 -    return 1;
   4.173 -
   4.174 - fail:
   4.175 -    spin_unlock(&rgt->lock);
   4.176 -    return 0;
   4.177 -}
   4.178 -
   4.179 -int 
   4.180  grant_table_create(
   4.181      struct domain *d)
   4.182  {
   4.183 @@ -943,7 +947,8 @@ gnttab_release_mappings(
   4.184              {
   4.185                  BUG_ON(!(act->pin & GNTPIN_hstr_mask));
   4.186                  act->pin -= GNTPIN_hstr_inc;
   4.187 -                put_page(pfn_to_page(act->frame));
   4.188 +                /* Done implicitly when page tables are destroyed. */
   4.189 +                /* put_page(pfn_to_page(act->frame)); */
   4.190              }
   4.191          }
   4.192          else
   4.193 @@ -959,7 +964,8 @@ gnttab_release_mappings(
   4.194              {
   4.195                  BUG_ON(!(act->pin & GNTPIN_hstw_mask));
   4.196                  act->pin -= GNTPIN_hstw_inc;
   4.197 -                put_page_and_type(pfn_to_page(act->frame));
   4.198 +                /* Done implicitly when page tables are destroyed. */
   4.199 +                /* put_page_and_type(pfn_to_page(act->frame)); */
   4.200              }
   4.201  
   4.202              if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
   4.203 @@ -982,24 +988,17 @@ void
   4.204  grant_table_destroy(
   4.205      struct domain *d)
   4.206  {
   4.207 -    grant_table_t *t;
   4.208 +    grant_table_t *t = d->grant_table;
   4.209  
   4.210 -    if ( (t = d->grant_table) != NULL )
   4.211 -    {
   4.212 -        /* Free memory relating to this grant table. */
   4.213 -        d->grant_table = NULL;
   4.214 -        free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
   4.215 -        free_xenheap_page(t->maptrack);
   4.216 -        xfree(t->active);
   4.217 -        xfree(t);
   4.218 -    }
   4.219 -}
   4.220 +    if ( t == NULL )
   4.221 +        return;
   4.222 +    
   4.223 +    free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
   4.224 +    free_xenheap_page(t->maptrack);
   4.225 +    xfree(t->active);
   4.226 +    xfree(t);
   4.227  
   4.228 -void
   4.229 -grant_table_init(
   4.230 -    void)
   4.231 -{
   4.232 -    /* Nothing. */
   4.233 +    d->grant_table = NULL;
   4.234  }
   4.235  
   4.236  /*
     5.1 --- a/xen/include/xen/grant_table.h	Wed Dec 21 18:25:34 2005 +0100
     5.2 +++ b/xen/include/xen/grant_table.h	Wed Dec 21 18:45:43 2005 +0100
     5.3 @@ -84,24 +84,12 @@ typedef struct {
     5.4      spinlock_t            lock;
     5.5  } grant_table_t;
     5.6  
     5.7 -/* Start-of-day system initialisation. */
     5.8 -void grant_table_init(
     5.9 -    void);
    5.10 -
    5.11  /* Create/destroy per-domain grant table context. */
    5.12  int grant_table_create(
    5.13      struct domain *d);
    5.14  void grant_table_destroy(
    5.15      struct domain *d);
    5.16  
    5.17 -/*
    5.18 - * Check that the given grant reference (rd,ref) allows 'ld' to transfer
    5.19 - * ownership of a page frame. If so, lock down the grant entry.
    5.20 - */
    5.21 -int 
    5.22 -gnttab_prepare_for_transfer(
    5.23 -    struct domain *rd, struct domain *ld, grant_ref_t ref);
    5.24 -
    5.25  /* Domain death release of granted mappings of other domains' memory. */
    5.26  void
    5.27  gnttab_release_mappings(