[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Re: [PATCH 14/15] [swiotlb] Move initialization (swiotlb_init) and its friends in swiotlb-default.c
* Konrad Rzeszutek Wilk (konrad.wilk@xxxxxxxxxx) wrote: > We move all of the initialization functions and as well > all functions defined in the swiotlb_ops to a seperate file. > > Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> > --- > lib/Makefile | 2 +- > lib/swiotlb-default.c | 242 > +++++++++++++++++++++++++++++++++++++++++++++++++ > lib/swiotlb.c | 231 +---------------------------------------------- > 3 files changed, 245 insertions(+), 230 deletions(-) > create mode 100644 lib/swiotlb-default.c > > diff --git a/lib/Makefile b/lib/Makefile > index 347ad8d..fd96891 100644 > --- a/lib/Makefile > +++ b/lib/Makefile > @@ -77,7 +77,7 @@ obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o > obj-$(CONFIG_SMP) += percpu_counter.o > obj-$(CONFIG_AUDIT_GENERIC) += audit.o > > -obj-$(CONFIG_SWIOTLB) += swiotlb.o > +obj-$(CONFIG_SWIOTLB) += swiotlb.o swiotlb-default.o > obj-$(CONFIG_IOMMU_HELPER) += iommu-helper.o > obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o > > diff --git a/lib/swiotlb-default.c b/lib/swiotlb-default.c > new file mode 100644 > index 0000000..c490fcf > --- /dev/null > +++ b/lib/swiotlb-default.c > @@ -0,0 +1,242 @@ > + > +#include <linux/dma-mapping.h> > +#include <linux/swiotlb.h> > +#include <linux/bootmem.h> > + > + > +#define OFFSET(val, align) ((unsigned long) \ > + (val) & ((align) - 1)) > + > +#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) > + > +/* > + * Minimum IO TLB size to bother booting with. Systems with mainly > + * 64bit capable cards will only lightly use the swiotlb. If we can't > + * allocate a contiguous 1MB, we're probably in trouble anyway. > + */ > +#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) > + > +/* Note that this doesn't work with highmem page */ > +static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, > + void *address) > +{ > + return phys_to_dma(hwdev, virt_to_phys(address)); > +} > + > +static void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t dev_addr) > +{ > + return phys_to_virt(dma_to_phys(hwdev, dev_addr)); > +}; > + > +/* > + * Statically reserve bounce buffer space and initialize bounce buffer data > + * structures for the software IO TLB used to implement the DMA API. > + */ > +void __init > +swiotlb_init_with_default_size(struct swiotlb_engine *iommu_sw, > + size_t default_size, int verbose) > +{ > + unsigned long i, bytes; > + > + if (!swiotlb_nslabs) { > + iommu_sw->nslabs = (default_size >> IO_TLB_SHIFT); > + iommu_sw->nslabs = ALIGN(iommu_sw->nslabs, IO_TLB_SEGSIZE); > + } else > + iommu_sw->nslabs = swiotlb_nslabs; > + > + bytes = iommu_sw->nslabs << IO_TLB_SHIFT; > + > + /* > + * Get IO TLB memory from the low pages > + */ > + iommu_sw->start = alloc_bootmem_low_pages(bytes); > + if (!iommu_sw->start) > + panic("Cannot allocate SWIOTLB buffer"); > + iommu_sw->end = iommu_sw->start + bytes; > + > + /* > + * Allocate and initialize the free list array. This array is used > + * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE > + * between iommu_sw->start and iommu_sw->end. > + */ > + iommu_sw->list = alloc_bootmem(iommu_sw->nslabs * sizeof(int)); > + for (i = 0; i < iommu_sw->nslabs; i++) > + iommu_sw->list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); > + iommu_sw->index = 0; > + iommu_sw->orig_addr = alloc_bootmem(iommu_sw->nslabs * > + sizeof(phys_addr_t)); > + > + /* > + * Get the overflow emergency buffer > + */ > + iommu_sw->overflow_buffer = alloc_bootmem_low(iommu_sw->overflow); > + if (!iommu_sw->overflow_buffer) > + panic("Cannot allocate SWIOTLB overflow buffer!\n"); > + if (verbose) > + swiotlb_print_info(); > + > + iommu_sw->priv = NULL; > +} > + > +int swiotlb_release(struct swiotlb_engine *iommu_sw) > +{ > + if (!iommu_sw) > + return -ENODEV; > + > + if (iommu_sw->priv) { > + free_pages((unsigned long)iommu_sw->overflow_buffer, > + get_order(iommu_sw->overflow)); > + free_pages((unsigned long)iommu_sw->orig_addr, > + get_order(iommu_sw->nslabs * sizeof(phys_addr_t))); > + free_pages((unsigned long)iommu_sw->list, > + get_order(iommu_sw->nslabs * sizeof(int))); > + free_pages((unsigned long)iommu_sw->start, > + get_order(iommu_sw->nslabs << IO_TLB_SHIFT)); > + } else { > + free_bootmem_late(__pa(iommu_sw->overflow_buffer), > + iommu_sw->overflow); > + free_bootmem_late(__pa(iommu_sw->orig_addr), > + iommu_sw->nslabs * sizeof(phys_addr_t)); > + free_bootmem_late(__pa(iommu_sw->list), > + iommu_sw->nslabs * sizeof(int)); > + free_bootmem_late(__pa(iommu_sw->start), > + iommu_sw->nslabs << IO_TLB_SHIFT); > + } > + return 0; > +} > + > +static int is_swiotlb_buffer(struct swiotlb_engine *iommu_sw, > + dma_addr_t dma_addr, phys_addr_t paddr) > +{ > + return paddr >= virt_to_phys(iommu_sw->start) && > + paddr < virt_to_phys(iommu_sw->end); > +} > + > +static bool swiotlb_dma_capable(struct device *hwdev, dma_addr_t dma_addr, > + phys_addr_t phys, size_t size) > +{ > + /* Phys is not neccessary in this case. */ > + return dma_capable(hwdev, dma_addr, size); > +} > +static struct swiotlb_engine swiotlb_ops = { > + .name = "software IO TLB", > + .overflow = 32 * 1024, > + .release = swiotlb_release, > + .dma_capable = swiotlb_dma_capable, > + .is_swiotlb_buffer = is_swiotlb_buffer, > + .phys_to_bus = phys_to_dma, > + .bus_to_phys = dma_to_phys, > + .virt_to_bus = swiotlb_virt_to_bus, > + .bus_to_virt = swiotlb_bus_to_virt, > +}; > + > +void __init > +swiotlb_init(int verbose) > +{ > + swiotlb_register_engine(&swiotlb_ops); > + swiotlb_init_with_default_size(&swiotlb_ops, 64 * (1<<20), > + verbose); /* default to 64MB */ > +} I'd expect the swiotlb-default file to have only private impl. of the swiotlb_engine. Shouldn't this and the init stay in swiotlb.c? Also, would you ever call swiotlb_init w/out register_engine, why not move register to the swiotlb_init? thanks, -chris _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |