[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [BALLOON] Replace alloc_empty_page_range with new helper alloc_empty_pages_and_pagevec.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 7efaaae374155b93bceb9a2918fb6c5023978ae7 # Parent 3971f49ce5924b9f08f9379093287b83e47c82f9 [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@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 157 +++++++++---------- linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 15 - linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 33 +-- linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 22 -- linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c | 28 --- linux-2.6-xen-sparse/include/xen/balloon.h | 12 - 6 files changed, 104 insertions(+), 163 deletions(-) diff -r 3971f49ce592 -r 7efaaae37415 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Fri Oct 06 10:30:43 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Fri Oct 06 11:52:41 2006 +0100 @@ -534,87 +534,88 @@ static int dealloc_pte_fn( return 0; } -struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) -{ - unsigned long vstart, flags; - unsigned int order = get_order(nr_pages * PAGE_SIZE); - int ret; - unsigned long i; - struct page *page; - - vstart = __get_free_pages(GFP_KERNEL, order); - if (vstart == 0) +struct page **alloc_empty_pages_and_pagevec(int nr_pages) +{ + unsigned long vaddr, flags; + struct page *page, **pagevec; + int i, ret; + + pagevec = kmalloc(sizeof(page) * nr_pages, GFP_KERNEL); + if (pagevec == NULL) return NULL; - scrub_pages(vstart, 1 << order); - + for (i = 0; i < nr_pages; i++) { + page = pagevec[i] = alloc_page(GFP_KERNEL); + if (page == NULL) + goto err; + + vaddr = (unsigned long)page_address(page); + + scrub_pages(vaddr, 1); + + balloon_lock(flags); + + if (xen_feature(XENFEAT_auto_translated_physmap)) { + unsigned long gmfn = page_to_pfn(page); + struct xen_memory_reservation reservation = { + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; + set_xen_guest_handle(reservation.extent_start, &gmfn); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + if (ret == 1) + ret = 0; /* success */ + } else { + ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE, + dealloc_pte_fn, NULL); + } + + if (ret != 0) { + balloon_unlock(flags); + __free_page(page); + goto err; + } + + totalram_pages = --current_pages; + + balloon_unlock(flags); + } + + out: + schedule_work(&balloon_worker); + flush_tlb_all(); + return pagevec; + + err: balloon_lock(flags); - if (xen_feature(XENFEAT_auto_translated_physmap)) { - unsigned long gmfn = __pa(vstart) >> PAGE_SHIFT; - struct xen_memory_reservation reservation = { - .nr_extents = 1, - .extent_order = order, - .domid = DOMID_SELF - }; - set_xen_guest_handle(reservation.extent_start, &gmfn); - ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, - &reservation); - if (ret == -ENOSYS) - goto err; - BUG_ON(ret != 1); - } else { - ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order, - dealloc_pte_fn, NULL); - if (ret == -ENOSYS) - goto err; - BUG_ON(ret); - } - current_pages -= 1UL << order; - totalram_pages = current_pages; + while (--i >= 0) + balloon_append(pagevec[i]); balloon_unlock(flags); + kfree(pagevec); + pagevec = NULL; + goto out; +} + +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages) +{ + unsigned long flags; + int i; + + if (pagevec == NULL) + return; + + balloon_lock(flags); + for (i = 0; i < nr_pages; i++) { + BUG_ON(page_count(pagevec[i]) != 1); + balloon_append(pagevec[i]); + } + balloon_unlock(flags); + + kfree(pagevec); schedule_work(&balloon_worker); - - flush_tlb_all(); - - page = virt_to_page(vstart); - - for (i = 0; i < (1UL << order); i++) - set_page_count(page + i, 1); - - return page; - - err: - free_pages(vstart, order); - balloon_unlock(flags); - return NULL; -} - -void balloon_dealloc_empty_page_range( - struct page *page, unsigned long nr_pages) -{ - unsigned long i, flags; - unsigned int order = get_order(nr_pages * PAGE_SIZE); - - balloon_lock(flags); - for (i = 0; i < (1UL << order); i++) { - BUG_ON(page_count(page + i) != 1); - balloon_append(page + i); - } - balloon_unlock(flags); - - schedule_work(&balloon_worker); -} - -struct page *balloon_alloc_empty_page(void) -{ - return balloon_alloc_empty_page_range(1); -} - -void balloon_free_empty_page( - struct page *page) -{ - balloon_dealloc_empty_page_range(page, 1); } void balloon_release_driver_page(struct page *page) @@ -630,10 +631,8 @@ void balloon_release_driver_page(struct } EXPORT_SYMBOL_GPL(balloon_update_driver_allowance); -EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range); -EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range); -EXPORT_SYMBOL_GPL(balloon_alloc_empty_page); -EXPORT_SYMBOL_GPL(balloon_free_empty_page); +EXPORT_SYMBOL_GPL(alloc_empty_pages_and_pagevec); +EXPORT_SYMBOL_GPL(free_empty_pages_and_pagevec); EXPORT_SYMBOL_GPL(balloon_release_driver_page); MODULE_LICENSE("Dual BSD/GPL"); diff -r 3971f49ce592 -r 7efaaae37415 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Fri Oct 06 10:30:43 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Fri Oct 06 11:52:41 2006 +0100 @@ -515,20 +515,13 @@ static int __init blkif_init(void) blkif_reqs, GFP_KERNEL); pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) * mmap_pages, GFP_KERNEL); - pending_pages = kmalloc(sizeof(pending_pages[0]) * - mmap_pages, GFP_KERNEL); + pending_pages = alloc_empty_pages_and_pagevec(mmap_pages); + if (!pending_reqs || !pending_grant_handles || !pending_pages) goto out_of_memory; - for (i = 0; i < mmap_pages; i++) { - pending_pages[i] = balloon_alloc_empty_page(); - if (pending_pages[i] == NULL) { - while (--i >= 0) - balloon_free_empty_page(pending_pages[i]); - goto out_of_memory; - } + for (i = 0; i < mmap_pages; i++) pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; - } blkif_interface_init(); @@ -545,7 +538,7 @@ static int __init blkif_init(void) out_of_memory: kfree(pending_reqs); kfree(pending_grant_handles); - kfree(pending_pages); + free_empty_pages_and_pagevec(pending_pages, mmap_pages); printk("%s: out of memory\n", __FUNCTION__); return -ENOMEM; } diff -r 3971f49ce592 -r 7efaaae37415 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Fri Oct 06 10:30:43 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Fri Oct 06 11:52:41 2006 +0100 @@ -728,28 +728,16 @@ static int req_increase(void) static int req_increase(void) { int i, j; - struct page **pages = NULL; if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) return -EINVAL; - pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) * - blkif_reqs, GFP_KERNEL); - pages = kmalloc(sizeof(pages[0]) * mmap_pages, GFP_KERNEL); - - if (!pending_reqs[mmap_alloc] || !pages) + pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) + * blkif_reqs, GFP_KERNEL); + foreign_pages[mmap_alloc] = alloc_empty_pages_and_pagevec(mmap_pages); + + if (!pending_reqs[mmap_alloc] || !foreign_pages[mmap_alloc]) goto out_of_memory; - - for (i = 0; i < mmap_pages; i++) { - pages[i] = balloon_alloc_empty_page(); - if (!pages[i]) { - while (--i >= 0) - balloon_free_empty_page(pages[i]); - goto out_of_memory; - } - } - - foreign_pages[mmap_alloc] = pages; DPRINTK("%s: reqs=%d, pages=%d\n", __FUNCTION__, blkif_reqs, mmap_pages); @@ -768,7 +756,7 @@ static int req_increase(void) return 0; out_of_memory: - kfree(pages); + free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages); kfree(pending_reqs[mmap_alloc]); WPRINTK("%s: out of memory\n", __FUNCTION__); return -ENOMEM; @@ -776,15 +764,12 @@ static int req_increase(void) static void mmap_req_del(int mmap) { - int i; - BUG_ON(!spin_is_locked(&pending_free_lock)); kfree(pending_reqs[mmap]); - - for (i = 0; i < mmap_pages; i++) - balloon_free_empty_page(foreign_pages[mmap][i]); - kfree(foreign_pages[mmap]); + pending_reqs[mmap] = NULL; + + free_empty_pages_and_pagevec(foreign_pages[mmap_alloc], mmap_pages); foreign_pages[mmap] = NULL; mmap_lock = 0; diff -r 3971f49ce592 -r 7efaaae37415 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Oct 06 10:30:43 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Oct 06 11:52:41 2006 +0100 @@ -1440,19 +1440,14 @@ static int __init netback_init(void) net_timer.data = 0; net_timer.function = net_alarm; - mmap_pages = kmalloc(sizeof(mmap_pages[0]) * MAX_PENDING_REQS, - GFP_KERNEL); - if (mmap_pages == NULL) - goto out_of_memory; + mmap_pages = alloc_empty_pages_and_pagevec(MAX_PENDING_REQS); + if (mmap_pages == NULL) { + printk("%s: out of memory\n", __FUNCTION__); + return -ENOMEM; + } for (i = 0; i < MAX_PENDING_REQS; i++) { - page = mmap_pages[i] = balloon_alloc_empty_page(); - if (page == NULL) { - while (--i >= 0) - balloon_free_empty_page(mmap_pages[i]); - goto out_of_memory; - } - set_page_count(page, 1); + page = mmap_pages[i]; SetPageForeign(page, netif_page_release); page->index = i; } @@ -1478,11 +1473,6 @@ static int __init netback_init(void) #endif return 0; - - out_of_memory: - kfree(mmap_pages); - printk("%s: out of memory\n", __FUNCTION__); - return -ENOMEM; } module_init(netback_init); diff -r 3971f49ce592 -r 7efaaae37415 linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Fri Oct 06 10:30:43 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Fri Oct 06 11:52:41 2006 +0100 @@ -23,10 +23,9 @@ static tpmif_t *alloc_tpmif(domid_t domi static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi) { tpmif_t *tpmif; - int i; tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL); - if (!tpmif) + if (tpmif == NULL) goto out_of_memory; memset(tpmif, 0, sizeof (*tpmif)); @@ -36,19 +35,9 @@ static tpmif_t *alloc_tpmif(domid_t domi snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid); atomic_set(&tpmif->refcnt, 1); - tpmif->mmap_pages = kmalloc(sizeof(tpmif->mmap_pages[0]) - * TPMIF_TX_RING_SIZE, GFP_KERNEL); + tpmif->mmap_pages = alloc_empty_pages_and_pagevec(TPMIF_TX_RING_SIZE); if (tpmif->mmap_pages == NULL) goto out_of_memory; - - for (i = 0; i < TPMIF_TX_RING_SIZE; i++) { - tpmif->mmap_pages[i] = balloon_alloc_empty_page(); - if (tpmif->mmap_pages[i] == NULL) { - while (--i >= 0) - balloon_free_empty_page(tpmif->mmap_pages[i]); - goto out_of_memory; - } - } list_add(&tpmif->tpmif_list, &tpmif_list); num_frontends++; @@ -56,26 +45,17 @@ static tpmif_t *alloc_tpmif(domid_t domi return tpmif; out_of_memory: - if (tpmif != NULL) { - kfree(tpmif->mmap_pages); + if (tpmif != NULL) kmem_cache_free(tpmif_cachep, tpmif); - } printk("%s: out of memory\n", __FUNCTION__); return ERR_PTR(-ENOMEM); } static void free_tpmif(tpmif_t * tpmif) { - int i; - num_frontends--; - list_del(&tpmif->tpmif_list); - - for (i = 0; i < TPMIF_TX_RING_SIZE; i++) - balloon_free_empty_page(tpmif->mmap_pages[i]); - kfree(tpmif->mmap_pages); - + free_empty_pages_and_pagevec(tpmif->mmap_pages, TPMIF_TX_RING_SIZE); kmem_cache_free(tpmif_cachep, tpmif); } diff -r 3971f49ce592 -r 7efaaae37415 linux-2.6-xen-sparse/include/xen/balloon.h --- a/linux-2.6-xen-sparse/include/xen/balloon.h Fri Oct 06 10:30:43 2006 +0100 +++ b/linux-2.6-xen-sparse/include/xen/balloon.h Fri Oct 06 11:52:41 2006 +0100 @@ -40,15 +40,9 @@ */ void balloon_update_driver_allowance(long delta); -/* Allocate an empty low-memory page range. */ -struct page *balloon_alloc_empty_page_range(unsigned long nr_pages); - -/* Deallocate an empty page range, adding to the balloon. */ -void balloon_dealloc_empty_page_range( - struct page *page, unsigned long nr_pages); - -struct page *balloon_alloc_empty_page(void); -void balloon_free_empty_page(struct page *page); +/* Allocate/free a set of empty pages in low memory (i.e., no RAM mapped). */ +struct page **alloc_empty_pages_and_pagevec(int nr_pages); +void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages); void balloon_release_driver_page(struct page *page); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |