ia64/xen-unstable

changeset 6297:d0f23c103453

Six the SWIOTLB. The bus range does need to be contiguous after
all as a range comparsion is used to determine if a given
dma address is within the swiotlb aperture.

Maybe we can do better sometime in the future (fast address
range comparison yet not require bus-contiguous aperture). But
reverting this morning's patch is fine for now.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Aug 19 17:51:37 2005 +0000 (2005-08-19)
parents 0608852073c8
children 1872e09bfba3 fd28bf8825a8
files linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c	Fri Aug 19 17:25:04 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c	Fri Aug 19 17:51:37 2005 +0000
     1.3 @@ -43,20 +43,18 @@
     1.4  #define IO_TLB_SHIFT 11
     1.5  
     1.6  int swiotlb_force;
     1.7 +static char *iotlb_virt_start;
     1.8 +static unsigned long iotlb_nslabs;
     1.9  
    1.10  /*
    1.11   * Used to do a quick range check in swiotlb_unmap_single and
    1.12   * swiotlb_sync_single_*, to see if the memory was in fact allocated by this
    1.13   * API.
    1.14   */
    1.15 -static char *iotlb_virt_start, *iotlb_virt_end;
    1.16 -static dma_addr_t iotlb_bus_start, iotlb_bus_end;
    1.17 +static dma_addr_t iotlb_bus_start, iotlb_bus_mask;
    1.18  
    1.19 -/*
    1.20 - * The number of IO TLB blocks (in groups of 64) betweeen iotlb_virt_start and
    1.21 - * iotlb_virt_end.  This is command line adjustable via setup_io_tlb_npages.
    1.22 - */
    1.23 -static unsigned long iotlb_nslabs;
    1.24 +/* Does the given dma address reside within the swiotlb aperture? */
    1.25 +#define in_swiotlb_aperture(a) (!(((a) ^ iotlb_bus_start) & iotlb_bus_mask))
    1.26  
    1.27  /*
    1.28   * When the IOMMU overflows we return a fallback buffer. This sets the size.
    1.29 @@ -94,6 +92,9 @@ setup_io_tlb_npages(char *str)
    1.30  		iotlb_nslabs = simple_strtoul(str, &str, 0) <<
    1.31  			(20 - IO_TLB_SHIFT);
    1.32  		iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
    1.33 +		/* Round up to power of two (xen_create_contiguous_region). */
    1.34 +		while (iotlb_nslabs & (iotlb_nslabs-1))
    1.35 +			iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
    1.36  	}
    1.37  	if (*str == ',')
    1.38  		++str;
    1.39 @@ -120,6 +121,9 @@ swiotlb_init_with_default_size (size_t d
    1.40  	if (!iotlb_nslabs) {
    1.41  		iotlb_nslabs = (default_size >> IO_TLB_SHIFT);
    1.42  		iotlb_nslabs = ALIGN(iotlb_nslabs, IO_TLB_SEGSIZE);
    1.43 +		/* Round up to power of two (xen_create_contiguous_region). */
    1.44 +		while (iotlb_nslabs & (iotlb_nslabs-1))
    1.45 +			iotlb_nslabs += iotlb_nslabs & ~(iotlb_nslabs-1);
    1.46  	}
    1.47  
    1.48  	bytes = iotlb_nslabs * (1UL << IO_TLB_SHIFT);
    1.49 @@ -133,17 +137,12 @@ swiotlb_init_with_default_size (size_t d
    1.50  		      "Use dom0_mem Xen boot parameter to reserve\n"
    1.51  		      "some DMA memory (e.g., dom0_mem=-128M).\n");
    1.52  
    1.53 -	for (i = 0; i < iotlb_nslabs; i += IO_TLB_SEGSIZE)
    1.54 -		xen_create_contiguous_region(
    1.55 -			(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
    1.56 -			get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT));
    1.57 -
    1.58 -	iotlb_virt_end = iotlb_virt_start + bytes;
    1.59 +	xen_create_contiguous_region(
    1.60 +		(unsigned long)iotlb_virt_start, get_order(bytes));
    1.61  
    1.62  	/*
    1.63  	 * Allocate and initialize the free list array.  This array is used
    1.64 -	 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE
    1.65 -	 * between iotlb_virt_start and iotlb_virt_end.
    1.66 +	 * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE.
    1.67  	 */
    1.68  	io_tlb_list = alloc_bootmem(iotlb_nslabs * sizeof(int));
    1.69  	for (i = 0; i < iotlb_nslabs; i++)
    1.70 @@ -156,15 +155,19 @@ swiotlb_init_with_default_size (size_t d
    1.71  	 * Get the overflow emergency buffer
    1.72  	 */
    1.73  	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
    1.74 +
    1.75  	iotlb_bus_start = virt_to_bus(iotlb_virt_start);
    1.76 -	iotlb_bus_end   = iotlb_bus_start + bytes;
    1.77 +	iotlb_bus_mask  = ~(dma_addr_t)(bytes - 1);
    1.78 +
    1.79  	printk(KERN_INFO "Software IO TLB enabled: \n"
    1.80  	       " Aperture:     %lu megabytes\n"
    1.81  	       " Bus range:    0x%016lx - 0x%016lx\n"
    1.82  	       " Kernel range: 0x%016lx - 0x%016lx\n",
    1.83  	       bytes >> 20,
    1.84 -	       (unsigned long)iotlb_bus_start, (unsigned long)iotlb_bus_end,
    1.85 -	       (unsigned long)iotlb_virt_start, (unsigned long)iotlb_virt_end);
    1.86 +	       (unsigned long)iotlb_bus_start,
    1.87 +	       (unsigned long)iotlb_bus_start + bytes,
    1.88 +	       (unsigned long)iotlb_virt_start,
    1.89 +	       (unsigned long)iotlb_virt_start + bytes);
    1.90  }
    1.91  
    1.92  void
    1.93 @@ -444,7 +447,7 @@ swiotlb_unmap_single(struct device *hwde
    1.94  		     int dir)
    1.95  {
    1.96  	BUG_ON(dir == DMA_NONE);
    1.97 -	if ((dev_addr >= iotlb_bus_start) && (dev_addr < iotlb_bus_end))
    1.98 +	if (in_swiotlb_aperture(dev_addr))
    1.99  		unmap_single(hwdev, bus_to_virt(dev_addr), size, dir);
   1.100  }
   1.101  
   1.102 @@ -463,7 +466,7 @@ swiotlb_sync_single_for_cpu(struct devic
   1.103  			    size_t size, int dir)
   1.104  {
   1.105  	BUG_ON(dir == DMA_NONE);
   1.106 -	if ((dev_addr >= iotlb_bus_start) && (dev_addr < iotlb_bus_end))
   1.107 +	if (in_swiotlb_aperture(dev_addr))
   1.108  		sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
   1.109  }
   1.110  
   1.111 @@ -472,7 +475,7 @@ swiotlb_sync_single_for_device(struct de
   1.112  			       size_t size, int dir)
   1.113  {
   1.114  	BUG_ON(dir == DMA_NONE);
   1.115 -	if ((dev_addr >= iotlb_bus_start) && (dev_addr < iotlb_bus_end))
   1.116 +	if (in_swiotlb_aperture(dev_addr))
   1.117  		sync_single(hwdev, bus_to_virt(dev_addr), size, dir);
   1.118  }
   1.119  
   1.120 @@ -610,7 +613,7 @@ swiotlb_unmap_page(struct device *hwdev,
   1.121  		   size_t size, enum dma_data_direction direction)
   1.122  {
   1.123  	BUG_ON(direction == DMA_NONE);
   1.124 -	if ((dma_address >= iotlb_bus_start) && (dma_address < iotlb_bus_end))
   1.125 +	if (in_swiotlb_aperture(dma_address))
   1.126  		unmap_single(hwdev, bus_to_virt(dma_address), size, direction);
   1.127  }
   1.128