[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Allow xen_create_contiguous_region() to fail gracefully if it



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.