* [PATCH 0 of 9] swiotlb: use phys_addr_t for pages
@ 2008-12-22 18:26 Jeremy Fitzhardinge
2008-12-22 18:26 ` [PATCH 1 of 9] revert "swiotlb: support bouncing of HighMem pages." Jeremy Fitzhardinge
` (10 more replies)
0 siblings, 11 replies; 29+ messages in thread
From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw)
To: Ingo Molnar
Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell,
Becky Bruce, FUJITA Tomonori
Hi all,
Here's a work in progress series whcih does a partial revert of the
previous swiotlb changes, and does a partial replacement with Becky
Bruce's series.
The most important difference is Becky's use of phys_addr_t rather
than page+offset to represent arbitrary pages. This turns out to be
simpler.
I didn't replicate the map_single_page changes, since I'm not exactly
sure of ppc's requirements here, and it seemed like something that
could be easily added.
Quick testing showed no problems, but I haven't had the chance to do
anything extensive.
I've made some small changes to Becky's patches to make them apply,
but I've separated any functional changes into separate patches with
appropriate authorship.
J
^ permalink raw reply [flat|nested] 29+ messages in thread* [PATCH 1 of 9] revert "swiotlb: support bouncing of HighMem pages." 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 2 of 9] revert "swiotlb: factor out copy to/from device." Jeremy Fitzhardinge ` (9 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori git commit ef9b189352f2eb78f14e52996f4780a523b04a49 --- lib/swiotlb.c | 122 +++++++++++++++------------------------------------------ 1 file changed, 33 insertions(+), 89 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -26,7 +26,6 @@ #include <linux/swiotlb.h> #include <linux/types.h> #include <linux/ctype.h> -#include <linux/highmem.h> #include <asm/io.h> #include <asm/dma.h> @@ -39,6 +38,9 @@ #define OFFSET(val,align) ((unsigned long) \ ( (val) & ( (align) - 1))) +#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) +#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) + #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) /* @@ -89,10 +91,7 @@ * We need to save away the original address corresponding to a mapped entry * for the sync operations. */ -static struct swiotlb_phys_addr { - struct page *page; - unsigned int offset; -} *io_tlb_orig_addr; +static unsigned char **io_tlb_orig_addr; /* * Protect the above data structures in the map and unmap calls @@ -151,11 +150,6 @@ return 0; } -static dma_addr_t swiotlb_sg_to_bus(struct scatterlist *sg) -{ - return swiotlb_phys_to_bus(page_to_phys(sg_page(sg)) + sg->offset); -} - static void swiotlb_print_info(unsigned long bytes) { phys_addr_t pstart, pend; @@ -215,7 +209,7 @@ for (i = 0; i < io_tlb_nslabs; i++) io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(struct swiotlb_phys_addr)); + io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); /* * Get the overflow emergency buffer @@ -289,12 +283,12 @@ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = (struct swiotlb_phys_addr *)__get_free_pages(GFP_KERNEL, - get_order(io_tlb_nslabs * sizeof(struct swiotlb_phys_addr))); + io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL, + get_order(io_tlb_nslabs * sizeof(char *))); if (!io_tlb_orig_addr) goto cleanup3; - memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(struct swiotlb_phys_addr)); + memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *)); /* * Get the overflow emergency buffer @@ -341,59 +335,20 @@ return addr >= io_tlb_start && addr < io_tlb_end; } -static struct swiotlb_phys_addr swiotlb_bus_to_phys_addr(char *dma_addr) +static void +__sync_single(char *buffer, char *dma_addr, size_t size, int dir) { - int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - struct swiotlb_phys_addr buffer = io_tlb_orig_addr[index]; - buffer.offset += (long)dma_addr & ((1 << IO_TLB_SHIFT) - 1); - buffer.page += buffer.offset >> PAGE_SHIFT; - buffer.offset &= PAGE_SIZE - 1; - return buffer; -} - -static void -__sync_single(struct swiotlb_phys_addr buffer, char *dma_addr, size_t size, int dir) -{ - if (PageHighMem(buffer.page)) { - size_t len, bytes; - char *dev, *host, *kmp; - - len = size; - while (len != 0) { - unsigned long flags; - - bytes = len; - if ((bytes + buffer.offset) > PAGE_SIZE) - bytes = PAGE_SIZE - buffer.offset; - local_irq_save(flags); /* protects KM_BOUNCE_READ */ - kmp = kmap_atomic(buffer.page, KM_BOUNCE_READ); - dev = dma_addr + size - len; - host = kmp + buffer.offset; - if (dir == DMA_FROM_DEVICE) - memcpy(host, dev, bytes); - else - memcpy(dev, host, bytes); - kunmap_atomic(kmp, KM_BOUNCE_READ); - local_irq_restore(flags); - len -= bytes; - buffer.page++; - buffer.offset = 0; - } - } else { - void *v = page_address(buffer.page) + buffer.offset; - - if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, v, size); - else - memcpy(v, dma_addr, size); - } + if (dir == DMA_TO_DEVICE) + memcpy(dma_addr, buffer, size); + else + memcpy(buffer, dma_addr, size); } /* * Allocates bounce buffer and returns its kernel virtual address. */ static void * -map_single(struct device *hwdev, struct swiotlb_phys_addr buffer, size_t size, int dir) +map_single(struct device *hwdev, char *buffer, size_t size, int dir) { unsigned long flags; char *dma_addr; @@ -403,7 +358,6 @@ unsigned long mask; unsigned long offset_slots; unsigned long max_slots; - struct swiotlb_phys_addr slot_buf; mask = dma_get_seg_boundary(hwdev); start_dma_addr = swiotlb_virt_to_bus(io_tlb_start) & mask; @@ -488,13 +442,8 @@ * This is needed when we sync the memory. Then we sync the buffer if * needed. */ - slot_buf = buffer; - for (i = 0; i < nslots; i++) { - slot_buf.page += slot_buf.offset >> PAGE_SHIFT; - slot_buf.offset &= PAGE_SIZE - 1; - io_tlb_orig_addr[index+i] = slot_buf; - slot_buf.offset += 1 << IO_TLB_SHIFT; - } + for (i = 0; i < nslots; i++) + io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); @@ -510,12 +459,12 @@ unsigned long flags; int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - struct swiotlb_phys_addr buffer = swiotlb_bus_to_phys_addr(dma_addr); + char *buffer = io_tlb_orig_addr[index]; /* * First, sync the memory before unmapping the entry */ - if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)) + if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) /* * bounce... copy the data back into the original buffer * and * delete the bounce buffer. @@ -552,7 +501,10 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir, int target) { - struct swiotlb_phys_addr buffer = swiotlb_bus_to_phys_addr(dma_addr); + int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; + char *buffer = io_tlb_orig_addr[index]; + + buffer += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1)); switch (target) { case SYNC_FOR_CPU: @@ -600,10 +552,7 @@ * swiotlb_map_single(), which will grab memory from * the lowest available address range. */ - struct swiotlb_phys_addr buffer; - buffer.page = virt_to_page(NULL); - buffer.offset = 0; - ret = map_single(hwdev, buffer, size, DMA_FROM_DEVICE); + ret = map_single(hwdev, NULL, size, DMA_FROM_DEVICE); if (!ret) return NULL; } @@ -671,7 +620,6 @@ { dma_addr_t dev_addr = swiotlb_virt_to_bus(ptr); void *map; - struct swiotlb_phys_addr buffer; BUG_ON(dir == DMA_NONE); /* @@ -686,9 +634,7 @@ /* * Oh well, have to allocate and map a bounce buffer. */ - buffer.page = virt_to_page(ptr); - buffer.offset = (unsigned long)ptr & ~PAGE_MASK; - map = map_single(hwdev, buffer, size, dir); + map = map_single(hwdev, ptr, size, dir); if (!map) { swiotlb_full(hwdev, size, dir, 1); map = io_tlb_overflow_buffer; @@ -833,20 +779,18 @@ int dir, struct dma_attrs *attrs) { struct scatterlist *sg; - struct swiotlb_phys_addr buffer; + void *addr; dma_addr_t dev_addr; int i; BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - dev_addr = swiotlb_sg_to_bus(sg); + addr = SG_ENT_VIRT_ADDRESS(sg); + dev_addr = swiotlb_virt_to_bus(addr); if (range_needs_mapping(sg_virt(sg), sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { - void *map; - buffer.page = sg_page(sg); - buffer.offset = sg->offset; - map = map_single(hwdev, buffer, sg->length, dir); + void *map = map_single(hwdev, addr, sg->length, dir); if (!map) { /* Don't panic here, we expect map_sg users to do proper error handling. */ @@ -886,11 +830,11 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != swiotlb_sg_to_bus(sg)) + if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); + dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); } } EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); @@ -919,11 +863,11 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != swiotlb_sg_to_bus(sg)) + if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir, target); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); + dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); } } ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 2 of 9] revert "swiotlb: factor out copy to/from device." 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 1 of 9] revert "swiotlb: support bouncing of HighMem pages." Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 3 of 9] swiotlb: add hwdev to swiotlb_phys_to_bus Jeremy Fitzhardinge ` (8 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori git commit 1b548f667c1487d92e794a9f7a67788f49b952d8 --- lib/swiotlb.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -335,15 +335,6 @@ return addr >= io_tlb_start && addr < io_tlb_end; } -static void -__sync_single(char *buffer, char *dma_addr, size_t size, int dir) -{ - if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, buffer, size); - else - memcpy(buffer, dma_addr, size); -} - /* * Allocates bounce buffer and returns its kernel virtual address. */ @@ -445,7 +436,7 @@ for (i = 0; i < nslots; i++) io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) - __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); + memcpy(dma_addr, buffer, size); return dma_addr; } @@ -469,7 +460,7 @@ * bounce... copy the data back into the original buffer * and * delete the bounce buffer. */ - __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); + memcpy(buffer, dma_addr, size); /* * Return the buffer to the free list by setting the corresponding @@ -509,13 +500,13 @@ switch (target) { case SYNC_FOR_CPU: if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) - __sync_single(buffer, dma_addr, size, DMA_FROM_DEVICE); + memcpy(buffer, dma_addr, size); else BUG_ON(dir != DMA_TO_DEVICE); break; case SYNC_FOR_DEVICE: if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) - __sync_single(buffer, dma_addr, size, DMA_TO_DEVICE); + memcpy(dma_addr, buffer, size); else BUG_ON(dir != DMA_FROM_DEVICE); break; ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 3 of 9] swiotlb: add hwdev to swiotlb_phys_to_bus 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 1 of 9] revert "swiotlb: support bouncing of HighMem pages." Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 2 of 9] revert "swiotlb: factor out copy to/from device." Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 4 of 9] swiotlb: Drop SG_ENT_VIRT_ADDRESS macro Jeremy Fitzhardinge ` (7 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori Some architectures need it. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> --- arch/x86/kernel/pci-swiotlb_64.c | 2 - include/linux/swiotlb.h | 3 +- lib/swiotlb.c | 45 +++++++++++++++----------------------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -23,7 +23,7 @@ return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order); } -dma_addr_t swiotlb_phys_to_bus(phys_addr_t paddr) +dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) { return paddr; } diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -27,7 +27,8 @@ extern void *swiotlb_alloc_boot(size_t bytes, unsigned long nslabs); extern void *swiotlb_alloc(unsigned order, unsigned long nslabs); -extern dma_addr_t swiotlb_phys_to_bus(phys_addr_t address); +extern dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, + phys_addr_t address); extern phys_addr_t swiotlb_bus_to_phys(dma_addr_t address); extern int swiotlb_arch_range_needs_mapping(void *ptr, size_t size); diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -125,7 +125,7 @@ return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order); } -dma_addr_t __weak swiotlb_phys_to_bus(phys_addr_t paddr) +dma_addr_t __weak swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) { return paddr; } @@ -135,9 +135,10 @@ return baddr; } -static dma_addr_t swiotlb_virt_to_bus(volatile void *address) +static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, + volatile void *address) { - return swiotlb_phys_to_bus(virt_to_phys(address)); + return swiotlb_phys_to_bus(hwdev, virt_to_phys(address)); } static void *swiotlb_bus_to_virt(dma_addr_t address) @@ -153,27 +154,15 @@ static void swiotlb_print_info(unsigned long bytes) { phys_addr_t pstart, pend; - dma_addr_t bstart, bend; pstart = virt_to_phys(io_tlb_start); pend = virt_to_phys(io_tlb_end); - bstart = swiotlb_phys_to_bus(pstart); - bend = swiotlb_phys_to_bus(pend); - printk(KERN_INFO "Placing %luMB software IO TLB between %p - %p\n", bytes >> 20, io_tlb_start, io_tlb_end); - if (pstart != bstart || pend != bend) - printk(KERN_INFO "software IO TLB at phys %#llx - %#llx" - " bus %#llx - %#llx\n", - (unsigned long long)pstart, - (unsigned long long)pend, - (unsigned long long)bstart, - (unsigned long long)bend); - else - printk(KERN_INFO "software IO TLB at phys %#llx - %#llx\n", - (unsigned long long)pstart, - (unsigned long long)pend); + printk(KERN_INFO "software IO TLB at phys %#llx - %#llx\n", + (unsigned long long)pstart, + (unsigned long long)pend); } /* @@ -351,7 +340,7 @@ unsigned long max_slots; mask = dma_get_seg_boundary(hwdev); - start_dma_addr = swiotlb_virt_to_bus(io_tlb_start) & mask; + start_dma_addr = swiotlb_virt_to_bus(hwdev, io_tlb_start) & mask; offset_slots = ALIGN(start_dma_addr, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; @@ -528,7 +517,9 @@ dma_mask = hwdev->coherent_dma_mask; ret = (void *)__get_free_pages(flags, order); - if (ret && !is_buffer_dma_capable(dma_mask, swiotlb_virt_to_bus(ret), size)) { + if (ret && + !is_buffer_dma_capable(dma_mask, swiotlb_virt_to_bus(hwdev, ret), + size)) { /* * The allocated memory isn't reachable by the device. * Fall back on swiotlb_map_single(). @@ -549,7 +540,7 @@ } memset(ret, 0, size); - dev_addr = swiotlb_virt_to_bus(ret); + dev_addr = swiotlb_virt_to_bus(hwdev, ret); /* Confirm address can be DMA'd by device */ if (!is_buffer_dma_capable(dma_mask, dev_addr, size)) { @@ -609,7 +600,7 @@ swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, int dir, struct dma_attrs *attrs) { - dma_addr_t dev_addr = swiotlb_virt_to_bus(ptr); + dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, ptr); void *map; BUG_ON(dir == DMA_NONE); @@ -631,7 +622,7 @@ map = io_tlb_overflow_buffer; } - dev_addr = swiotlb_virt_to_bus(map); + dev_addr = swiotlb_virt_to_bus(hwdev, map); /* * Ensure that the address returned is DMA'ble @@ -778,7 +769,7 @@ for_each_sg(sgl, sg, nelems, i) { addr = SG_ENT_VIRT_ADDRESS(sg); - dev_addr = swiotlb_virt_to_bus(addr); + dev_addr = swiotlb_virt_to_bus(hwdev, addr); if (range_needs_mapping(sg_virt(sg), sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { void *map = map_single(hwdev, addr, sg->length, dir); @@ -791,7 +782,7 @@ sgl[0].dma_length = 0; return 0; } - sg->dma_address = swiotlb_virt_to_bus(map); + sg->dma_address = swiotlb_virt_to_bus(hwdev, map); } else sg->dma_address = dev_addr; sg->dma_length = sg->length; @@ -879,7 +870,7 @@ int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) { - return (dma_addr == swiotlb_virt_to_bus(io_tlb_overflow_buffer)); + return (dma_addr == swiotlb_virt_to_bus(hwdev, io_tlb_overflow_buffer)); } /* @@ -891,7 +882,7 @@ int swiotlb_dma_supported(struct device *hwdev, u64 mask) { - return swiotlb_virt_to_bus(io_tlb_end - 1) <= mask; + return swiotlb_virt_to_bus(hwdev, io_tlb_end - 1) <= mask; } EXPORT_SYMBOL(swiotlb_map_single); ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 4 of 9] swiotlb: Drop SG_ENT_VIRT_ADDRESS macro 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (2 preceding siblings ...) 2008-12-22 18:26 ` [PATCH 3 of 9] swiotlb: add hwdev to swiotlb_phys_to_bus Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 5 of 9] swiotlb: Rename SG_ENT_PHYS_ADDRESS to SG_ENT_BUS_ADDRESS Jeremy Fitzhardinge ` (6 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori From: Becky Bruce <beckyb@kernel.crashing.org> All SG_ENT_VIRT_ADDRESS does is call sg_virt(), get rid of this needless layer of complexity. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -38,8 +38,7 @@ #define OFFSET(val,align) ((unsigned long) \ ( (val) & ( (align) - 1))) -#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) -#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg)) +#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(sg_virt(sg)) #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) @@ -768,9 +767,9 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - addr = SG_ENT_VIRT_ADDRESS(sg); + addr = sg_virt(sg); dev_addr = swiotlb_virt_to_bus(hwdev, addr); - if (range_needs_mapping(sg_virt(sg), sg->length) || + if (range_needs_mapping(addr, sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { void *map = map_single(hwdev, addr, sg->length, dir); if (!map) { @@ -816,7 +815,7 @@ unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); + dma_mark_clean(sg_virt(sg), sg->dma_length); } } EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); @@ -849,7 +848,7 @@ sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir, target); else if (dir == DMA_FROM_DEVICE) - dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); + dma_mark_clean(sg_virt(sg), sg->dma_length); } } ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 5 of 9] swiotlb: Rename SG_ENT_PHYS_ADDRESS to SG_ENT_BUS_ADDRESS 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (3 preceding siblings ...) 2008-12-22 18:26 ` [PATCH 4 of 9] swiotlb: Drop SG_ENT_VIRT_ADDRESS macro Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 6 of 9] swiotlb: Store phys address in io_tlb_orig_addr array Jeremy Fitzhardinge ` (5 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori From: Becky Bruce <beckyb@kernel.crashing.org> Also add hwdev argument - some platforms will need this to calculate an actual bus address. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -38,7 +38,7 @@ #define OFFSET(val,align) ((unsigned long) \ ( (val) & ( (align) - 1))) -#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(sg_virt(sg)) +#define SG_ENT_BUS_ADDRESS(hwdev, sg) swiotlb_virt_to_bus(hwdev, sg_virt(sg)) #define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT)) @@ -811,7 +811,7 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) + if (sg->dma_address != SG_ENT_BUS_ADDRESS(hwdev, sg)) unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir); else if (dir == DMA_FROM_DEVICE) @@ -844,7 +844,7 @@ BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) + if (sg->dma_address != SG_ENT_BUS_ADDRESS(hwdev, sg)) sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), sg->dma_length, dir, target); else if (dir == DMA_FROM_DEVICE) ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 6 of 9] swiotlb: Store phys address in io_tlb_orig_addr array 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (4 preceding siblings ...) 2008-12-22 18:26 ` [PATCH 5 of 9] swiotlb: Rename SG_ENT_PHYS_ADDRESS to SG_ENT_BUS_ADDRESS Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 7 of 9] swiotlb: Add support for systems with highmem Jeremy Fitzhardinge ` (4 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori From: Becky Bruce <beckyb@kernel.crashing.org> When we enable swiotlb for platforms that support HIGHMEM, we can no longer store the virtual address of the original dma buffer, because that buffer might not have a permament mapping. Change the iotlb code to instead store the physical address of the original buffer. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 47 ++++++++++++++++++++++++----------------------- 1 files changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -90,7 +90,7 @@ * We need to save away the original address corresponding to a mapped entry * for the sync operations. */ -static unsigned char **io_tlb_orig_addr; +static phys_addr_t *io_tlb_orig_addr; /* * Protect the above data structures in the map and unmap calls @@ -197,7 +197,7 @@ for (i = 0; i < io_tlb_nslabs; i++) io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); + io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(phys_addr_t)); /* * Get the overflow emergency buffer @@ -271,12 +271,14 @@ io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_index = 0; - io_tlb_orig_addr = (unsigned char **)__get_free_pages(GFP_KERNEL, - get_order(io_tlb_nslabs * sizeof(char *))); + io_tlb_orig_addr = (phys_addr_t *) + __get_free_pages(GFP_KERNEL, + get_order(io_tlb_nslabs * + sizeof(phys_addr_t))); if (!io_tlb_orig_addr) goto cleanup3; - memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(char *)); + memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(phys_addr_t)); /* * Get the overflow emergency buffer @@ -291,8 +293,8 @@ return 0; cleanup4: - free_pages((unsigned long)io_tlb_orig_addr, get_order(io_tlb_nslabs * - sizeof(char *))); + free_pages((unsigned long)io_tlb_orig_addr, + get_order(io_tlb_nslabs * sizeof(phys_addr_t))); io_tlb_orig_addr = NULL; cleanup3: free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * @@ -327,7 +329,7 @@ * Allocates bounce buffer and returns its kernel virtual address. */ static void * -map_single(struct device *hwdev, char *buffer, size_t size, int dir) +map_single(struct device *hwdev, phys_addr_t phys, size_t size, int dir) { unsigned long flags; char *dma_addr; @@ -422,9 +424,9 @@ * needed. */ for (i = 0; i < nslots; i++) - io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT); + io_tlb_orig_addr[index+i] = phys + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) - memcpy(dma_addr, buffer, size); + memcpy(dma_addr, phys_to_virt(phys), size); return dma_addr; } @@ -438,17 +440,17 @@ unsigned long flags; int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - char *buffer = io_tlb_orig_addr[index]; + phys_addr_t phys = io_tlb_orig_addr[index]; /* * First, sync the memory before unmapping the entry */ - if (buffer && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) + if (phys && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) /* * bounce... copy the data back into the original buffer * and * delete the bounce buffer. */ - memcpy(buffer, dma_addr, size); + memcpy(phys_to_virt(phys), dma_addr, size); /* * Return the buffer to the free list by setting the corresponding @@ -481,20 +483,20 @@ int dir, int target) { int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - char *buffer = io_tlb_orig_addr[index]; + phys_addr_t phys = io_tlb_orig_addr[index]; - buffer += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1)); + phys += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1)); switch (target) { case SYNC_FOR_CPU: if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(buffer, dma_addr, size); + memcpy(phys_to_virt(phys), dma_addr, size); else BUG_ON(dir != DMA_TO_DEVICE); break; case SYNC_FOR_DEVICE: if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(dma_addr, buffer, size); + memcpy(dma_addr, phys_to_virt(phys), size); else BUG_ON(dir != DMA_FROM_DEVICE); break; @@ -533,7 +535,7 @@ * swiotlb_map_single(), which will grab memory from * the lowest available address range. */ - ret = map_single(hwdev, NULL, size, DMA_FROM_DEVICE); + ret = map_single(hwdev, 0, size, DMA_FROM_DEVICE); if (!ret) return NULL; } @@ -615,7 +617,7 @@ /* * Oh well, have to allocate and map a bounce buffer. */ - map = map_single(hwdev, ptr, size, dir); + map = map_single(hwdev, virt_to_phys(ptr), size, dir); if (!map) { swiotlb_full(hwdev, size, dir, 1); map = io_tlb_overflow_buffer; @@ -760,18 +762,18 @@ int dir, struct dma_attrs *attrs) { struct scatterlist *sg; - void *addr; - dma_addr_t dev_addr; int i; BUG_ON(dir == DMA_NONE); for_each_sg(sgl, sg, nelems, i) { - addr = sg_virt(sg); - dev_addr = swiotlb_virt_to_bus(hwdev, addr); + void *addr = sg_virt(sg); + dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, addr); + if (range_needs_mapping(addr, sg->length) || address_needs_mapping(hwdev, dev_addr, sg->length)) { - void *map = map_single(hwdev, addr, sg->length, dir); + void *map = map_single(hwdev, sg_phys(sg), + sg->length, dir); if (!map) { /* Don't panic here, we expect map_sg users to do proper error handling. */ ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 7 of 9] swiotlb: Add support for systems with highmem 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (5 preceding siblings ...) 2008-12-22 18:26 ` [PATCH 6 of 9] swiotlb: Store phys address in io_tlb_orig_addr array Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 8 of 9] swiotlb: cleanups to swiotlb_bounce() Jeremy Fitzhardinge ` (3 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori From: Becky Bruce <beckyb@kernel.crashing.org> On highmem systems, the original dma buffer might not have a virtual mapping - we need to kmap it in to perform the bounce. Extract the code that does the actual copy into a function that does the kmap if highmem is enabled, and defaults to the normal swiotlb memcpy if not. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- lib/swiotlb.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 45 insertions(+), 8 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -14,6 +14,7 @@ * 04/07/.. ak Better overflow handling. Assorted fixes. * 05/09/10 linville Add support for syncing ranges, support syncing for * DMA_BIDIRECTIONAL mappings, miscellaneous cleanup. + * 08/12/11 beckyb Add highmem support */ #include <linux/cache.h> @@ -26,6 +27,7 @@ #include <linux/swiotlb.h> #include <linux/types.h> #include <linux/ctype.h> +#include <linux/highmem.h> #include <asm/io.h> #include <asm/dma.h> @@ -326,6 +328,45 @@ } /* + * Bounce: copy the swiotlb buffer back to the original dma location + */ +void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, + enum dma_data_direction dir) +{ +#ifdef CONFIG_HIGHMEM + /* The buffer may not have a mapping. Map it in and copy */ + unsigned int offset = ((unsigned long)phys & + ((1 << PAGE_SHIFT) - 1)); + char *buffer; + unsigned int sz = 0; + unsigned long flags; + + while (size) { + sz = ((PAGE_SIZE - offset) > size) ? size : + PAGE_SIZE - offset; + local_irq_save(flags); + buffer = kmap_atomic(pfn_to_page(phys >> PAGE_SHIFT), + KM_BOUNCE_READ); + if (dir == DMA_TO_DEVICE) + memcpy(dma_addr, buffer + offset, sz); + else + memcpy(buffer + offset, dma_addr, sz); + kunmap_atomic(buffer, KM_BOUNCE_READ); + local_irq_restore(flags); + size -= sz; + phys += sz; + dma_addr += sz; + offset = 0; + } +#else + if (dir == DMA_TO_DEVICE) + memcpy(dma_addr, phys_to_virt(phys), size); + else + memcpy(phys_to_virt(phys), dma_addr, size); +#endif +} + +/* * Allocates bounce buffer and returns its kernel virtual address. */ static void * @@ -426,7 +467,7 @@ for (i = 0; i < nslots; i++) io_tlb_orig_addr[index+i] = phys + (i << IO_TLB_SHIFT); if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) - memcpy(dma_addr, phys_to_virt(phys), size); + swiotlb_bounce(phys, dma_addr, size, DMA_TO_DEVICE); return dma_addr; } @@ -446,11 +487,7 @@ * First, sync the memory before unmapping the entry */ if (phys && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) - /* - * bounce... copy the data back into the original buffer * and - * delete the bounce buffer. - */ - memcpy(phys_to_virt(phys), dma_addr, size); + swiotlb_bounce(phys, dma_addr, size, DMA_FROM_DEVICE); /* * Return the buffer to the free list by setting the corresponding @@ -490,13 +527,13 @@ switch (target) { case SYNC_FOR_CPU: if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(phys_to_virt(phys), dma_addr, size); + swiotlb_bounce(phys, dma_addr, size, DMA_FROM_DEVICE); else BUG_ON(dir != DMA_TO_DEVICE); break; case SYNC_FOR_DEVICE: if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) - memcpy(dma_addr, phys_to_virt(phys), size); + swiotlb_bounce(phys, dma_addr, size, DMA_TO_DEVICE); else BUG_ON(dir != DMA_FROM_DEVICE); break; ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 8 of 9] swiotlb: cleanups to swiotlb_bounce() 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (6 preceding siblings ...) 2008-12-22 18:26 ` [PATCH 7 of 9] swiotlb: Add support for systems with highmem Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops Jeremy Fitzhardinge ` (2 subsequent siblings) 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori Make swiotlb_bounce test each page for highness rather than relying on CONFIG_HIGHMEM, and a couple of other cleanups. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> --- lib/swiotlb.c | 61 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -25,6 +25,7 @@ #include <linux/swiotlb.h> #include <linux/string.h> #include <linux/swiotlb.h> +#include <linux/pfn.h> #include <linux/types.h> #include <linux/ctype.h> #include <linux/highmem.h> @@ -330,40 +331,42 @@ /* * Bounce: copy the swiotlb buffer back to the original dma location */ -void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, - enum dma_data_direction dir) +static void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, + enum dma_data_direction dir) { -#ifdef CONFIG_HIGHMEM - /* The buffer may not have a mapping. Map it in and copy */ - unsigned int offset = ((unsigned long)phys & - ((1 << PAGE_SHIFT) - 1)); - char *buffer; - unsigned int sz = 0; - unsigned long flags; + unsigned long pfn = PFN_DOWN(phys); - while (size) { - sz = ((PAGE_SIZE - offset) > size) ? size : - PAGE_SIZE - offset; - local_irq_save(flags); - buffer = kmap_atomic(pfn_to_page(phys >> PAGE_SHIFT), - KM_BOUNCE_READ); + if (PageHighMem(pfn_to_page(pfn))) { + /* The buffer does not have a mapping. Map it in and copy */ + unsigned int offset = phys & ~PAGE_MASK; + char *buffer; + unsigned int sz = 0; + unsigned long flags; + + while (size) { + sz = min(PAGE_SIZE - offset, size); + + local_irq_save(flags); + buffer = kmap_atomic(pfn_to_page(pfn), + KM_BOUNCE_READ); + if (dir == DMA_TO_DEVICE) + memcpy(dma_addr, buffer + offset, sz); + else + memcpy(buffer + offset, dma_addr, sz); + kunmap_atomic(buffer, KM_BOUNCE_READ); + local_irq_restore(flags); + + size -= sz; + pfn++; + dma_addr += sz; + offset = 0; + } + } else { if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, buffer + offset, sz); + memcpy(dma_addr, phys_to_virt(phys), size); else - memcpy(buffer + offset, dma_addr, sz); - kunmap_atomic(buffer, KM_BOUNCE_READ); - local_irq_restore(flags); - size -= sz; - phys += sz; - dma_addr += sz; - offset = 0; + memcpy(phys_to_virt(phys), dma_addr, size); } -#else - if (dir == DMA_TO_DEVICE) - memcpy(dma_addr, phys_to_virt(phys), size); - else - memcpy(phys_to_virt(phys), dma_addr, size); -#endif } /* ^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (7 preceding siblings ...) 2008-12-22 18:26 ` [PATCH 8 of 9] swiotlb: cleanups to swiotlb_bounce() Jeremy Fitzhardinge @ 2008-12-22 18:26 ` Jeremy Fitzhardinge 2008-12-22 18:43 ` [PATCH 0 of 9] swiotlb: use phys_addr_t for pages FUJITA Tomonori 2008-12-27 10:48 ` Ingo Molnar 10 siblings, 0 replies; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-22 18:26 UTC (permalink / raw) To: Ingo Molnar Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori From: Becky Bruce <beckyb@kernel.crashing.org> SWIOTLB currently uses "int" as the type of the dma direction, not "enum dma_data_direction as documented in DMA_API.txt. Now that this code is about to become shared with powerpc, which uses the enum, update the swiotlb code to use the enum as well. Doing this requires changing all the arch's that use swiotlb use the enum also. Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org> --- arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ arch/ia64/hp/common/sba_iommu.c | 12 ++++--- arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ arch/ia64/kernel/machvec.c | 6 ++- arch/ia64/sn/kernel/io_common.c | 3 +- arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- arch/ia64/sn/pci/tioca_provider.c | 3 +- arch/x86/include/asm/dma-mapping.h | 50 ++++++++++++++++++-------------- arch/x86/include/asm/swiotlb.h | 24 +++++++++------ arch/x86/include/asm/tce.h | 3 +- arch/x86/kernel/amd_iommu.c | 16 +++++----- arch/x86/kernel/pci-calgary_64.c | 11 ++++--- arch/x86/kernel/pci-gart_64.c | 19 ++++++++---- arch/x86/kernel/pci-nommu.c | 4 +- arch/x86/kernel/pci-swiotlb_64.c | 2 +- arch/x86/kernel/tce_64.c | 3 +- drivers/pci/intel-iommu.c | 13 ++++---- include/linux/intel-iommu.h | 12 +++++-- include/linux/swiotlb.h | 33 ++++++++++++--------- lib/swiotlb.c | 54 ++++++++++++++++++++--------------- 23 files changed, 219 insertions(+), 159 deletions(-) diff --git a/arch/ia64/dig/dig_vtd_iommu.c b/arch/ia64/dig/dig_vtd_iommu.c --- a/arch/ia64/dig/dig_vtd_iommu.c +++ b/arch/ia64/dig/dig_vtd_iommu.c @@ -21,7 +21,7 @@ dma_addr_t vtd_map_single_attrs(struct device *dev, void *addr, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { return intel_map_single(dev, (phys_addr_t)addr, size, dir); } @@ -29,7 +29,7 @@ void vtd_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { intel_unmap_single(dev, iova, size, dir); } @@ -37,7 +37,7 @@ int vtd_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { return intel_map_sg(dev, sglist, nents, dir); } @@ -45,7 +45,8 @@ void vtd_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, - int nents, int dir, struct dma_attrs *attrs) + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) { intel_unmap_sg(dev, sglist, nents, dir); } diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -91,8 +91,8 @@ } dma_addr_t -hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, - struct dma_attrs *attrs) +hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_map_single_attrs(dev, addr, size, dir, attrs); @@ -103,7 +103,7 @@ void hwsw_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_unmap_single_attrs(dev, iova, size, dir, attrs); @@ -114,7 +114,7 @@ int hwsw_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_map_sg_attrs(dev, sglist, nents, dir, attrs); @@ -125,7 +125,7 @@ void hwsw_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { if (use_swiotlb(dev)) return swiotlb_unmap_sg_attrs(dev, sglist, nents, dir, attrs); @@ -135,7 +135,8 @@ EXPORT_SYMBOL(hwsw_unmap_sg_attrs); void -hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir) +hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_single_for_cpu(dev, addr, size, dir); @@ -144,7 +145,8 @@ } void -hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir) +hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir); @@ -153,7 +155,8 @@ } void -hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir) +hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_single_for_device(dev, addr, size, dir); @@ -162,7 +165,8 @@ } void -hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir) +hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction dir) { if (use_swiotlb(dev)) swiotlb_sync_sg_for_device(dev, sg, nelems, dir); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -909,8 +909,8 @@ * See Documentation/DMA-mapping.txt */ dma_addr_t -sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, - struct dma_attrs *attrs) +sba_map_single_attrs(struct device *dev, void *addr, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) { struct ioc *ioc; dma_addr_t iovp; @@ -1027,7 +1027,8 @@ * See Documentation/DMA-mapping.txt */ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, + struct dma_attrs *attrs) { struct ioc *ioc; #if DELAYED_RESOURCE_CNT > 0 @@ -1423,7 +1424,7 @@ * See Documentation/DMA-mapping.txt */ int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { struct ioc *ioc; int coalesced, filled = 0; @@ -1515,7 +1516,8 @@ * See Documentation/DMA-mapping.txt */ void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, - int nents, int dir, struct dma_attrs *attrs) + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) { #ifdef ASSERT_PDIR_SANITY struct ioc *ioc; diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -17,32 +17,32 @@ void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); dma_addr_t (*map_single)(struct device *hwdev, unsigned long ptr, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*unmap_single)(struct device *dev, dma_addr_t addr, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*sync_single_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_for_device)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_range_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*sync_single_range_for_device)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, enum dma_data_direction direction); void (*sync_sg_for_cpu)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); void (*sync_sg_for_device)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); int (*map_sg)(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); void (*unmap_sg)(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); int (*dma_supported_op)(struct device *hwdev, u64 mask); int is_phys; }; @@ -70,25 +70,26 @@ } #define dma_map_single_attrs platform_dma_map_single_attrs static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, - size_t size, int dir) + size_t size, + enum dma_data_direction dir) { return dma_map_single_attrs(dev, cpu_addr, size, dir, NULL); } #define dma_map_sg_attrs platform_dma_map_sg_attrs static inline int dma_map_sg(struct device *dev, struct scatterlist *sgl, - int nents, int dir) + int nents, enum dma_data_direction dir) { return dma_map_sg_attrs(dev, sgl, nents, dir, NULL); } #define dma_unmap_single_attrs platform_dma_unmap_single_attrs static inline void dma_unmap_single(struct device *dev, dma_addr_t cpu_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { return dma_unmap_single_attrs(dev, cpu_addr, size, dir, NULL); } #define dma_unmap_sg_attrs platform_dma_unmap_sg_attrs static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sgl, - int nents, int dir) + int nents, enum dma_data_direction dir) { return dma_unmap_sg_attrs(dev, sgl, nents, dir, NULL); } diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h --- a/arch/ia64/include/asm/swiotlb.h +++ b/arch/ia64/include/asm/swiotlb.h @@ -6,35 +6,41 @@ /* SWIOTLB interface */ extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c --- a/arch/ia64/kernel/machvec.c +++ b/arch/ia64/kernel/machvec.c @@ -75,14 +75,16 @@ EXPORT_SYMBOL(machvec_timer_interrupt); void -machvec_dma_sync_single (struct device *hwdev, dma_addr_t dma_handle, size_t size, int dir) +machvec_dma_sync_single (struct device *hwdev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir) { mb(); } EXPORT_SYMBOL(machvec_dma_sync_single); void -machvec_dma_sync_sg (struct device *hwdev, struct scatterlist *sg, int n, int dir) +machvec_dma_sync_sg (struct device *hwdev, struct scatterlist *sg, int n, + enum dma_data_direction dir) { mb(); } diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -60,7 +60,8 @@ } static void -sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) +sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, + enum dma_data_direction direction) { return; } diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -174,7 +174,8 @@ * figure out how to save dmamap handle so can use two step. */ dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr, - size_t size, int direction, + size_t size, + enum dma_data_direction direction, struct dma_attrs *attrs) { dma_addr_t dma_addr; @@ -216,7 +217,8 @@ * coherent, so we just need to free any ATEs associated with this mapping. */ void sn_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr, - size_t size, int direction, + size_t size, + enum dma_data_direction direction, struct dma_attrs *attrs) { struct pci_dev *pdev = to_pci_dev(dev); @@ -239,7 +241,7 @@ * Unmap a set of streaming mode DMA translations. */ void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl, - int nhwentries, int direction, + int nhwentries, enum dma_data_direction direction, struct dma_attrs *attrs) { int i; @@ -273,7 +275,8 @@ * Maps each entry of @sg for DMA. */ int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, - int nhwentries, int direction, struct dma_attrs *attrs) + int nhwentries, enum dma_data_direction direction, + struct dma_attrs *attrs) { unsigned long phys_addr; struct scatterlist *saved_sg = sgl, *sg; @@ -323,28 +326,30 @@ EXPORT_SYMBOL(sn_dma_map_sg_attrs); void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, + enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } EXPORT_SYMBOL(sn_dma_sync_single_for_cpu); void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, + enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } EXPORT_SYMBOL(sn_dma_sync_single_for_device); void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu); void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { BUG_ON(dev->bus != &pci_bus_type); } diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -205,7 +205,8 @@ * DMA mappings for Direct 64 and 32 do not have any DMA maps. */ void -pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction) +pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, + enum dma_data_direction direction) { struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev); struct pcibus_info *pcibus_info = diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -467,7 +467,8 @@ * resources to release. */ static void -tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) +tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, + enum dma_data_direction dir) { int i, entry; struct tioca_common *tioca_common; diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -25,32 +25,36 @@ void (*free_coherent)(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*unmap_single)(struct device *dev, dma_addr_t addr, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*sync_single_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_for_device)(struct device *hwdev, dma_addr_t dma_handle, size_t size, - int direction); + enum dma_data_direction direction); void (*sync_single_range_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*sync_single_range_for_device)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, - size_t size, int direction); + size_t size, + enum dma_data_direction direction); void (*sync_sg_for_cpu)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); void (*sync_sg_for_device)(struct device *hwdev, struct scatterlist *sg, int nelems, - int direction); + enum dma_data_direction direction); int (*map_sg)(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); void (*unmap_sg)(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); int (*dma_supported)(struct device *hwdev, u64 mask); int is_phys; }; @@ -91,7 +95,7 @@ static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -102,7 +106,7 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(dev); @@ -113,7 +117,7 @@ static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction) + int nents, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -123,7 +127,7 @@ static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -134,7 +138,7 @@ static inline void dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -146,7 +150,7 @@ static inline void dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -158,7 +162,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, - unsigned long offset, size_t size, int direction) + unsigned long offset, size_t size, + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -172,7 +177,7 @@ static inline void dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -185,7 +190,7 @@ static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -197,7 +202,7 @@ static inline void dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(hwdev); @@ -210,7 +215,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size, - int direction) + enum dma_data_direction direction) { struct dma_mapping_ops *ops = get_dma_ops(dev); @@ -220,7 +225,8 @@ } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, - size_t size, int direction) + size_t size, + enum dma_data_direction direction) { dma_unmap_single(dev, addr, size, direction); } diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h --- a/arch/x86/include/asm/swiotlb.h +++ b/arch/x86/include/asm/swiotlb.h @@ -6,35 +6,39 @@ /* SWIOTLB interface */ extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, - size_t size, int dir); + size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, - int dir); + enum dma_data_direction dir); extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction); + int nents, enum dma_data_direction direction); extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); diff --git a/arch/x86/include/asm/tce.h b/arch/x86/include/asm/tce.h --- a/arch/x86/include/asm/tce.h +++ b/arch/x86/include/asm/tce.h @@ -39,7 +39,8 @@ #define TCE_RPN_MASK 0x0000fffffffff000ULL extern void tce_build(struct iommu_table *tbl, unsigned long index, - unsigned int npages, unsigned long uaddr, int direction); + unsigned int npages, unsigned long uaddr, + enum dma_data_direction direction); extern void tce_free(struct iommu_table *tbl, long index, unsigned int npages); extern void * __init alloc_tce_table(void); extern void __init free_tce_table(void *tbl); diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -873,7 +873,7 @@ struct dma_ops_domain *dom, unsigned long address, phys_addr_t paddr, - int direction) + enum dma_data_direction direction) { u64 *pte, __pte; @@ -933,7 +933,7 @@ struct dma_ops_domain *dma_dom, phys_addr_t paddr, size_t size, - int dir, + enum dma_data_direction dir, bool align, u64 dma_mask) { @@ -980,7 +980,7 @@ struct dma_ops_domain *dma_dom, dma_addr_t dma_addr, size_t size, - int dir) + enum dma_data_direction dir) { dma_addr_t i, start; unsigned int pages; @@ -1010,7 +1010,7 @@ * The exported map_single function for dma_ops. */ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1048,7 +1048,7 @@ * The exported unmap_single function for dma_ops. */ static void unmap_single(struct device *dev, dma_addr_t dma_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1074,7 +1074,7 @@ * device which is not handled by an AMD IOMMU in the system. */ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { struct scatterlist *s; int i; @@ -1092,7 +1092,7 @@ * lists). */ static int map_sg(struct device *dev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; @@ -1154,7 +1154,7 @@ * lists). */ static void unmap_sg(struct device *dev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { unsigned long flags; struct amd_iommu *iommu; diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -297,7 +297,8 @@ } static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl, - void *vaddr, unsigned int npages, int direction) + void *vaddr, unsigned int npages, + enum dma_data_direction direction) { unsigned long entry; dma_addr_t ret = bad_dma_address; @@ -381,7 +382,7 @@ } static void calgary_unmap_sg(struct device *dev, - struct scatterlist *sglist, int nelems, int direction) + struct scatterlist *sglist, int nelems, enum dma_data_direction dir) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -404,7 +405,7 @@ } static int calgary_map_sg(struct device *dev, struct scatterlist *sg, - int nelems, int direction) + int nelems, enum dma_data_direction direction) { struct iommu_table *tbl = find_iommu_table(dev); struct scatterlist *s; @@ -446,7 +447,7 @@ } static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { void *vaddr = phys_to_virt(paddr); unsigned long uaddr; @@ -460,7 +461,7 @@ } static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { struct iommu_table *tbl = find_iommu_table(dev); unsigned int npages; diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -188,7 +188,8 @@ # define CLEAR_LEAK(x) #endif -static void iommu_full(struct device *dev, size_t size, int dir) +static void +iommu_full(struct device *dev, size_t size, enum dma_data_direction dir) { /* * Ran out of IOMMU space for this operation. This is very bad. @@ -231,7 +232,8 @@ * Caller needs to check if the iommu is needed and flush. */ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, - size_t size, int dir, unsigned long align_mask) + size_t size, enum dma_data_direction dir, + unsigned long align_mask) { unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE); unsigned long iommu_page = alloc_iommu(dev, npages, align_mask); @@ -256,7 +258,8 @@ /* Map a single area into the IOMMU */ static dma_addr_t -gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) +gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { unsigned long bus; @@ -276,7 +279,7 @@ * Free a DMA mapping. */ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr, - size_t size, int direction) + size_t size, enum dma_data_direction direction) { unsigned long iommu_page; int npages; @@ -299,7 +302,8 @@ * Wrapper for pci_unmap_single working with scatterlists. */ static void -gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) +gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) { struct scatterlist *s; int i; @@ -313,7 +317,7 @@ /* Fallback for dma_map_sg in case of overflow */ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, - int nents, int dir) + int nents, enum dma_data_direction dir) { struct scatterlist *s; int i; @@ -401,7 +405,8 @@ * Merge chunks that have page aligned sizes into a continuous mapping. */ static int -gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) +gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) { struct scatterlist *s, *ps, *start_sg, *sgmap; int need = 0, nextneed, i, out, start; diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -27,7 +27,7 @@ static dma_addr_t nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, - int direction) + enum dma_data_direction direction) { dma_addr_t bus = paddr; WARN_ON(size == 0); @@ -54,7 +54,7 @@ * the same here. */ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction) + int nents, enum dma_data_direction direction) { struct scatterlist *s; int i; diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -40,7 +40,7 @@ static dma_addr_t swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, - int direction) + enum dma_data_direction direction) { return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); } diff --git a/arch/x86/kernel/tce_64.c b/arch/x86/kernel/tce_64.c --- a/arch/x86/kernel/tce_64.c +++ b/arch/x86/kernel/tce_64.c @@ -46,7 +46,8 @@ } void tce_build(struct iommu_table *tbl, unsigned long index, - unsigned int npages, unsigned long uaddr, int direction) + unsigned int npages, unsigned long uaddr, + enum dma_data_direction direction) { u64* tp; u64 t; diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1819,7 +1819,8 @@ } static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, - size_t size, int dir, u64 dma_mask) + size_t size, + enum dma_data_direction dir, u64 dma_mask) { struct pci_dev *pdev = to_pci_dev(hwdev); struct dmar_domain *domain; @@ -1881,7 +1882,7 @@ } dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { return __intel_map_single(hwdev, paddr, size, dir, to_pci_dev(hwdev)->dma_mask); @@ -1946,7 +1947,7 @@ } void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, - int dir) + enum dma_data_direction dir) { struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; @@ -2026,7 +2027,7 @@ #define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg))) void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { int i; struct pci_dev *pdev = to_pci_dev(hwdev); @@ -2066,7 +2067,7 @@ } static int intel_nontranslate_map_sg(struct device *hddev, - struct scatterlist *sglist, int nelems, int dir) + struct scatterlist *sglist, int nelems, enum dma_data_direction dir) { int i; struct scatterlist *sg; @@ -2080,7 +2081,7 @@ } int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems, - int dir) + enum dma_data_direction dir) { void *addr; int i; diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -355,9 +355,13 @@ extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t); -extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, int); -extern void intel_unmap_single(struct device *, dma_addr_t, size_t, int); -extern int intel_map_sg(struct device *, struct scatterlist *, int, int); -extern void intel_unmap_sg(struct device *, struct scatterlist *, int, int); +extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, + enum dma_data_direction); +extern void intel_unmap_single(struct device *, dma_addr_t, size_t, + enum dma_data_direction); +extern int intel_map_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction); +extern void intel_unmap_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction); #endif diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -42,60 +42,65 @@ void *vaddr, dma_addr_t dma_handle); extern dma_addr_t -swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir); +swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, + enum dma_data_direction dir); extern void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern dma_addr_t swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, - int dir, struct dma_attrs *attrs); + enum dma_data_direction dir, + struct dma_attrs *attrs); extern void swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir, struct dma_attrs *attrs); + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs); extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, - int direction); + enum dma_data_direction direction); extern int swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir, struct dma_attrs *attrs); + enum dma_data_direction dir, struct dma_attrs *attrs); extern void swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, - int nelems, int dir, struct dma_attrs *attrs); + int nelems, enum dma_data_direction dir, + struct dma_attrs *attrs); extern void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir); + int nelems, enum dma_data_direction dir); extern void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir); + size_t size, enum dma_data_direction dir); extern void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir); + int nelems, enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - unsigned long offset, size_t size, int dir); + unsigned long offset, size_t size, + enum dma_data_direction dir); extern void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, - int dir); + enum dma_data_direction dir); extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); diff --git a/lib/swiotlb.c b/lib/swiotlb.c --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -373,7 +373,8 @@ * Allocates bounce buffer and returns its kernel virtual address. */ static void * -map_single(struct device *hwdev, phys_addr_t phys, size_t size, int dir) +map_single(struct device *hwdev, phys_addr_t phys, size_t size, + enum dma_data_direction dir) { unsigned long flags; char *dma_addr; @@ -479,7 +480,8 @@ * dma_addr is the kernel virtual address of the bounce buffer to unmap. */ static void -unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) +unmap_single(struct device *hwdev, char *dma_addr, size_t size, + enum dma_data_direction dir) { unsigned long flags; int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; @@ -520,7 +522,7 @@ static void sync_single(struct device *hwdev, char *dma_addr, size_t size, - int dir, int target) + enum dma_data_direction dir, int target) { int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; phys_addr_t phys = io_tlb_orig_addr[index]; @@ -610,7 +612,8 @@ } static void -swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) +swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir, + int do_panic) { /* * Ran out of IOMMU space for this operation. This is very bad. @@ -639,7 +642,7 @@ */ dma_addr_t swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { dma_addr_t dev_addr = swiotlb_virt_to_bus(hwdev, ptr); void *map; @@ -676,7 +679,8 @@ EXPORT_SYMBOL(swiotlb_map_single_attrs); dma_addr_t -swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) +swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, + enum dma_data_direction dir) { return swiotlb_map_single_attrs(hwdev, ptr, size, dir, NULL); } @@ -691,7 +695,8 @@ */ void swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir, struct dma_attrs *attrs) + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs) { char *dma_addr = swiotlb_bus_to_virt(dev_addr); @@ -705,7 +710,7 @@ void swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, - int dir) + enum dma_data_direction dir) { return swiotlb_unmap_single_attrs(hwdev, dev_addr, size, dir, NULL); } @@ -721,7 +726,7 @@ */ static void swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir, int target) + size_t size, enum dma_data_direction dir, int target) { char *dma_addr = swiotlb_bus_to_virt(dev_addr); @@ -734,14 +739,14 @@ void swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU); } void swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, - size_t size, int dir) + size_t size, enum dma_data_direction dir) { swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE); } @@ -752,7 +757,7 @@ static void swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, unsigned long offset, size_t size, - int dir, int target) + enum dma_data_direction dir, int target) { char *dma_addr = swiotlb_bus_to_virt(dev_addr) + offset; @@ -765,7 +770,8 @@ void swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, - unsigned long offset, size_t size, int dir) + unsigned long offset, size_t size, + enum dma_data_direction dir) { swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, SYNC_FOR_CPU); @@ -773,14 +779,15 @@ void swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, - unsigned long offset, size_t size, int dir) + unsigned long offset, size_t size, + enum dma_data_direction dir) { swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir, SYNC_FOR_DEVICE); } -void swiotlb_unmap_sg_attrs(struct device *, struct scatterlist *, int, int, - struct dma_attrs *); +void swiotlb_unmap_sg_attrs(struct device *, struct scatterlist *, int, + enum dma_data_direction, struct dma_attrs *); /* * Map a set of buffers described by scatterlist in streaming mode for DMA. * This is the scatter-gather version of the above swiotlb_map_single @@ -799,7 +806,7 @@ */ int swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir, struct dma_attrs *attrs) + enum dma_data_direction dir, struct dma_attrs *attrs) { struct scatterlist *sg; int i; @@ -834,7 +841,7 @@ int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir) + enum dma_data_direction dir) { return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL); } @@ -845,7 +852,8 @@ */ void swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, - int nelems, int dir, struct dma_attrs *attrs) + int nelems, enum dma_data_direction dir, + struct dma_attrs *attrs) { struct scatterlist *sg; int i; @@ -864,7 +872,7 @@ void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, - int dir) + enum dma_data_direction dir) { return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL); } @@ -878,7 +886,7 @@ */ static void swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl, - int nelems, int dir, int target) + int nelems, enum dma_data_direction dir, int target) { struct scatterlist *sg; int i; @@ -896,14 +904,14 @@ void swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU); } void swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, - int nelems, int dir) + int nelems, enum dma_data_direction dir) { swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE); } ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (8 preceding siblings ...) 2008-12-22 18:26 ` [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops Jeremy Fitzhardinge @ 2008-12-22 18:43 ` FUJITA Tomonori 2008-12-27 10:48 ` Ingo Molnar 10 siblings, 0 replies; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-22 18:43 UTC (permalink / raw) To: jeremy Cc: mingo, linux-kernel, xen-devel, x86, ian.campbell, beckyb, fujita.tomonori On Mon, 22 Dec 2008 10:26:02 -0800 Jeremy Fitzhardinge <jeremy@goop.org> wrote: > Hi all, > > Here's a work in progress series whcih does a partial revert of the > previous swiotlb changes, and does a partial replacement with Becky > Bruce's series. > > The most important difference is Becky's use of phys_addr_t rather > than page+offset to represent arbitrary pages. This turns out to be > simpler. Great, thanks a lot! But I think that we should just drop the previous patchset completely and start cleanly. > I didn't replicate the map_single_page changes, since I'm not exactly > sure of ppc's requirements here, and it seemed like something that > could be easily added. I think the patch is not necessary. Just exporting map_single should be fine. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge ` (9 preceding siblings ...) 2008-12-22 18:43 ` [PATCH 0 of 9] swiotlb: use phys_addr_t for pages FUJITA Tomonori @ 2008-12-27 10:48 ` Ingo Molnar 2008-12-27 15:06 ` FUJITA Tomonori 2008-12-27 16:44 ` FUJITA Tomonori 10 siblings, 2 replies; 29+ messages in thread From: Ingo Molnar @ 2008-12-27 10:48 UTC (permalink / raw) To: Jeremy Fitzhardinge, Tony Luck Cc: linux-kernel, Xen-devel, the arch/x86 maintainers, Ian Campbell, Becky Bruce, FUJITA Tomonori * Jeremy Fitzhardinge <jeremy@goop.org> wrote: > Hi all, > > Here's a work in progress series whcih does a partial revert of the > previous swiotlb changes, and does a partial replacement with Becky > Bruce's series. > > The most important difference is Becky's use of phys_addr_t rather than > page+offset to represent arbitrary pages. This turns out to be simpler. > > I didn't replicate the map_single_page changes, since I'm not exactly > sure of ppc's requirements here, and it seemed like something that could > be easily added. > > Quick testing showed no problems, but I haven't had the chance to do > anything extensive. > > I've made some small changes to Becky's patches to make them apply, but > I've separated any functional changes into separate patches with > appropriate authorship. looks good to me in principle. Fujita-san, do you have any principal objections against these generalizations? Also, this patch will interact with ia64 materially: Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops So we'll need a bit more confidence in the testing status of this queue, and we probably want to wait until Tony merged the pending .29 ia64 changes, and also get an Ack from Tony for these bits: arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ arch/ia64/hp/common/sba_iommu.c | 12 ++++--- arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ arch/ia64/kernel/machvec.c | 6 ++- arch/ia64/sn/kernel/io_common.c | 3 +- arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- arch/ia64/sn/pci/tioca_provider.c | 3 +- (Tony Cc:-ed) Ingo ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-27 10:48 ` Ingo Molnar @ 2008-12-27 15:06 ` FUJITA Tomonori 2008-12-28 5:01 ` Jeremy Fitzhardinge 2008-12-27 16:44 ` FUJITA Tomonori 1 sibling, 1 reply; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-27 15:06 UTC (permalink / raw) To: mingo Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, fujita.tomonori On Sat, 27 Dec 2008 11:48:23 +0100 Ingo Molnar <mingo@elte.hu> wrote: > > * Jeremy Fitzhardinge <jeremy@goop.org> wrote: > > > Hi all, > > > > Here's a work in progress series whcih does a partial revert of the > > previous swiotlb changes, and does a partial replacement with Becky > > Bruce's series. > > > > The most important difference is Becky's use of phys_addr_t rather than > > page+offset to represent arbitrary pages. This turns out to be simpler. > > > > I didn't replicate the map_single_page changes, since I'm not exactly > > sure of ppc's requirements here, and it seemed like something that could > > be easily added. > > > > Quick testing showed no problems, but I haven't had the chance to do > > anything extensive. > > > > I've made some small changes to Becky's patches to make them apply, but > > I've separated any functional changes into separate patches with > > appropriate authorship. > > looks good to me in principle. Fujita-san, do you have any principal > objections against these generalizations? Well, I asked Jeremy to use Becky's approach so I don't have though this patchset isn't enough for Becky (possibly for Xen too) since Jeremy didn't put Becky's map_single_page changes. These changes are necessary to support map_map_page with highmem. I think that we can do it simpler than his patch. I'll send patches to that in a different way soon. It's not principal objection, but as I said, the patches to revert Jeremy's highmem patches in this patchset like the following are pointless. Commit e58c866b9b74a825771e2024d4a059bd07359d75 Author: Jeremy Fitzhardinge <jeremy@goop.org> Date: Mon Dec 22 10:26:03 2008 -0800 revert "swiotlb: support bouncing of HighMem pages." git commit ef9b189352f2eb78f14e52996f4780a523b04a49 This doesn't explain why we reverted it. The two approaches are different so there is no point to merge these patch in this way. There is no patches in tip/core/iommu except for this swiotlb stuff. The end result is exactly same (I just reordered patches). So there is nothing to worry. You can safely replace tip/core/iommu with this tree. git://git.kernel.org/pub/scm/linux/kernel/git/tomo/linux-2.6-misc.git swiotlb > Also, this patch will interact with ia64 materially: > > Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops > > So we'll need a bit more confidence in the testing status of this queue, > and we probably want to wait until Tony merged the pending .29 ia64 > changes, and also get an Ack from Tony for these bits: > > arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- > arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ > arch/ia64/hp/common/sba_iommu.c | 12 ++++--- > arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- > arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ > arch/ia64/kernel/machvec.c | 6 ++- > arch/ia64/sn/kernel/io_common.c | 3 +- > arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- > arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- > arch/ia64/sn/pci/tioca_provider.c | 3 +- > > (Tony Cc:-ed) > > Ingo > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-27 15:06 ` FUJITA Tomonori @ 2008-12-28 5:01 ` Jeremy Fitzhardinge 2008-12-28 9:50 ` Ingo Molnar 0 siblings, 1 reply; 29+ messages in thread From: Jeremy Fitzhardinge @ 2008-12-28 5:01 UTC (permalink / raw) To: FUJITA Tomonori Cc: mingo, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb FUJITA Tomonori wrote: > Well, I asked Jeremy to use Becky's approach so I don't have though > this patchset isn't enough for Becky (possibly for Xen too) since > Jeremy didn't put Becky's map_single_page changes. These changes are > necessary to support map_map_page with highmem. I think that we can do > it simpler than his patch. I'll send patches to that in a different > way soon. > > It's not principal objection, but as I said, the patches to revert > Jeremy's highmem patches in this patchset like the following are > pointless. > I don't mind either way. I was hoping to go with something that I've actually tested, but I don't see any reason why Becky's patches won't work in principle for Xen. I'm on vacation at the moment, but I can test things out when I get back in a couple of weeks and apply whatever fixes are needed at whatever stage we're at then. J ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 5:01 ` Jeremy Fitzhardinge @ 2008-12-28 9:50 ` Ingo Molnar 0 siblings, 0 replies; 29+ messages in thread From: Ingo Molnar @ 2008-12-28 9:50 UTC (permalink / raw) To: Jeremy Fitzhardinge Cc: FUJITA Tomonori, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb * Jeremy Fitzhardinge <jeremy@goop.org> wrote: > FUJITA Tomonori wrote: >> Well, I asked Jeremy to use Becky's approach so I don't have though >> this patchset isn't enough for Becky (possibly for Xen too) since >> Jeremy didn't put Becky's map_single_page changes. These changes are >> necessary to support map_map_page with highmem. I think that we can do >> it simpler than his patch. I'll send patches to that in a different >> way soon. >> >> It's not principal objection, but as I said, the patches to revert >> Jeremy's highmem patches in this patchset like the following are >> pointless. >> > > I don't mind either way. I was hoping to go with something that I've > actually tested, but I don't see any reason why Becky's patches won't > work in principle for Xen. I'm on vacation at the moment, but I can > test things out when I get back in a couple of weeks and apply whatever > fixes are needed at whatever stage we're at then. yes, obviously we prefer append-only - i kept your patches and added the Becky lineup and Fujita's cleanups on top of that. If they break your Xen swiotlb use it should all be easily bisectable. Ingo ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-27 10:48 ` Ingo Molnar 2008-12-27 15:06 ` FUJITA Tomonori @ 2008-12-27 16:44 ` FUJITA Tomonori 2008-12-27 16:56 ` Ingo Molnar 1 sibling, 1 reply; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-27 16:44 UTC (permalink / raw) To: mingo Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, fujita.tomonori On Sat, 27 Dec 2008 11:48:23 +0100 Ingo Molnar <mingo@elte.hu> wrote: > Also, this patch will interact with ia64 materially: > > Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops > > So we'll need a bit more confidence in the testing status of this queue, > and we probably want to wait until Tony merged the pending .29 ia64 > changes, and also get an Ack from Tony for these bits: > > arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- > arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ > arch/ia64/hp/common/sba_iommu.c | 12 ++++--- > arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- > arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ > arch/ia64/kernel/machvec.c | 6 ++- > arch/ia64/sn/kernel/io_common.c | 3 +- > arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- > arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- > arch/ia64/sn/pci/tioca_provider.c | 3 +- > > (Tony Cc:-ed) BTW, the above patch breaks IA64 build. It's fixable but I think that it would be better to just drop this huge patch and add some cast in powerpc code. the types of SWIOTBL function arguments don't need to mach to DAM_API.txt though it might be nice if so. There are other type mismatches. If we really want to do this cleanups, we should fix up all the mismatches. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-27 16:44 ` FUJITA Tomonori @ 2008-12-27 16:56 ` Ingo Molnar 2008-12-27 17:03 ` FUJITA Tomonori 0 siblings, 1 reply; 29+ messages in thread From: Ingo Molnar @ 2008-12-27 16:56 UTC (permalink / raw) To: FUJITA Tomonori Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > On Sat, 27 Dec 2008 11:48:23 +0100 > Ingo Molnar <mingo@elte.hu> wrote: > > > Also, this patch will interact with ia64 materially: > > > > Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops > > > > So we'll need a bit more confidence in the testing status of this queue, > > and we probably want to wait until Tony merged the pending .29 ia64 > > changes, and also get an Ack from Tony for these bits: > > > > arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- > > arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ > > arch/ia64/hp/common/sba_iommu.c | 12 ++++--- > > arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- > > arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ > > arch/ia64/kernel/machvec.c | 6 ++- > > arch/ia64/sn/kernel/io_common.c | 3 +- > > arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- > > arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- > > arch/ia64/sn/pci/tioca_provider.c | 3 +- > > > > (Tony Cc:-ed) > > BTW, the above patch breaks IA64 build. > > It's fixable but I think that it would be better to just drop this huge > patch and add some cast in powerpc code. the types of SWIOTBL function > arguments don't need to mach to DAM_API.txt though it might be nice if > so. There are other type mismatches. If we really want to do this > cleanups, we should fix up all the mismatches. hm, we shouldnt do ugly typecasts - lets fix all the places. As Jeremy indicated, this is work in progress. Ingo ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-27 16:56 ` Ingo Molnar @ 2008-12-27 17:03 ` FUJITA Tomonori 2008-12-28 5:29 ` FUJITA Tomonori 0 siblings, 1 reply; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-27 17:03 UTC (permalink / raw) To: mingo Cc: fujita.tomonori, jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb On Sat, 27 Dec 2008 17:56:22 +0100 Ingo Molnar <mingo@elte.hu> wrote: > > * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > On Sat, 27 Dec 2008 11:48:23 +0100 > > Ingo Molnar <mingo@elte.hu> wrote: > > > > > Also, this patch will interact with ia64 materially: > > > > > > Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops > > > > > > So we'll need a bit more confidence in the testing status of this queue, > > > and we probably want to wait until Tony merged the pending .29 ia64 > > > changes, and also get an Ack from Tony for these bits: > > > > > > arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- > > > arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ > > > arch/ia64/hp/common/sba_iommu.c | 12 ++++--- > > > arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- > > > arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ > > > arch/ia64/kernel/machvec.c | 6 ++- > > > arch/ia64/sn/kernel/io_common.c | 3 +- > > > arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- > > > arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- > > > arch/ia64/sn/pci/tioca_provider.c | 3 +- > > > > > > (Tony Cc:-ed) > > > > BTW, the above patch breaks IA64 build. > > > > It's fixable but I think that it would be better to just drop this huge > > patch and add some cast in powerpc code. the types of SWIOTBL function > > arguments don't need to mach to DAM_API.txt though it might be nice if > > so. There are other type mismatches. If we really want to do this > > cleanups, we should fix up all the mismatches. > > hm, we shouldnt do ugly typecasts - lets fix all the places. As Jeremy > indicated, this is work in progress. It's not about this patchset, swiotlb. I'm talking about all the mismatches of dma mapping operations. But it need huge patches (touching lots of the architectures). I'm not sure it is worth doing it. Even if we want, it's not the job that this swiotlb patches does. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-27 17:03 ` FUJITA Tomonori @ 2008-12-28 5:29 ` FUJITA Tomonori 2008-12-28 7:30 ` Christoph Hellwig 2008-12-28 9:37 ` Ingo Molnar 0 siblings, 2 replies; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-28 5:29 UTC (permalink / raw) To: mingo; +Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb On Sun, 28 Dec 2008 02:03:37 +0900 FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > On Sat, 27 Dec 2008 17:56:22 +0100 > Ingo Molnar <mingo@elte.hu> wrote: > > > > > * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > > > On Sat, 27 Dec 2008 11:48:23 +0100 > > > Ingo Molnar <mingo@elte.hu> wrote: > > > > > > > Also, this patch will interact with ia64 materially: > > > > > > > > Subject: [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops > > > > > > > > So we'll need a bit more confidence in the testing status of this queue, > > > > and we probably want to wait until Tony merged the pending .29 ia64 > > > > changes, and also get an Ack from Tony for these bits: > > > > > > > > arch/ia64/dig/dig_vtd_iommu.c | 9 +++-- > > > > arch/ia64/hp/common/hwsw_iommu.c | 22 ++++++++------ > > > > arch/ia64/hp/common/sba_iommu.c | 12 ++++--- > > > > arch/ia64/include/asm/dma-mapping.h | 29 +++++++++--------- > > > > arch/ia64/include/asm/swiotlb.h | 26 ++++++++++------ > > > > arch/ia64/kernel/machvec.c | 6 ++- > > > > arch/ia64/sn/kernel/io_common.c | 3 +- > > > > arch/ia64/sn/pci/pci_dma.c | 21 ++++++++----- > > > > arch/ia64/sn/pci/pcibr/pcibr_dma.c | 3 +- > > > > arch/ia64/sn/pci/tioca_provider.c | 3 +- > > > > > > > > (Tony Cc:-ed) > > > > > > BTW, the above patch breaks IA64 build. > > > > > > It's fixable but I think that it would be better to just drop this huge > > > patch and add some cast in powerpc code. the types of SWIOTBL function > > > arguments don't need to mach to DAM_API.txt though it might be nice if > > > so. There are other type mismatches. If we really want to do this > > > cleanups, we should fix up all the mismatches. > > > > hm, we shouldnt do ugly typecasts - lets fix all the places. As Jeremy > > indicated, this is work in progress. > > It's not about this patchset, swiotlb. I'm talking about all the > mismatches of dma mapping operations. But it need huge patches > (touching lots of the architectures). I'm not sure it is worth doing > it. Even if we want, it's not the job that this swiotlb patches does. If we really want to clean up the dma mapping operations, we should define struct dma_mapping_ops in a generic place (such as include/linux/dma-mapping.h) instead each architecture define the own struct dma_mapping_ops. These dma_mapping_ops structures are very similar but a bit different. That's the root cause of the dma mapping operation ugliness. If we do, X86 and IA64 can share swiotlb and intel VTD code cleanly, X86, IA64, and POWERPC can share swiotlb cleanly too. For example, we can define swiotlb_dma_ops in lib/swiotlb.c and then everyone can share it. Currently, X86 and IA64 define the own swiotlb_dma_ops (and X86 needs swiotlb_map_single_phys hack). It doesn't make sense. If we want to clean up all the dma mapping operation ugliness, the above patch is wrong. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 5:29 ` FUJITA Tomonori @ 2008-12-28 7:30 ` Christoph Hellwig 2008-12-28 9:36 ` FUJITA Tomonori 2008-12-28 21:37 ` Benjamin Herrenschmidt 2008-12-28 9:37 ` Ingo Molnar 1 sibling, 2 replies; 29+ messages in thread From: Christoph Hellwig @ 2008-12-28 7:30 UTC (permalink / raw) To: FUJITA Tomonori Cc: mingo, jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb On Sun, Dec 28, 2008 at 02:29:54PM +0900, FUJITA Tomonori wrote: > If we really want to clean up the dma mapping operations, we should > define struct dma_mapping_ops in a generic place (such as > include/linux/dma-mapping.h) instead each architecture define the own > struct dma_mapping_ops. These dma_mapping_ops structures are very > similar but a bit different. That's the root cause of the dma mapping > operation ugliness. Yes, please. For people hacking on different architectures occasionally the current setup with per-arch ops (and sometimes none at all) is pain. > If we do, X86 and IA64 can share swiotlb and intel VTD code cleanly, > X86, IA64, and POWERPC can share swiotlb cleanly too. For example, we > can define swiotlb_dma_ops in lib/swiotlb.c and then everyone can > share it. Currently, X86 and IA64 define the own swiotlb_dma_ops (and > X86 needs swiotlb_map_single_phys hack). It doesn't make sense. Also the calgary iommu is very similar to those used on some pseries machines, but I'd have to look at the code if the interface actually still is similar, or if the PPC firmware adds too much abstractions inbetween. Also the older IA64 altixens have a slightly updated version of the iommu used on MIPS IP27 (and the same as on MIPS IP35 which we'll hopefully support one day) ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 7:30 ` Christoph Hellwig @ 2008-12-28 9:36 ` FUJITA Tomonori 2008-12-28 21:37 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-28 9:36 UTC (permalink / raw) To: hch Cc: fujita.tomonori, mingo, jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb On Sun, 28 Dec 2008 02:30:12 -0500 Christoph Hellwig <hch@infradead.org> wrote: > On Sun, Dec 28, 2008 at 02:29:54PM +0900, FUJITA Tomonori wrote: > > If we really want to clean up the dma mapping operations, we should > > define struct dma_mapping_ops in a generic place (such as > > include/linux/dma-mapping.h) instead each architecture define the own > > struct dma_mapping_ops. These dma_mapping_ops structures are very > > similar but a bit different. That's the root cause of the dma mapping > > operation ugliness. > > Yes, please. For people hacking on different architectures occasionally > the current setup with per-arch ops (and sometimes none at all) is pain. The biggest obstacle is IA64's way to handle multiple dma mapping operations (artistic define magics). I'll take care of the cleanups if Tony lets me change IA64 to handle multiple dma mapping operations as other architectures do (x86 and powerpc). ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 7:30 ` Christoph Hellwig 2008-12-28 9:36 ` FUJITA Tomonori @ 2008-12-28 21:37 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 29+ messages in thread From: Benjamin Herrenschmidt @ 2008-12-28 21:37 UTC (permalink / raw) To: Christoph Hellwig Cc: FUJITA Tomonori, mingo, jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb On Sun, 2008-12-28 at 02:30 -0500, Christoph Hellwig wrote: > Also the calgary iommu is very similar to those used on some pseries > machines, but I'd have to look at the code if the interface actually > still is similar, or if the PPC firmware adds too much abstractions > inbetween. Well, we have basically two backends... in the same file but they are really different and I may split them one of these days. One is "native", used in theory only on POWER4 (and internal bare-metal stuff) and one is purely via hypervisor calls. > Also the older IA64 altixens have a slightly updated version of the > iommu used on MIPS IP27 (and the same as on MIPS IP35 which we'll > hopefully support one day) BTW. On a tangent here, but I do prefer in the long run switching DMA ops mostly away from struct page * + offset and toward phys_addr_t (even if we won't change the SG variant). The reason is sneaky :-) But there are cases, especially in embedded space, where it would be nice to be able to DMA to/from MMIO areas or in general areas not covered by struct pages. Currently doing so requires hacking all the way through the stack, it might be possible to do it more nicely with arch custom DMA ops provided we can pass around addresses an not struct page*. Cheers, Ben. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 5:29 ` FUJITA Tomonori 2008-12-28 7:30 ` Christoph Hellwig @ 2008-12-28 9:37 ` Ingo Molnar 2008-12-28 10:02 ` FUJITA Tomonori 1 sibling, 1 reply; 29+ messages in thread From: Ingo Molnar @ 2008-12-28 9:37 UTC (permalink / raw) To: FUJITA Tomonori Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, Joerg Roedel * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > If we really want to clean up the dma mapping operations, we should > define struct dma_mapping_ops in a generic place (such as > include/linux/dma-mapping.h) instead each architecture define the own > struct dma_mapping_ops. These dma_mapping_ops structures are very > similar but a bit different. That's the root cause of the dma mapping > operation ugliness. > > If we do, X86 and IA64 can share swiotlb and intel VTD code cleanly, > X86, IA64, and POWERPC can share swiotlb cleanly too. For example, we > can define swiotlb_dma_ops in lib/swiotlb.c and then everyone can share > it. Currently, X86 and IA64 define the own swiotlb_dma_ops (and X86 > needs swiotlb_map_single_phys hack). It doesn't make sense. Sure. Note that we went through this process (of unifying dma_mapping_ops) recently on x86 recently - 32-bit and 64-bit x86 had such differences. Note that the main complication wasnt even the small variations in signatures, but the different _semantics_: one dma_mapping_ops implementation passed in kernel-virtual addresses, the other physical addresses. Unifying that was invasive and non-trivial, and it can break stuff not at the build level but at the runtime level. We can expect similar complications when done over 20 architectures as well. But yes, it's all desired. Obviously extending swiotlb to highmem and using it on xen and powerpc is an essential first step in the direction of generalizing all this code. Ingo ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 9:37 ` Ingo Molnar @ 2008-12-28 10:02 ` FUJITA Tomonori 2008-12-28 10:34 ` Ingo Molnar 0 siblings, 1 reply; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-28 10:02 UTC (permalink / raw) To: mingo Cc: fujita.tomonori, jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, joerg.roedel On Sun, 28 Dec 2008 10:37:51 +0100 Ingo Molnar <mingo@elte.hu> wrote: > > * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > If we really want to clean up the dma mapping operations, we should > > define struct dma_mapping_ops in a generic place (such as > > include/linux/dma-mapping.h) instead each architecture define the own > > struct dma_mapping_ops. These dma_mapping_ops structures are very > > similar but a bit different. That's the root cause of the dma mapping > > operation ugliness. > > > > If we do, X86 and IA64 can share swiotlb and intel VTD code cleanly, > > X86, IA64, and POWERPC can share swiotlb cleanly too. For example, we > > can define swiotlb_dma_ops in lib/swiotlb.c and then everyone can share > > it. Currently, X86 and IA64 define the own swiotlb_dma_ops (and X86 > > needs swiotlb_map_single_phys hack). It doesn't make sense. > > Sure. > > Note that we went through this process (of unifying dma_mapping_ops) > recently on x86 recently - 32-bit and 64-bit x86 had such differences. Not really. x86_32 did not use the dma_ops scheme. > Note that the main complication wasnt even the small variations in > signatures, but the different _semantics_: one dma_mapping_ops > implementation passed in kernel-virtual addresses, the other physical > addresses. Unifying that was invasive and non-trivial, and it can break I guess that you are talking about the dma_map_single difference between x86_32 and x86_64. As far as I know, Only x64_64 uses physical address with dma_map_single. > stuff not at the build level but at the runtime level. We can expect > similar complications when done over 20 architectures as well. We don't need to touch 20 architectures. We are talking about unifying dma_mapping_ops. Only architectures that need to handle multiple dma mapping operations use the dma_mapping_ops scheme; X86, IA64, POWERPC, SPARC, and PARISC. Unifying X86, IA64 and POWERPC is a must since they actually share dma_mapping_ops. > But yes, it's all desired. Obviously extending swiotlb to highmem and > using it on xen and powerpc is an essential first step in the direction of > generalizing all this code. No, it's not about swiotlb highmem patchset. Due to this problem, IA64 and X86_64 share swiotlb in a very hacky way. We added more hacky code due to this problem again when we added VT-d support to IA64. This problem has been for long time. We added ugly hacks again and again instead of fixing the root cause. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 10:02 ` FUJITA Tomonori @ 2008-12-28 10:34 ` Ingo Molnar 2008-12-28 11:00 ` FUJITA Tomonori 0 siblings, 1 reply; 29+ messages in thread From: Ingo Molnar @ 2008-12-28 10:34 UTC (permalink / raw) To: FUJITA Tomonori Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, joerg.roedel * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > Note that the main complication wasnt even the small variations in > > signatures, but the different _semantics_: one dma_mapping_ops > > implementation passed in kernel-virtual addresses, the other physical > > addresses. Unifying that was invasive and non-trivial, and it can > > break > > I guess that you are talking about the dma_map_single difference between > x86_32 and x86_64. As far as I know, Only x64_64 uses physical address > with dma_map_single. yes - dma_map_single() has this signature: static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, int direction) on x86 dma_mapping_ops.map_single has this signature: dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, size_t size, int direction); ia64 and powerpc uses kernel-virt addresses for map_single(). So there's material semantic differences between the dma_mapping_ops implementations. > > stuff not at the build level but at the runtime level. We can expect > > similar complications when done over 20 architectures as well. > > We don't need to touch 20 architectures. We are talking about unifying > dma_mapping_ops. Only architectures that need to handle multiple dma > mapping operations use the dma_mapping_ops scheme; X86, IA64, POWERPC, > SPARC, and PARISC. Unifying X86, IA64 and POWERPC is a must since they > actually share dma_mapping_ops. if it's just dma_mapping_ops - then it's those 3 architectures. But there's no reason why the various DMA bouncing implementations in other architectures couldnt use the common code - for example couldnt arch/arm/common/dmabounce.c use the swiotlb too? > > But yes, it's all desired. Obviously extending swiotlb to highmem and > > using it on xen and powerpc is an essential first step in the > > direction of generalizing all this code. > > No, it's not about swiotlb highmem patchset. > > Due to this problem, IA64 and X86_64 share swiotlb in a very hacky way. > We added more hacky code due to this problem again when we added VT-d > support to IA64. > > This problem has been for long time. We added ugly hacks again and again > instead of fixing the root cause. well the swiotlb highmem patches are what enable xen (and now powerpc too) to make full use of the swiotlb dma bouncing facilities. And that gives a common platform for unifying all the rest of the lowlevel DMA mapping APIs as well. Without that, the swiotlb code is limited, life is going on in separate islands, with everyone doing their own private variations and hacks. We would still probably be nowhere with this had Jeremy not sent the highmem patches. Ingo ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 10:34 ` Ingo Molnar @ 2008-12-28 11:00 ` FUJITA Tomonori 2008-12-28 11:56 ` Ingo Molnar 0 siblings, 1 reply; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-28 11:00 UTC (permalink / raw) To: mingo Cc: fujita.tomonori, jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, joerg.roedel On Sun, 28 Dec 2008 11:34:19 +0100 Ingo Molnar <mingo@elte.hu> wrote: > > * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > > Note that the main complication wasnt even the small variations in > > > signatures, but the different _semantics_: one dma_mapping_ops > > > implementation passed in kernel-virtual addresses, the other physical > > > addresses. Unifying that was invasive and non-trivial, and it can > > > break > > > > I guess that you are talking about the dma_map_single difference between > > x86_32 and x86_64. As far as I know, Only x64_64 uses physical address > > with dma_map_single. > > yes - dma_map_single() has this signature: > > static inline dma_addr_t > dma_map_single(struct device *hwdev, void *ptr, size_t size, int direction) > > on x86 dma_mapping_ops.map_single has this signature: > > dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, > size_t size, int direction); > > ia64 and powerpc uses kernel-virt addresses for map_single(). So there's > material semantic differences between the dma_mapping_ops implementations. I know. And as I wrote, as far as I know, only x86 use physical addresses with map_single. I think except for x86, all other archs use cpu addresses because we define dma_map_single() in the following way: dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, enum dma_data_direction direction) > > > stuff not at the build level but at the runtime level. We can expect > > > similar complications when done over 20 architectures as well. > > > > We don't need to touch 20 architectures. We are talking about unifying > > dma_mapping_ops. Only architectures that need to handle multiple dma > > mapping operations use the dma_mapping_ops scheme; X86, IA64, POWERPC, > > SPARC, and PARISC. Unifying X86, IA64 and POWERPC is a must since they > > actually share dma_mapping_ops. > > if it's just dma_mapping_ops - then it's those 3 architectures. But Well, there are 5 architectures at least, as I wrote. > there's no reason why the various DMA bouncing implementations in other > architectures couldnt use the common code - for example couldnt > arch/arm/common/dmabounce.c use the swiotlb too? Well, it's a different issue. I and hch are talking about dma_mapping_ops unification. You brought up a different topic, DMA bouncing implementations unification. DMA bouncing implementations unification is a very nice cleanup. But it's not related with Becky's patch to break IA64 build at all. > > > But yes, it's all desired. Obviously extending swiotlb to highmem and > > > using it on xen and powerpc is an essential first step in the > > > direction of generalizing all this code. > > > > No, it's not about swiotlb highmem patchset. > > > > Due to this problem, IA64 and X86_64 share swiotlb in a very hacky way. > > We added more hacky code due to this problem again when we added VT-d > > support to IA64. > > > > This problem has been for long time. We added ugly hacks again and again > > instead of fixing the root cause. > > well the swiotlb highmem patches are what enable xen (and now powerpc too) > to make full use of the swiotlb dma bouncing facilities. And that gives a > common platform for unifying all the rest of the lowlevel DMA mapping APIs > as well. > > Without that, the swiotlb code is limited, life is going on in separate > islands, with everyone doing their own private variations and hacks. We > would still probably be nowhere with this had Jeremy not sent the highmem > patches. Again, you are talking about a different issue, which is not related with Becky's patch to break IA64 build. As I wrote, Becky's patch is a workaround for the problem that has been for long time. It's not just about swiotlb. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 11:00 ` FUJITA Tomonori @ 2008-12-28 11:56 ` Ingo Molnar 2008-12-28 12:34 ` FUJITA Tomonori 0 siblings, 1 reply; 29+ messages in thread From: Ingo Molnar @ 2008-12-28 11:56 UTC (permalink / raw) To: FUJITA Tomonori Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, joerg.roedel * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > You brought up a different topic, DMA bouncing implementations > unification. DMA bouncing implementations unification is a very nice > cleanup. But it's not related with Becky's patch to break IA64 build at > all. All i'm saying is that obviously neither Jeremy's nor Becky's patches were created in a vacuum, and had it not been for the need and desire to extend swiotlb we'd not have seen Becky's 9/9 cleanup patch either. Ingo ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 11:56 ` Ingo Molnar @ 2008-12-28 12:34 ` FUJITA Tomonori 2008-12-28 12:49 ` Ingo Molnar 0 siblings, 1 reply; 29+ messages in thread From: FUJITA Tomonori @ 2008-12-28 12:34 UTC (permalink / raw) To: mingo Cc: fujita.tomonori, jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, joerg.roedel On Sun, 28 Dec 2008 12:56:21 +0100 Ingo Molnar <mingo@elte.hu> wrote: > > * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > > > You brought up a different topic, DMA bouncing implementations > > unification. DMA bouncing implementations unification is a very nice > > cleanup. But it's not related with Becky's patch to break IA64 build at > > all. > > All i'm saying is that obviously neither Jeremy's nor Becky's patches were > created in a vacuum, and had it not been for the need and desire to extend > swiotlb we'd not have seen Becky's 9/9 cleanup patch either. As I wrote, Becky's 9/9 cleanup path is not about swiotlb highmem extention. We had known about the need to clean up the dma mapping operation ugliness. But we has ignored it and added workarounds again and again. We haven't seen something like his 9/9 because we added workarounds in architecture-specific code. Anyway, his 9/9 patch is wrong if we want to fix the root cause. If we don't fix the root cause, the lots of changes of his 9/9 patch don't make sense. Probably, it would better to add some workarounds in architecture-specific code (POWERPC in this case) as we have done in the past. Ok, I'll try to fix the root cause. We need lots of changes to IA64 especially. Hopefully, I can get Tony's ACK on these changes. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 0 of 9] swiotlb: use phys_addr_t for pages 2008-12-28 12:34 ` FUJITA Tomonori @ 2008-12-28 12:49 ` Ingo Molnar 0 siblings, 0 replies; 29+ messages in thread From: Ingo Molnar @ 2008-12-28 12:49 UTC (permalink / raw) To: FUJITA Tomonori Cc: jeremy, tony.luck, linux-kernel, xen-devel, x86, ian.campbell, beckyb, joerg.roedel * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote: > Ok, I'll try to fix the root cause. We need lots of changes to IA64 > especially. Hopefully, I can get Tony's ACK on these changes. great - let me know if you need testing help on the x86 side as well. I.e. we can test some preliminary patch series from you as well, without committing it to anything stable (i.e. keeping open the ability to rebase/redo it) - while waiting for Tony's ACK. Ingo ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2008-12-28 21:44 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-12-22 18:26 [PATCH 0 of 9] swiotlb: use phys_addr_t for pages Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 1 of 9] revert "swiotlb: support bouncing of HighMem pages." Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 2 of 9] revert "swiotlb: factor out copy to/from device." Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 3 of 9] swiotlb: add hwdev to swiotlb_phys_to_bus Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 4 of 9] swiotlb: Drop SG_ENT_VIRT_ADDRESS macro Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 5 of 9] swiotlb: Rename SG_ENT_PHYS_ADDRESS to SG_ENT_BUS_ADDRESS Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 6 of 9] swiotlb: Store phys address in io_tlb_orig_addr array Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 7 of 9] swiotlb: Add support for systems with highmem Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 8 of 9] swiotlb: cleanups to swiotlb_bounce() Jeremy Fitzhardinge 2008-12-22 18:26 ` [PATCH 9 of 9] ia64/x86/swiotlb: use enum dma_data_direciton in dma_ops Jeremy Fitzhardinge 2008-12-22 18:43 ` [PATCH 0 of 9] swiotlb: use phys_addr_t for pages FUJITA Tomonori 2008-12-27 10:48 ` Ingo Molnar 2008-12-27 15:06 ` FUJITA Tomonori 2008-12-28 5:01 ` Jeremy Fitzhardinge 2008-12-28 9:50 ` Ingo Molnar 2008-12-27 16:44 ` FUJITA Tomonori 2008-12-27 16:56 ` Ingo Molnar 2008-12-27 17:03 ` FUJITA Tomonori 2008-12-28 5:29 ` FUJITA Tomonori 2008-12-28 7:30 ` Christoph Hellwig 2008-12-28 9:36 ` FUJITA Tomonori 2008-12-28 21:37 ` Benjamin Herrenschmidt 2008-12-28 9:37 ` Ingo Molnar 2008-12-28 10:02 ` FUJITA Tomonori 2008-12-28 10:34 ` Ingo Molnar 2008-12-28 11:00 ` FUJITA Tomonori 2008-12-28 11:56 ` Ingo Molnar 2008-12-28 12:34 ` FUJITA Tomonori 2008-12-28 12:49 ` Ingo Molnar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox