# HG changeset patch
# User Ian.Campbell@xxxxxxxxxxxxx
# Node ID c1850c659e40042d4ce2bf006d6f37b9ebda307a
# Parent 9f70d57aadcfbad4308abb0a8168bf779618c961
Make ballon and backend drivers fail gracefully if they are unable to initialize
due to missing hypervisor support.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 9 +++
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c | 23 +++++----
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 50 +++++++++++++--------
linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 4 +
4 files changed, 58 insertions(+), 28 deletions(-)
diff -r 9f70d57aadcf -r c1850c659e40
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Aug 09
11:26:11 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Wed Aug 09
11:27:28 2006 +0100
@@ -563,10 +563,14 @@ struct page *balloon_alloc_empty_page_ra
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;
@@ -583,6 +587,11 @@ struct page *balloon_alloc_empty_page_ra
set_page_count(page + i, 1);
return page;
+
+ err:
+ free_pages(vstart, order);
+ balloon_unlock(flags);
+ return NULL;
}
void balloon_dealloc_empty_page_range(
diff -r 9f70d57aadcf -r c1850c659e40
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Wed Aug 09
11:26:11 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Wed Aug 09
11:27:28 2006 +0100
@@ -518,6 +518,19 @@ static int __init blkif_init(void)
return -ENODEV;
mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
+
+#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
+ extern unsigned long alloc_empty_foreign_map_page_range(
+ unsigned long pages);
+ mmap_vstart = (unsigned long)
+ alloc_empty_foreign_map_page_range(mmap_pages);
+#else /* ! ia64 */
+ page = balloon_alloc_empty_page_range(mmap_pages);
+ if (page == NULL)
+ return -ENOMEM;
+ mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+#endif
+
pending_reqs = kmalloc(sizeof(pending_reqs[0]) *
blkif_reqs, GFP_KERNEL);
pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
@@ -534,16 +547,6 @@ static int __init blkif_init(void)
blkif_interface_init();
-#ifdef CONFIG_XEN_IA64_DOM0_NON_VP
- extern unsigned long alloc_empty_foreign_map_page_range(
- unsigned long pages);
- mmap_vstart = (unsigned long)
- alloc_empty_foreign_map_page_range(mmap_pages);
-#else /* ! ia64 */
- page = balloon_alloc_empty_page_range(mmap_pages);
- BUG_ON(page == NULL);
- mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
-#endif
printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
__FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
BUG_ON(mmap_vstart == 0);
diff -r 9f70d57aadcf -r c1850c659e40
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Wed Aug 09 11:26:11
2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Wed Aug 09 11:27:28
2006 +0100
@@ -709,29 +709,18 @@ static void make_response(blkif_t *blkif
/******************************************************************
* misc small helpers
*/
-/* FIXME: Return ENOMEM properly on failure to allocate additional reqs. */
-static void req_increase(void)
+static int req_increase(void)
{
int i, j;
struct page *page;
unsigned long flags;
+ int ret;
spin_lock_irqsave(&pending_free_lock, flags);
+ ret = -EINVAL;
if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock)
goto done;
-
- pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) *
- blkif_reqs, GFP_KERNEL);
- pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
- mmap_pages, GFP_KERNEL);
-
- if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
- kfree(pending_reqs[mmap_alloc]);
- kfree(pending_addrs[mmap_alloc]);
- WPRINTK("%s: out of memory\n", __FUNCTION__);
- goto done;
- }
#ifdef __ia64__
extern unsigned long alloc_empty_foreign_map_page_range(
@@ -740,7 +729,11 @@ static void req_increase(void)
alloc_empty_foreign_map_page_range(mmap_pages);
#else /* ! ia64 */
page = balloon_alloc_empty_page_range(mmap_pages);
- BUG_ON(page == NULL);
+ ret = -ENOMEM;
+ if (page == NULL) {
+ printk("%s balloon_alloc_empty_page_range gave NULL\n",
__FUNCTION__);
+ goto done;
+ }
/* Pin all of the pages. */
for (i=0; i<mmap_pages; i++)
@@ -751,6 +744,23 @@ static void req_increase(void)
mmap_start[mmap_alloc].mpage = page;
#endif
+
+ pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) *
+ blkif_reqs, GFP_KERNEL);
+ pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) *
+ mmap_pages, GFP_KERNEL);
+
+ ret = -ENOMEM;
+ if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) {
+ kfree(pending_reqs[mmap_alloc]);
+ kfree(pending_addrs[mmap_alloc]);
+ WPRINTK("%s: out of memory\n", __FUNCTION__);
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ ret = 0;
+
DPRINTK("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
__FUNCTION__, blkif_reqs, mmap_pages,
mmap_start[mmap_alloc].start);
@@ -774,7 +784,7 @@ static void req_increase(void)
DPRINTK("# MMAPs increased to %d\n",mmap_alloc);
done:
spin_unlock_irqrestore(&pending_free_lock, flags);
-
+ return ret;
}
static void mmap_req_del(int mmap)
@@ -1394,7 +1404,13 @@ static int __init blkif_init(void)
return -ENODEV;
INIT_LIST_HEAD(&pending_free);
- for(i = 0; i < 2; i++) req_increase();
+ for(i = 0; i < 2; i++) {
+ ret = req_increase();
+ if (ret)
+ break;
+ }
+ if (i == 0)
+ return ret;
tap_blkif_interface_init();
diff -r 9f70d57aadcf -r c1850c659e40
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Aug 09
11:26:11 2006 +0100
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Aug 09
11:27:28 2006 +0100
@@ -1306,7 +1306,9 @@ static int __init netback_init(void)
net_timer.function = net_alarm;
page = balloon_alloc_empty_page_range(MAX_PENDING_REQS);
- BUG_ON(page == NULL);
+ if (page == NULL)
+ return -ENOMEM;
+
mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
for (i = 0; i < MAX_PENDING_REQS; i++) {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|