# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 356c175366a1b65d8b2ae82653247b5ae675cf7d
# Parent 5066d2aa2fb0e26abb8b2123d3bfca3cefbfd727
Allow xen_create_contiguous_region() to fail gracefully if it
cannot allocate a contiguous multi-page extent of memory. This
should avoid unnecessary crashes in the xen-specific skbuff
cache constructor.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 5066d2aa2fb0 -r 356c175366a1
linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c Wed Nov 9
12:59:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c Wed Nov 9
13:39:32 2005
@@ -152,8 +152,11 @@
ret = (void *)vstart;
if (ret != NULL) {
- xen_create_contiguous_region(vstart, order);
-
+ /* NB. Hardcode 31 address bits for now: aacraid limitation. */
+ if (xen_create_contiguous_region(vstart, order, 31) != 0) {
+ free_pages(vstart, order);
+ return NULL;
+ }
memset(ret, 0, size);
*dma_handle = virt_to_bus(ret);
}
diff -r 5066d2aa2fb0 -r 356c175366a1
linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c Wed Nov 9
12:59:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c Wed Nov 9
13:39:32 2005
@@ -117,6 +117,7 @@
swiotlb_init_with_default_size (size_t default_size)
{
unsigned long i, bytes;
+ int rc;
if (!iotlb_nslabs) {
iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
@@ -137,8 +138,10 @@
"Use dom0_mem Xen boot parameter to reserve\n"
"some DMA memory (e.g., dom0_mem=-128M).\n");
- xen_create_contiguous_region(
- (unsigned long)iotlb_virt_start, get_order(bytes));
+ /* Hardcode 31 address bits for now: aacraid limitation. */
+ rc = xen_create_contiguous_region(
+ (unsigned long)iotlb_virt_start, get_order(bytes), 31);
+ BUG_ON(rc);
/*
* Allocate and initialize the free list array. This array is used
diff -r 5066d2aa2fb0 -r 356c175366a1
linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Wed Nov 9
12:59:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Wed Nov 9
13:39:32 2005
@@ -314,7 +314,8 @@
}
/* Ensure multi-page extents are contiguous in machine memory. */
-void xen_create_contiguous_region(unsigned long vstart, unsigned int order)
+int xen_create_contiguous_region(
+ unsigned long vstart, unsigned int order, unsigned int address_bits)
{
pgd_t *pgd;
pud_t *pud;
@@ -349,9 +350,10 @@
/* 2. Get a new contiguous memory extent. */
reservation.extent_order = order;
- reservation.address_bits = 31; /* aacraid limitation */
- BUG_ON(HYPERVISOR_memory_op(
- XENMEM_increase_reservation, &reservation) != 1);
+ reservation.address_bits = address_bits;
+ if (HYPERVISOR_memory_op(XENMEM_increase_reservation,
+ &reservation) != 1)
+ goto fail;
/* 3. Map the new extent in place of old pages. */
for (i = 0; i < (1<<order); i++) {
@@ -367,6 +369,28 @@
contiguous_bitmap_set(__pa(vstart) >> PAGE_SHIFT, 1UL << order);
balloon_unlock(flags);
+
+ return 0;
+
+ fail:
+ reservation.extent_order = 0;
+ reservation.address_bits = 0;
+
+ for (i = 0; i < (1<<order); i++) {
+ BUG_ON(HYPERVISOR_memory_op(
+ XENMEM_increase_reservation, &reservation) != 1);
+ BUG_ON(HYPERVISOR_update_va_mapping(
+ vstart + (i*PAGE_SIZE),
+ pfn_pte_ma(mfn, PAGE_KERNEL), 0));
+ xen_machphys_update(mfn, (__pa(vstart)>>PAGE_SHIFT)+i);
+ phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = mfn;
+ }
+
+ flush_tlb_all();
+
+ balloon_unlock(flags);
+
+ return -ENOMEM;
}
void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
diff -r 5066d2aa2fb0 -r 356c175366a1
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Wed Nov 9 12:59:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Wed Nov 9 13:39:32 2005
@@ -279,8 +279,9 @@
unsigned long flags;
#ifdef CONFIG_X86_PAE
- /* this gives us a page below 4GB */
- xen_create_contiguous_region((unsigned long)pgd, 0);
+ /* Ensure pgd resides below 4GB. */
+ int rc = xen_create_contiguous_region((unsigned long)pgd, 0, 32);
+ BUG_ON(rc);
#endif
if (!HAVE_SHARED_KERNEL_PMD)
diff -r 5066d2aa2fb0 -r 356c175366a1
linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c Wed Nov 9 12:59:53 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c Wed Nov 9 13:39:32 2005
@@ -79,8 +79,10 @@
while (skbuff_order_cachep[order] != cachep)
order++;
+ /* Do our best to allocate contiguous memory but fall back to IOMMU. */
if (order != 0)
- xen_create_contiguous_region((unsigned long)buf, order);
+ (void)xen_create_contiguous_region(
+ (unsigned long)buf, order, 0);
scrub_pages(buf, 1 << order);
}
diff -r 5066d2aa2fb0 -r 356c175366a1
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h Wed Nov
9 12:59:53 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h Wed Nov
9 13:39:32 2005
@@ -129,8 +129,11 @@
#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
#endif /* linux < 2.6.0 */
-void xen_create_contiguous_region(unsigned long vstart, unsigned int order);
-void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
+/* Returns zero on success else negative errno. */
+int xen_create_contiguous_region(
+ unsigned long vstart, unsigned int order, unsigned int address_bits);
+void xen_destroy_contiguous_region(
+ unsigned long vstart, unsigned int order);
#include <asm/hypercall.h>
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|