ia64/xen-unstable

changeset 3845:46c3f40cba0b

bitkeeper revision 1.1213 (42137438B9PrvSq_PgHTjzbXpJ1YhA)

xmalloc.c:
Fix xmalloc allocator to not merge across page boundaries.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@scramble.cl.cam.ac.uk
date Wed Feb 16 16:26:32 2005 +0000 (2005-02-16)
parents 0698ed077bc2
children 7645e7facda9
files xen/common/xmalloc.c
line diff
     1.1 --- a/xen/common/xmalloc.c	Wed Feb 16 15:48:27 2005 +0000
     1.2 +++ b/xen/common/xmalloc.c	Wed Feb 16 16:26:32 2005 +0000
     1.3 @@ -25,7 +25,7 @@
     1.4  #include <xen/ac_timer.h>
     1.5  #include <xen/cache.h>
     1.6  
     1.7 -#define BUG_ON(x) do { if (x) BUG(); }while(0)
     1.8 +#define BUG_ON(x) do { if (x) BUG(); } while(0)
     1.9  
    1.10  static LIST_HEAD(freelist);
    1.11  static spinlock_t freelist_lock = SPIN_LOCK_UNLOCKED;
    1.12 @@ -48,8 +48,9 @@ static void maybe_split(struct xmalloc_h
    1.13  		extra = (void *)hdr + size;
    1.14  		extra->size = leftover;
    1.15  		list_add(&extra->freelist, &freelist);
    1.16 -	} else
    1.17 +	} else {
    1.18  		size = block;
    1.19 +	}
    1.20  
    1.21  	hdr->size = size;
    1.22  	/* Debugging aid. */
    1.23 @@ -62,7 +63,7 @@ static void *xmalloc_new_page(size_t siz
    1.24  	unsigned long flags;
    1.25  
    1.26  	hdr = (void *)alloc_xenheap_pages(0);
    1.27 -	if (!hdr)
    1.28 +	if (hdr == NULL)
    1.29  		return NULL;
    1.30  
    1.31  	spin_lock_irqsave(&freelist_lock, flags);
    1.32 @@ -78,7 +79,7 @@ static void *xmalloc_whole_pages(size_t 
    1.33  	unsigned int pageorder = get_order(size);
    1.34  
    1.35  	hdr = (void *)alloc_xenheap_pages(pageorder);
    1.36 -	if (!hdr)
    1.37 +	if (hdr == NULL)
    1.38  		return NULL;
    1.39  
    1.40  	hdr->size = (1 << (pageorder + PAGE_SHIFT));
    1.41 @@ -130,7 +131,7 @@ void xfree(const void *p)
    1.42  	unsigned long flags;
    1.43  	struct xmalloc_hdr *i, *tmp, *hdr;
    1.44  
    1.45 -	if (!p)
    1.46 +	if (p == NULL)
    1.47  		return;
    1.48  
    1.49  	hdr = (struct xmalloc_hdr *)p - 1;
    1.50 @@ -150,14 +151,19 @@ void xfree(const void *p)
    1.51  	/* Merge with other free block, or put in list. */
    1.52  	spin_lock_irqsave(&freelist_lock, flags);
    1.53  	list_for_each_entry_safe(i, tmp, &freelist, freelist) {
    1.54 +		unsigned long _i   = (unsigned long)i;
    1.55 +		unsigned long _hdr = (unsigned long)hdr;
    1.56 +		/* Do not merge across page boundaries. */
    1.57 +		if (((_i ^ _hdr) & PAGE_MASK) != 0)
    1.58 +			continue;
    1.59  		/* We follow this block?  Swallow it. */
    1.60 -		if ((void *)i + i->size == (void *)hdr) {
    1.61 +		if ((_i + i->size) == _hdr) {
    1.62  			list_del(&i->freelist);
    1.63  			i->size += hdr->size;
    1.64  			hdr = i;
    1.65  		}
    1.66 -		/* It follows us?  Delete it and add it to us. */
    1.67 -		if ((void *)hdr + hdr->size == (void *)i) {
    1.68 +		/* We precede this block? Swallow it. */
    1.69 +		if ((_hdr + hdr->size) == _i) {
    1.70  			list_del(&i->freelist);
    1.71  			hdr->size += i->size;
    1.72  		}
    1.73 @@ -167,7 +173,9 @@ void xfree(const void *p)
    1.74  	if (hdr->size == PAGE_SIZE) {
    1.75  		BUG_ON((((unsigned long)hdr) & (PAGE_SIZE-1)) != 0);
    1.76  		free_xenheap_pages((unsigned long)hdr, 0);
    1.77 -	} else
    1.78 +	} else {
    1.79  		list_add(&hdr->freelist, &freelist);
    1.80 +	}
    1.81 +
    1.82  	spin_unlock_irqrestore(&freelist_lock, flags);
    1.83  }