[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 35/35] x86: Don't panic if can not alloc buffer for swiotlb
On Thu, Jan 24, 2013 at 12:20:16PM -0800, Yinghai Lu wrote: > Normal boot path on system with iommu support: > swiotlb buffer will be allocated early at first and then try to initialize > iommu, if iommu for intel or AMD could setup properly, swiotlb buffer > will be freed. > > The early allocating is with bootmem, and could panic when we try to use > kdump with buffer above 4G only, or with memmap to limit mem under 4G. > for example: memmap=4095M$1M to remove memory under 4G. > > According to Eric, add _nopanic version and no_iotlb_memory to fail > map single later if swiotlb is still needed. > > -v2: don't pass nopanic, and use -ENOMEM return value according to Eric. > panic early instead of using swiotlb_full to panic...according to > Eric/Konrad. > -v3: make swiotlb_init to be notpanic, but will affect: > arm64, ia64, powerpc, tile, unicore32, x86. > -v4: cleanup swiotlb_init by removing swiotlb_init_with_default_size. > > Suggested-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> > Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> :-) > Cc: Joerg Roedel <joro@xxxxxxxxxx> > Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx> > Cc: Jeremy Fitzhardinge <jeremy@xxxxxxxx> > Cc: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> > Cc: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx> > Cc: Arnd Bergmann <arnd@xxxxxxxx> > Cc: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> > Cc: linux-mips@xxxxxxxxxxxxxx > Cc: xen-devel@xxxxxxxxxxxxxxxxxxx > Cc: virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx > Cc: Shuah Khan <shuahkhan@xxxxxxxxx> > --- > arch/mips/cavium-octeon/dma-octeon.c | 3 ++- > drivers/xen/swiotlb-xen.c | 4 ++- > include/linux/swiotlb.h | 2 +- > lib/swiotlb.c | 47 > +++++++++++++++++++++------------- > 4 files changed, 35 insertions(+), 21 deletions(-) > > diff --git a/arch/mips/cavium-octeon/dma-octeon.c > b/arch/mips/cavium-octeon/dma-octeon.c > index 41dd0088..02f2444 100644 > --- a/arch/mips/cavium-octeon/dma-octeon.c > +++ b/arch/mips/cavium-octeon/dma-octeon.c > @@ -317,7 +317,8 @@ void __init plat_swiotlb_setup(void) > > octeon_swiotlb = alloc_bootmem_low_pages(swiotlbsize); > > - swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1); > + if (swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1) == -ENOMEM) > + panic("Cannot allocate SWIOTLB buffer"); > > mips_dma_map_ops = &octeon_linear_dma_map_ops.dma_map_ops; > } > diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c > index af47e75..1d94316 100644 > --- a/drivers/xen/swiotlb-xen.c > +++ b/drivers/xen/swiotlb-xen.c > @@ -231,7 +231,9 @@ retry: > } > start_dma_addr = xen_virt_to_bus(xen_io_tlb_start); > if (early) { > - swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, > verbose); > + if (swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, > + verbose)) > + panic("Cannot allocate SWIOTLB buffer"); > rc = 0; > } else > rc = swiotlb_late_init_with_tbl(xen_io_tlb_start, > xen_io_tlb_nslabs); > diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h > index 071d62c..2de42f9 100644 > --- a/include/linux/swiotlb.h > +++ b/include/linux/swiotlb.h > @@ -23,7 +23,7 @@ extern int swiotlb_force; > #define IO_TLB_SHIFT 11 > > extern void swiotlb_init(int verbose); > -extern void swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int > verbose); > +int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); > extern unsigned long swiotlb_nr_tbl(void); > extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs); > > diff --git a/lib/swiotlb.c b/lib/swiotlb.c > index 196b069..bfe02b8 100644 > --- a/lib/swiotlb.c > +++ b/lib/swiotlb.c > @@ -122,11 +122,18 @@ static dma_addr_t swiotlb_virt_to_bus(struct device > *hwdev, > return phys_to_dma(hwdev, virt_to_phys(address)); > } > > +static bool no_iotlb_memory; > + > void swiotlb_print_info(void) > { > unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT; > unsigned char *vstart, *vend; > > + if (no_iotlb_memory) { > + pr_warn("software IO TLB: No low mem\n"); > + return; > + } > + > vstart = phys_to_virt(io_tlb_start); > vend = phys_to_virt(io_tlb_end); > > @@ -136,7 +143,7 @@ void swiotlb_print_info(void) > bytes >> 20, vstart, vend - 1); > } > > -void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int > verbose) > +int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int > verbose) > { > void *v_overflow_buffer; > unsigned long i, bytes; > @@ -150,9 +157,10 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned > long nslabs, int verbose) > /* > * Get the overflow emergency buffer > */ > - v_overflow_buffer = > alloc_bootmem_low_pages(PAGE_ALIGN(io_tlb_overflow)); > + v_overflow_buffer = alloc_bootmem_low_pages_nopanic( > + PAGE_ALIGN(io_tlb_overflow)); > if (!v_overflow_buffer) > - panic("Cannot allocate SWIOTLB overflow buffer!\n"); > + return -ENOMEM; > > io_tlb_overflow_buffer = __pa(v_overflow_buffer); > > @@ -169,15 +177,19 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned > long nslabs, int verbose) > > if (verbose) > swiotlb_print_info(); > + > + return 0; > } > > /* > * Statically reserve bounce buffer space and initialize bounce buffer data > * structures for the software IO TLB used to implement the DMA API. > */ > -static void __init > -swiotlb_init_with_default_size(size_t default_size, int verbose) > +void __init > +swiotlb_init(int verbose) > { > + /* default to 64MB */ > + size_t default_size = 64UL<<20; > unsigned char *vstart; > unsigned long bytes; > > @@ -188,20 +200,16 @@ swiotlb_init_with_default_size(size_t default_size, int > verbose) > > bytes = io_tlb_nslabs << IO_TLB_SHIFT; > > - /* > - * Get IO TLB memory from the low pages > - */ > - vstart = alloc_bootmem_low_pages(PAGE_ALIGN(bytes)); > - if (!vstart) > - panic("Cannot allocate SWIOTLB buffer"); > - > - swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose); > -} > + /* Get IO TLB memory from the low pages */ > + vstart = alloc_bootmem_low_pages_nopanic(PAGE_ALIGN(bytes)); > + if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose)) > + return; > > -void __init > -swiotlb_init(int verbose) > -{ > - swiotlb_init_with_default_size(64 * (1<<20), verbose); /* default to > 64MB */ > + if (io_tlb_start) > + free_bootmem(io_tlb_start, > + PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); > + pr_warn("Cannot allocate SWIOTLB buffer"); > + no_iotlb_memory = true; > } > > /* > @@ -405,6 +413,9 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, > unsigned long offset_slots; > unsigned long max_slots; > > + if (no_iotlb_memory) > + panic("Can not allocate SWIOTLB buffer earlier and can't now > provide you with the DMA bounce buffer"); > + > mask = dma_get_seg_boundary(hwdev); > > tbl_dma_addr &= mask; > -- > 1.7.10.4 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |