ia64/xen-unstable
changeset 7716:356c175366a1
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@xensource.com>
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@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Wed Nov 09 14:39:32 2005 +0100 (2005-11-09) |
parents | 5066d2aa2fb0 |
children | 6b62605e77b5 |
files | linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h |
line diff
1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c Wed Nov 09 13:59:53 2005 +0100 1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c Wed Nov 09 14:39:32 2005 +0100 1.3 @@ -152,8 +152,11 @@ void *dma_alloc_coherent(struct device * 1.4 ret = (void *)vstart; 1.5 1.6 if (ret != NULL) { 1.7 - xen_create_contiguous_region(vstart, order); 1.8 - 1.9 + /* NB. Hardcode 31 address bits for now: aacraid limitation. */ 1.10 + if (xen_create_contiguous_region(vstart, order, 31) != 0) { 1.11 + free_pages(vstart, order); 1.12 + return NULL; 1.13 + } 1.14 memset(ret, 0, size); 1.15 *dma_handle = virt_to_bus(ret); 1.16 }
2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c Wed Nov 09 13:59:53 2005 +0100 2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c Wed Nov 09 14:39:32 2005 +0100 2.3 @@ -117,6 +117,7 @@ void 2.4 swiotlb_init_with_default_size (size_t default_size) 2.5 { 2.6 unsigned long i, bytes; 2.7 + int rc; 2.8 2.9 if (!iotlb_nslabs) { 2.10 iotlb_nslabs = (default_size >> IO_TLB_SHIFT); 2.11 @@ -137,8 +138,10 @@ swiotlb_init_with_default_size (size_t d 2.12 "Use dom0_mem Xen boot parameter to reserve\n" 2.13 "some DMA memory (e.g., dom0_mem=-128M).\n"); 2.14 2.15 - xen_create_contiguous_region( 2.16 - (unsigned long)iotlb_virt_start, get_order(bytes)); 2.17 + /* Hardcode 31 address bits for now: aacraid limitation. */ 2.18 + rc = xen_create_contiguous_region( 2.19 + (unsigned long)iotlb_virt_start, get_order(bytes), 31); 2.20 + BUG_ON(rc); 2.21 2.22 /* 2.23 * Allocate and initialize the free list array. This array is used
3.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Wed Nov 09 13:59:53 2005 +0100 3.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Wed Nov 09 14:39:32 2005 +0100 3.3 @@ -314,7 +314,8 @@ static void contiguous_bitmap_clear( 3.4 } 3.5 3.6 /* Ensure multi-page extents are contiguous in machine memory. */ 3.7 -void xen_create_contiguous_region(unsigned long vstart, unsigned int order) 3.8 +int xen_create_contiguous_region( 3.9 + unsigned long vstart, unsigned int order, unsigned int address_bits) 3.10 { 3.11 pgd_t *pgd; 3.12 pud_t *pud; 3.13 @@ -349,9 +350,10 @@ void xen_create_contiguous_region(unsign 3.14 3.15 /* 2. Get a new contiguous memory extent. */ 3.16 reservation.extent_order = order; 3.17 - reservation.address_bits = 31; /* aacraid limitation */ 3.18 - BUG_ON(HYPERVISOR_memory_op( 3.19 - XENMEM_increase_reservation, &reservation) != 1); 3.20 + reservation.address_bits = address_bits; 3.21 + if (HYPERVISOR_memory_op(XENMEM_increase_reservation, 3.22 + &reservation) != 1) 3.23 + goto fail; 3.24 3.25 /* 3. Map the new extent in place of old pages. */ 3.26 for (i = 0; i < (1<<order); i++) { 3.27 @@ -367,6 +369,28 @@ void xen_create_contiguous_region(unsign 3.28 contiguous_bitmap_set(__pa(vstart) >> PAGE_SHIFT, 1UL << order); 3.29 3.30 balloon_unlock(flags); 3.31 + 3.32 + return 0; 3.33 + 3.34 + fail: 3.35 + reservation.extent_order = 0; 3.36 + reservation.address_bits = 0; 3.37 + 3.38 + for (i = 0; i < (1<<order); i++) { 3.39 + BUG_ON(HYPERVISOR_memory_op( 3.40 + XENMEM_increase_reservation, &reservation) != 1); 3.41 + BUG_ON(HYPERVISOR_update_va_mapping( 3.42 + vstart + (i*PAGE_SIZE), 3.43 + pfn_pte_ma(mfn, PAGE_KERNEL), 0)); 3.44 + xen_machphys_update(mfn, (__pa(vstart)>>PAGE_SHIFT)+i); 3.45 + phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = mfn; 3.46 + } 3.47 + 3.48 + flush_tlb_all(); 3.49 + 3.50 + balloon_unlock(flags); 3.51 + 3.52 + return -ENOMEM; 3.53 } 3.54 3.55 void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Wed Nov 09 13:59:53 2005 +0100 4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Wed Nov 09 14:39:32 2005 +0100 4.3 @@ -279,8 +279,9 @@ void pgd_ctor(void *pgd, kmem_cache_t *c 4.4 unsigned long flags; 4.5 4.6 #ifdef CONFIG_X86_PAE 4.7 - /* this gives us a page below 4GB */ 4.8 - xen_create_contiguous_region((unsigned long)pgd, 0); 4.9 + /* Ensure pgd resides below 4GB. */ 4.10 + int rc = xen_create_contiguous_region((unsigned long)pgd, 0, 32); 4.11 + BUG_ON(rc); 4.12 #endif 4.13 4.14 if (!HAVE_SHARED_KERNEL_PMD)
5.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c Wed Nov 09 13:59:53 2005 +0100 5.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/skbuff.c Wed Nov 09 14:39:32 2005 +0100 5.3 @@ -79,8 +79,10 @@ static void skbuff_ctor(void *buf, kmem_ 5.4 while (skbuff_order_cachep[order] != cachep) 5.5 order++; 5.6 5.7 + /* Do our best to allocate contiguous memory but fall back to IOMMU. */ 5.8 if (order != 0) 5.9 - xen_create_contiguous_region((unsigned long)buf, order); 5.10 + (void)xen_create_contiguous_region( 5.11 + (unsigned long)buf, order, 0); 5.12 5.13 scrub_pages(buf, 1 << order); 5.14 }
6.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h Wed Nov 09 13:59:53 2005 +0100 6.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h Wed Nov 09 14:39:32 2005 +0100 6.3 @@ -129,8 +129,11 @@ void xen_invlpg_mask(cpumask_t *mask, un 6.4 #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) 6.5 #endif /* linux < 2.6.0 */ 6.6 6.7 -void xen_create_contiguous_region(unsigned long vstart, unsigned int order); 6.8 -void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order); 6.9 +/* Returns zero on success else negative errno. */ 6.10 +int xen_create_contiguous_region( 6.11 + unsigned long vstart, unsigned int order, unsigned int address_bits); 6.12 +void xen_destroy_contiguous_region( 6.13 + unsigned long vstart, unsigned int order); 6.14 6.15 #include <asm/hypercall.h> 6.16