aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-10-05 22:11:24 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-10-05 22:11:24 +0100
commit76c184f4280d56968c6a362469777ea362a7cfb8 (patch)
treeac5b678a67557642152017265bc715050032d1e3
parent3930ae7abdded5cdde5f9ecf38956ddc1a724031 (diff)
downloadxen-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.c13
-rw-r--r--linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c52
-rw-r--r--linux-2.6-xen-sparse/include/xen/balloon.h18
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