ia64/xen-unstable

changeset 11767:7efaaae37415

[BALLOON] Replace alloc_empty_page_range with new helper alloc_empty_pages_and_pagevec.
This is a better fit with all the callers, who now allocate discontiguous empty pages.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Oct 06 11:52:41 2006 +0100 (2006-10-06)
parents 3971f49ce592
children ff9746d600e9
files linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c linux-2.6-xen-sparse/drivers/xen/netback/netback.c linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c linux-2.6-xen-sparse/include/xen/balloon.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Fri Oct 06 10:30:43 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Fri Oct 06 11:52:41 2006 +0100
     1.3 @@ -534,87 +534,88 @@ static int dealloc_pte_fn(
     1.4  	return 0;
     1.5  }
     1.6  
     1.7 -struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
     1.8 +struct page **alloc_empty_pages_and_pagevec(int nr_pages)
     1.9  {
    1.10 -	unsigned long vstart, flags;
    1.11 -	unsigned int  order = get_order(nr_pages * PAGE_SIZE);
    1.12 -	int ret;
    1.13 -	unsigned long i;
    1.14 -	struct page *page;
    1.15 +	unsigned long vaddr, flags;
    1.16 +	struct page *page, **pagevec;
    1.17 +	int i, ret;
    1.18  
    1.19 -	vstart = __get_free_pages(GFP_KERNEL, order);
    1.20 -	if (vstart == 0)
    1.21 +	pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL);
    1.22 +	if (pagevec == NULL)
    1.23  		return NULL;
    1.24  
    1.25 -	scrub_pages(vstart, 1 << order);
    1.26 +	for (i = 0; i < nr_pages; i++) {
    1.27 +		page = pagevec[i] = alloc_page(GFP_KERNEL);
    1.28 +		if (page == NULL)
    1.29 +			goto err;
    1.30 +
    1.31 +		vaddr = (unsigned long)page_address(page);
    1.32 +
    1.33 +		scrub_pages(vaddr, 1);
    1.34 +
    1.35 +		balloon_lock(flags);
    1.36 +
    1.37 +		if (xen_feature(XENFEAT_auto_translated_physmap)) {
    1.38 +			unsigned long gmfn = page_to_pfn(page);
    1.39 +			struct xen_memory_reservation reservation = {
    1.40 +				.nr_extents   = 1,
    1.41 +				.extent_order = 0,
    1.42 +				.domid        = DOMID_SELF
    1.43 +			};
    1.44 +			set_xen_guest_handle(reservation.extent_start, &gmfn);
    1.45 +			ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
    1.46 +						   &reservation);
    1.47 +			if (ret == 1)
    1.48 +				ret = 0; /* success */
    1.49 +		} else {
    1.50 +			ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
    1.51 +						  dealloc_pte_fn, NULL);
    1.52 +		}
    1.53 +
    1.54 +		if (ret != 0) {
    1.55 +			balloon_unlock(flags);
    1.56 +			__free_page(page);
    1.57 +			goto err;
    1.58 +		}
    1.59 +
    1.60 +		totalram_pages = --current_pages;
    1.61 +
    1.62 +		balloon_unlock(flags);
    1.63 +	}
    1.64 +
    1.65 + out:
    1.66 +	schedule_work(&balloon_worker);
    1.67 +	flush_tlb_all();
    1.68 +	return pagevec;
    1.69 +
    1.70 + err:
    1.71 +	balloon_lock(flags);
    1.72 +	while (--i >= 0)
    1.73 +		balloon_append(pagevec[i]);
    1.74 +	balloon_unlock(flags);
    1.75 +	kfree(pagevec);
    1.76 +	pagevec = NULL;
    1.77 +	goto out;
    1.78 +}
    1.79 +
    1.80 +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
    1.81 +{
    1.82 +	unsigned long flags;
    1.83 +	int i;
    1.84 +
    1.85 +	if (pagevec == NULL)
    1.86 +		return;
    1.87  
    1.88  	balloon_lock(flags);
    1.89 -	if (xen_feature(XENFEAT_auto_translated_physmap)) {
    1.90 -		unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT;
    1.91 -		struct xen_memory_reservation reservation = {
    1.92 -			.nr_extents   = 1,
    1.93 -			.extent_order = order,
    1.94 -			.domid        = DOMID_SELF
    1.95 -		};
    1.96 -		set_xen_guest_handle(reservation.extent_start, &gmfn);
    1.97 -		ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
    1.98 -					   &reservation);
    1.99 -		if (ret == -ENOSYS)
   1.100 -			goto err;
   1.101 -		BUG_ON(ret != 1);
   1.102 -	} else {
   1.103 -		ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order,
   1.104 -					  dealloc_pte_fn, NULL);
   1.105 -		if (ret == -ENOSYS)
   1.106 -			goto err;
   1.107 -		BUG_ON(ret);
   1.108 -	}
   1.109 -	current_pages -= 1UL << order;
   1.110 -	totalram_pages = current_pages;
   1.111 -	balloon_unlock(flags);
   1.112 -
   1.113 -	schedule_work(&balloon_worker);
   1.114 -
   1.115 -	flush_tlb_all();
   1.116 -
   1.117 -	page = virt_to_page(vstart);
   1.118 -
   1.119 -	for (i = 0; i < (1UL << order); i++)
   1.120 -		set_page_count(page + i, 1);
   1.121 -
   1.122 -	return page;
   1.123 -
   1.124 - err:
   1.125 -	free_pages(vstart, order);
   1.126 -	balloon_unlock(flags);
   1.127 -	return NULL;
   1.128 -}
   1.129 -
   1.130 -void balloon_dealloc_empty_page_range(
   1.131 -	struct page *page, unsigned long nr_pages)
   1.132 -{
   1.133 -	unsigned long i, flags;
   1.134 -	unsigned int  order = get_order(nr_pages * PAGE_SIZE);
   1.135 -
   1.136 -	balloon_lock(flags);
   1.137 -	for (i = 0; i < (1UL << order); i++) {
   1.138 -		BUG_ON(page_count(page + i) != 1);
   1.139 -		balloon_append(page + i);
   1.140 +	for (i = 0; i < nr_pages; i++) {
   1.141 +		BUG_ON(page_count(pagevec[i]) != 1);
   1.142 +		balloon_append(pagevec[i]);
   1.143  	}
   1.144  	balloon_unlock(flags);
   1.145  
   1.146 -	schedule_work(&balloon_worker);
   1.147 -}
   1.148 +	kfree(pagevec);
   1.149  
   1.150 -struct page *balloon_alloc_empty_page(void)
   1.151 -{
   1.152 -	return balloon_alloc_empty_page_range(1);
   1.153 -}
   1.154 -
   1.155 -void balloon_free_empty_page(
   1.156 -	struct page *page)
   1.157 -{
   1.158 -	balloon_dealloc_empty_page_range(page, 1);
   1.159 +	schedule_work(&balloon_worker);
   1.160  }
   1.161  
   1.162  void balloon_release_driver_page(struct page *page)
   1.163 @@ -630,10 +631,8 @@ void balloon_release_driver_page(struct 
   1.164  }
   1.165  
   1.166  EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
   1.167 -EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
   1.168 -EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
   1.169 -EXPORT_SYMBOL_GPL(balloon_alloc_empty_page);
   1.170 -EXPORT_SYMBOL_GPL(balloon_free_empty_page);
   1.171 +EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec);
   1.172 +EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec);
   1.173  EXPORT_SYMBOL_GPL(balloon_release_driver_page);
   1.174  
   1.175  MODULE_LICENSE("Dual BSD/GPL");
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Oct 06 10:30:43 2006 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c	Fri Oct 06 11:52:41 2006 +0100
     2.3 @@ -515,20 +515,13 @@ static int __init blkif_init(void)
     2.4  					blkif_reqs, GFP_KERNEL);
     2.5  	pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
     2.6  					mmap_pages, GFP_KERNEL);
     2.7 -	pending_pages         = kmalloc(sizeof(pending_pages[0]) *
     2.8 -					mmap_pages, GFP_KERNEL);
     2.9 +	pending_pages         = alloc_empty_pages_and_pagevec(mmap_pages);
    2.10 +
    2.11  	if (!pending_reqs || !pending_grant_handles || !pending_pages)
    2.12  		goto out_of_memory;
    2.13  
    2.14 -	for (i = 0; i < mmap_pages; i++) {
    2.15 -		pending_pages[i] = balloon_alloc_empty_page();
    2.16 -		if (pending_pages[i] == NULL) {
    2.17 -			while (--i >= 0)
    2.18 -				balloon_free_empty_page(pending_pages[i]);
    2.19 -			goto out_of_memory;
    2.20 -		}
    2.21 +	for (i = 0; i < mmap_pages; i++)
    2.22  		pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
    2.23 -	}
    2.24  
    2.25  	blkif_interface_init();
    2.26  
    2.27 @@ -545,7 +538,7 @@ static int __init blkif_init(void)
    2.28   out_of_memory:
    2.29  	kfree(pending_reqs);
    2.30  	kfree(pending_grant_handles);
    2.31 -	kfree(pending_pages);
    2.32 +	free_empty_pages_and_pagevec(pending_pages, mmap_pages);
    2.33  	printk("%s: out of memory\n", __FUNCTION__);
    2.34  	return -ENOMEM;
    2.35  }
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Fri Oct 06 10:30:43 2006 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c	Fri Oct 06 11:52:41 2006 +0100
     3.3 @@ -728,28 +728,16 @@ static void make_response(blkif_t *blkif
     3.4  static int req_increase(void)
     3.5  {
     3.6  	int i, j;
     3.7 -	struct page **pages = NULL;
     3.8  
     3.9  	if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) 
    3.10  		return -EINVAL;
    3.11  
    3.12 -	pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) *
    3.13 -					   blkif_reqs, GFP_KERNEL);
    3.14 -	pages = kmalloc(sizeof(pages[0]) * mmap_pages, GFP_KERNEL);
    3.15 -
    3.16 -	if (!pending_reqs[mmap_alloc] || !pages)
    3.17 -		goto out_of_memory;
    3.18 +	pending_reqs[mmap_alloc]  = kzalloc(sizeof(pending_req_t)
    3.19 +					    * blkif_reqs, GFP_KERNEL);
    3.20 +	foreign_pages[mmap_alloc] = alloc_empty_pages_and_pagevec(mmap_pages);
    3.21  
    3.22 -	for (i = 0; i < mmap_pages; i++) {
    3.23 -		pages[i] = balloon_alloc_empty_page();
    3.24 -		if (!pages[i]) {
    3.25 -			while (--i >= 0)
    3.26 -				balloon_free_empty_page(pages[i]);
    3.27 -			goto out_of_memory;
    3.28 -		}
    3.29 -	}
    3.30 -
    3.31 -	foreign_pages[mmap_alloc] = pages;
    3.32 +	if (!pending_reqs[mmap_alloc] || !foreign_pages[mmap_alloc])
    3.33 +		goto out_of_memory;
    3.34  
    3.35  	DPRINTK("%s: reqs=%d, pages=%d\n",
    3.36  		__FUNCTION__, blkif_reqs, mmap_pages);
    3.37 @@ -768,7 +756,7 @@ static int req_increase(void)
    3.38  	return 0;
    3.39  
    3.40   out_of_memory:
    3.41 -	kfree(pages);
    3.42 +	free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
    3.43  	kfree(pending_reqs[mmap_alloc]);
    3.44  	WPRINTK("%s: out of memory\n", __FUNCTION__);
    3.45  	return -ENOMEM;
    3.46 @@ -776,15 +764,12 @@ static int req_increase(void)
    3.47  
    3.48  static void mmap_req_del(int mmap)
    3.49  {
    3.50 -	int i;
    3.51 -
    3.52  	BUG_ON(!spin_is_locked(&pending_free_lock));
    3.53  
    3.54  	kfree(pending_reqs[mmap]);
    3.55 +	pending_reqs[mmap] = NULL;
    3.56  
    3.57 -	for (i = 0; i < mmap_pages; i++)
    3.58 -		balloon_free_empty_page(foreign_pages[mmap][i]);
    3.59 -	kfree(foreign_pages[mmap]);
    3.60 +	free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages);
    3.61  	foreign_pages[mmap] = NULL;
    3.62  
    3.63  	mmap_lock = 0;
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Fri Oct 06 10:30:43 2006 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c	Fri Oct 06 11:52:41 2006 +0100
     4.3 @@ -1440,19 +1440,14 @@ static int __init netback_init(void)
     4.4  	net_timer.data = 0;
     4.5  	net_timer.function = net_alarm;
     4.6  
     4.7 -	mmap_pages = kmalloc(sizeof(mmap_pages[0]) * MAX_PENDING_REQS,
     4.8 -			     GFP_KERNEL);
     4.9 -	if (mmap_pages == NULL)
    4.10 -		goto out_of_memory;
    4.11 +	mmap_pages = alloc_empty_pages_and_pagevec(MAX_PENDING_REQS);
    4.12 +	if (mmap_pages == NULL) {
    4.13 +		printk("%s: out of memory\n", __FUNCTION__);
    4.14 +		return -ENOMEM;
    4.15 +	}
    4.16  
    4.17  	for (i = 0; i < MAX_PENDING_REQS; i++) {
    4.18 -		page = mmap_pages[i] = balloon_alloc_empty_page();
    4.19 -		if (page == NULL) {
    4.20 -			while (--i >= 0)
    4.21 -				balloon_free_empty_page(mmap_pages[i]);
    4.22 -			goto out_of_memory;
    4.23 -		}
    4.24 -		set_page_count(page, 1);
    4.25 +		page = mmap_pages[i];
    4.26  		SetPageForeign(page, netif_page_release);
    4.27  		page->index = i;
    4.28  	}
    4.29 @@ -1478,11 +1473,6 @@ static int __init netback_init(void)
    4.30  #endif
    4.31  
    4.32  	return 0;
    4.33 -
    4.34 - out_of_memory:
    4.35 -	kfree(mmap_pages);
    4.36 -	printk("%s: out of memory\n", __FUNCTION__);
    4.37 -	return -ENOMEM;
    4.38  }
    4.39  
    4.40  module_init(netback_init);
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Fri Oct 06 10:30:43 2006 +0100
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Fri Oct 06 11:52:41 2006 +0100
     5.3 @@ -23,10 +23,9 @@ LIST_HEAD(tpmif_list);
     5.4  static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi)
     5.5  {
     5.6  	tpmif_t *tpmif;
     5.7 -	int i;
     5.8  
     5.9  	tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL);
    5.10 -	if (!tpmif)
    5.11 +	if (tpmif == NULL)
    5.12  		goto out_of_memory;
    5.13  
    5.14  	memset(tpmif, 0, sizeof (*tpmif));
    5.15 @@ -36,46 +35,27 @@ static tpmif_t *alloc_tpmif(domid_t domi
    5.16  	snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
    5.17  	atomic_set(&tpmif->refcnt, 1);
    5.18  
    5.19 -	tpmif->mmap_pages = kmalloc(sizeof(tpmif->mmap_pages[0])
    5.20 -				    * TPMIF_TX_RING_SIZE, GFP_KERNEL);
    5.21 +	tpmif->mmap_pages = alloc_empty_pages_and_pagevec(TPMIF_TX_RING_SIZE);
    5.22  	if (tpmif->mmap_pages == NULL)
    5.23  		goto out_of_memory;
    5.24  
    5.25 -	for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
    5.26 -		tpmif->mmap_pages[i] = balloon_alloc_empty_page();
    5.27 -		if (tpmif->mmap_pages[i] == NULL) {
    5.28 -			while (--i >= 0)
    5.29 -				balloon_free_empty_page(tpmif->mmap_pages[i]);
    5.30 -			goto out_of_memory;
    5.31 -		}
    5.32 -	}
    5.33 -
    5.34  	list_add(&tpmif->tpmif_list, &tpmif_list);
    5.35  	num_frontends++;
    5.36  
    5.37  	return tpmif;
    5.38  
    5.39   out_of_memory:
    5.40 -	if (tpmif != NULL) {
    5.41 -		kfree(tpmif->mmap_pages);
    5.42 +	if (tpmif != NULL)
    5.43  		kmem_cache_free(tpmif_cachep, tpmif);
    5.44 -	}
    5.45  	printk("%s: out of memory\n", __FUNCTION__);
    5.46  	return ERR_PTR(-ENOMEM);
    5.47  }
    5.48  
    5.49  static void free_tpmif(tpmif_t * tpmif)
    5.50  {
    5.51 -	int i;
    5.52 -
    5.53  	num_frontends--;
    5.54 -
    5.55  	list_del(&tpmif->tpmif_list);
    5.56 -
    5.57 -	for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
    5.58 -		balloon_free_empty_page(tpmif->mmap_pages[i]);
    5.59 -	kfree(tpmif->mmap_pages);
    5.60 -
    5.61 +	free_empty_pages_and_pagevec(tpmif->mmap_pages, TPMIF_TX_RING_SIZE);
    5.62  	kmem_cache_free(tpmif_cachep, tpmif);
    5.63  }
    5.64  
     6.1 --- a/linux-2.6-xen-sparse/include/xen/balloon.h	Fri Oct 06 10:30:43 2006 +0100
     6.2 +++ b/linux-2.6-xen-sparse/include/xen/balloon.h	Fri Oct 06 11:52:41 2006 +0100
     6.3 @@ -40,15 +40,9 @@
     6.4   */
     6.5  void balloon_update_driver_allowance(long delta);
     6.6  
     6.7 -/* Allocate an empty low-memory page range. */
     6.8 -struct page *balloon_alloc_empty_page_range(unsigned long nr_pages);
     6.9 -
    6.10 -/* Deallocate an empty page range, adding to the balloon. */
    6.11 -void balloon_dealloc_empty_page_range(
    6.12 -	struct page *page, unsigned long nr_pages);
    6.13 -
    6.14 -struct page *balloon_alloc_empty_page(void);
    6.15 -void balloon_free_empty_page(struct page *page);
    6.16 +/* Allocate/free a set of empty pages in low memory (i.e., no RAM mapped). */
    6.17 +struct page **alloc_empty_pages_and_pagevec(int nr_pages);
    6.18 +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages);
    6.19  
    6.20  void balloon_release_driver_page(struct page *page);
    6.21