# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID be6f5e262d844326113c47fdc6641c382f28577d
# Parent 79b56c02b836c2074817cae5907525029bc131ff
[BLK] back: Allocate pages for foreign mappings individually rather
than in one large contiguous region.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 13 +++++
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 54 +++++++++------------
linux-2.6-xen-sparse/include/xen/balloon.h | 18 ++-----
3 files changed, 45 insertions(+), 40 deletions(-)
diff -r 79b56c02b836 -r be6f5e262d84
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Thu Oct 05
16:48:28 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Thu Oct 05
22:11:24 2006 +0100
@@ -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 @@ EXPORT_SYMBOL_GPL(balloon_update_driver_
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 -r 79b56c02b836 -r be6f5e262d84
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Oct 05
16:48:28 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Thu Oct 05
22:11:24 2006 +0100
@@ -55,8 +55,6 @@ static int blkif_reqs = 64;
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;
@@ -87,8 +85,7 @@ static DECLARE_WAIT_QUEUE_HEAD(pending_f
#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_r
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
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;
+
+ 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;
+ }
+ pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
}
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_grant_handles[i] = BLKBACK_INVALID_HANDLE;
- }
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 -r 79b56c02b836 -r be6f5e262d84 linux-2.6-xen-sparse/include/xen/balloon.h
--- a/linux-2.6-xen-sparse/include/xen/balloon.h Thu Oct 05 16:48:28
2006 +0100
+++ b/linux-2.6-xen-sparse/include/xen/balloon.h Thu Oct 05 22:11:24
2006 +0100
@@ -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
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|