diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-10-05 22:11:24 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-10-05 22:11:24 +0100 |
commit | 76c184f4280d56968c6a362469777ea362a7cfb8 (patch) | |
tree | ac5b678a67557642152017265bc715050032d1e3 | |
parent | 3930ae7abdded5cdde5f9ecf38956ddc1a724031 (diff) | |
download | xen-76c184f4280d56968c6a362469777ea362a7cfb8.tar.gz xen-76c184f4280d56968c6a362469777ea362a7cfb8.tar.bz2 xen-76c184f4280d56968c6a362469777ea362a7cfb8.zip |
[BLK] back: Allocate pages for foreign mappings individually rather
than in one large contiguous region.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 13 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 52 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/include/xen/balloon.h | 18 |
3 files changed, 44 insertions, 39 deletions
diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index a6a8396c05..ad39655661 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -606,6 +606,17 @@ void balloon_dealloc_empty_page_range( 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) { unsigned long flags; @@ -621,6 +632,8 @@ void balloon_release_driver_page(struct page *page) 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(balloon_release_driver_page); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c index 416f7bc18c..5d5856d8f9 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -56,8 +56,6 @@ static int blkif_reqs = 64; module_param_named(reqs, blkif_reqs, int, 0); MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate"); -static int mmap_pages; - /* Run-time switchable: /sys/module/blkback/parameters/ */ static unsigned int log_stats = 0; static unsigned int debug_lvl = 0; @@ -87,8 +85,7 @@ static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq); #define BLKBACK_INVALID_HANDLE (~0) -static unsigned long mmap_vstart; -static unsigned long *pending_vaddrs; +static struct page **pending_pages; static grant_handle_t *pending_grant_handles; static inline int vaddr_pagenr(pending_req_t *req, int seg) @@ -98,7 +95,8 @@ static inline int vaddr_pagenr(pending_req_t *req, int seg) static inline unsigned long vaddr(pending_req_t *req, int seg) { - return pending_vaddrs[vaddr_pagenr(req, seg)]; + unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]); + return (unsigned long)pfn_to_kaddr(pfn); } #define pending_handle(_req, _seg) \ @@ -506,52 +504,50 @@ static void make_response(blkif_t *blkif, unsigned long id, static int __init blkif_init(void) { - struct page *page; - int i; + int i, mmap_pages; if (!is_running_on_xen()) return -ENODEV; - mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; - - page = balloon_alloc_empty_page_range(mmap_pages); - if (page == NULL) - return -ENOMEM; - mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); + mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; pending_reqs = kmalloc(sizeof(pending_reqs[0]) * blkif_reqs, GFP_KERNEL); pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) * mmap_pages, GFP_KERNEL); - pending_vaddrs = kmalloc(sizeof(pending_vaddrs[0]) * + pending_pages = kmalloc(sizeof(pending_pages[0]) * mmap_pages, GFP_KERNEL); - if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) { - kfree(pending_reqs); - kfree(pending_grant_handles); - kfree(pending_vaddrs); - printk("%s: out of memory\n", __FUNCTION__); - return -ENOMEM; - } + if (!pending_reqs || !pending_grant_handles || !pending_pages) + goto out_of_memory; - blkif_interface_init(); - - printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n", - __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart); - BUG_ON(mmap_vstart == 0); for (i = 0; i < mmap_pages; i++) { - pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT); + 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; + } pending_grant_handles[i] = BLKBACK_INVALID_HANDLE; } + blkif_interface_init(); + memset(pending_reqs, 0, sizeof(pending_reqs)); INIT_LIST_HEAD(&pending_free); for (i = 0; i < blkif_reqs; i++) list_add_tail(&pending_reqs[i].free_list, &pending_free); - + blkif_xenbus_init(); return 0; + + out_of_memory: + kfree(pending_reqs); + kfree(pending_grant_handles); + kfree(pending_pages); + printk("%s: out of memory\n", __FUNCTION__); + return -ENOMEM; } module_init(blkif_init); diff --git a/linux-2.6-xen-sparse/include/xen/balloon.h b/linux-2.6-xen-sparse/include/xen/balloon.h index 60d7099aa1..4e27a2e39a 100644 --- a/linux-2.6-xen-sparse/include/xen/balloon.h +++ b/linux-2.6-xen-sparse/include/xen/balloon.h @@ -38,23 +38,19 @@ * Inform the balloon driver that it should allow some slop for device-driver * memory activities. */ -void -balloon_update_driver_allowance( - long delta); +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); +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( +void balloon_dealloc_empty_page_range( struct page *page, unsigned long nr_pages); -void -balloon_release_driver_page( - struct page *page); +struct page *balloon_alloc_empty_page(void); +void balloon_free_empty_page(struct page *page); + +void balloon_release_driver_page(struct page *page); /* * Prevent the balloon driver from changing the memory reservation during |