ia64/xen-unstable

changeset 19379:e655cb27d085

x86: Fix get_page() to not drop reference count if it wasn't incremented.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 17 15:29:20 2009 +0000 (2009-03-17)
parents c09a81540080
children 92a6cc5eae2e
files xen/arch/x86/mm.c
line diff
     1.1 --- a/xen/arch/x86/mm.c	Tue Mar 17 14:32:52 2009 +0000
     1.2 +++ b/xen/arch/x86/mm.c	Tue Mar 17 15:29:20 2009 +0000
     1.3 @@ -1948,9 +1948,12 @@ struct domain *page_get_owner_and_refere
     1.4  
     1.5      do {
     1.6          x = y;
     1.7 -        if ( unlikely((x & PGC_count_mask) == 0) ||  /* Not allocated? */
     1.8 -             /* Keep one spare reference to be acquired by get_page_light(). */
     1.9 -             unlikely(((x + 2) & PGC_count_mask) <= 1) ) /* Overflow? */
    1.10 +        /*
    1.11 +         * Count ==  0: Page is not allocated, so we cannot take a reference.
    1.12 +         * Count == -1: Reference count would wrap, which is invalid. 
    1.13 +         * Count == -2: Remaining unused ref is reserved for get_page_light().
    1.14 +         */
    1.15 +        if ( unlikely(((x + 2) & PGC_count_mask) <= 2) )
    1.16              return NULL;
    1.17      }
    1.18      while ( (y = cmpxchg(&page->count_info, x, x + 1)) != x );
    1.19 @@ -1966,7 +1969,8 @@ int get_page(struct page_info *page, str
    1.20      if ( likely(owner == domain) )
    1.21          return 1;
    1.22  
    1.23 -    put_page(page);
    1.24 +    if ( owner != NULL )
    1.25 +        put_page(page);
    1.26  
    1.27      if ( !_shadow_mode_refcounts(domain) && !domain->is_dying )
    1.28          gdprintk(XENLOG_INFO,