ia64/xen-unstable

changeset 14197:0de2f7d8d89f

x86: No need to take full reference when doing mmu_update on a foreign
domain. Also fix a pre-existing race setting PGT_pinned versus
clearing it during domain_kill().
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Mar 01 12:14:53 2007 +0000 (2007-03-01)
parents 9d36026b1b43
children afed0aeff629
files xen/arch/x86/mm.c xen/include/xen/sched.h
line diff
     1.1 --- a/xen/arch/x86/mm.c	Thu Mar 01 11:38:55 2007 +0000
     1.2 +++ b/xen/arch/x86/mm.c	Thu Mar 01 12:14:53 2007 +0000
     1.3 @@ -1853,7 +1853,7 @@ static void process_deferred_ops(void)
     1.4  
     1.5      if ( unlikely(info->foreign != NULL) )
     1.6      {
     1.7 -        put_domain(info->foreign);
     1.8 +        rcu_unlock_domain(info->foreign);
     1.9          info->foreign = NULL;
    1.10      }
    1.11  }
    1.12 @@ -1885,8 +1885,7 @@ static int set_foreigndom(domid_t domid)
    1.13          switch ( domid )
    1.14          {
    1.15          case DOMID_IO:
    1.16 -            get_knownalive_domain(dom_io);
    1.17 -            info->foreign = dom_io;
    1.18 +            info->foreign = rcu_lock_domain(dom_io);
    1.19              break;
    1.20          default:
    1.21              MEM_LOG("Dom %u cannot set foreign dom", d->domain_id);
    1.22 @@ -1896,18 +1895,16 @@ static int set_foreigndom(domid_t domid)
    1.23      }
    1.24      else
    1.25      {
    1.26 -        info->foreign = e = get_domain_by_id(domid);
    1.27 +        info->foreign = e = rcu_lock_domain_by_id(domid);
    1.28          if ( e == NULL )
    1.29          {
    1.30              switch ( domid )
    1.31              {
    1.32              case DOMID_XEN:
    1.33 -                get_knownalive_domain(dom_xen);
    1.34 -                info->foreign = dom_xen;
    1.35 +                info->foreign = rcu_lock_domain(dom_xen);
    1.36                  break;
    1.37              case DOMID_IO:
    1.38 -                get_knownalive_domain(dom_io);
    1.39 -                info->foreign = dom_io;
    1.40 +                info->foreign = rcu_lock_domain(dom_io);
    1.41                  break;
    1.42              default:
    1.43                  MEM_LOG("Unknown domain '%u'", domid);
    1.44 @@ -2043,6 +2040,12 @@ int do_mmuext_op(
    1.45              /* A page is dirtied when its pin status is set. */
    1.46              mark_dirty(d, mfn);
    1.47             
    1.48 +            /* We can race domain destruction (domain_relinquish_resources). */
    1.49 +            if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) &&
    1.50 +                 test_bit(_DOMF_dying, &FOREIGNDOM->domain_flags) &&
    1.51 +                 test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
    1.52 +                put_page_and_type(page);
    1.53 +
    1.54              break;
    1.55  
    1.56          case MMUEXT_UNPIN_TABLE:
     2.1 --- a/xen/include/xen/sched.h	Thu Mar 01 11:38:55 2007 +0000
     2.2 +++ b/xen/include/xen/sched.h	Thu Mar 01 12:14:53 2007 +0000
     2.3 @@ -292,10 +292,15 @@ static inline void rcu_unlock_domain(str
     2.4      rcu_read_unlock(&domlist_read_lock);
     2.5  }
     2.6  
     2.7 +static inline struct domain *rcu_lock_domain(struct domain *d)
     2.8 +{
     2.9 +    rcu_read_lock(d);
    2.10 +    return d;
    2.11 +}
    2.12 +
    2.13  static inline struct domain *rcu_lock_current_domain(void)
    2.14  {
    2.15 -    rcu_read_lock(&domlist_read_lock);
    2.16 -    return current->domain;
    2.17 +    return rcu_lock_domain(current->domain);
    2.18  }
    2.19  
    2.20  struct domain *get_domain_by_id(domid_t dom);