[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |