LKML Archive on lore.kernel.org help / color / mirror / Atom feed
* [PATCH -mm 0/4] fix iommu segment boundary problems (alpha) @ 2008-02-23 6:13 FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 1/4] alpha: convert IOMMU to use ALIGN() FUJITA Tomonori 0 siblings, 1 reply; 5+ messages in thread From: FUJITA Tomonori @ 2008-02-23 6:13 UTC (permalink / raw) To: linux-kernel; +Cc: tomof, Richard Henderson, Ivan Kokshaysky, Andrew Morton This patchset is another sequel to my patchset to fix iommu segment boundary problems, IOMMUs allocate memory areas without considering a low level driver's segment boundary limits: http://www.mail-archive.com/linux-scsi@vger.kernel.org/msg11919.html This patchset fixes the Alpha IOMMU code. There are four patches in this patchset. The first two patches are preparation for the third patch, which fixes the IOMMU segment boundary problem. The fourth patch just a cleanup, which removes an unused code. This is against 2.6.25-rc2-mm1. ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH -mm 1/4] alpha: convert IOMMU to use ALIGN() 2008-02-23 6:13 [PATCH -mm 0/4] fix iommu segment boundary problems (alpha) FUJITA Tomonori @ 2008-02-23 6:13 ` FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 2/4] alpha: IOMMU had better access to the free space bitmap at only one place FUJITA Tomonori 0 siblings, 1 reply; 5+ messages in thread From: FUJITA Tomonori @ 2008-02-23 6:13 UTC (permalink / raw) To: linux-kernel Cc: tomof, FUJITA Tomonori, Richard Henderson, Ivan Kokshaysky, Andrew Morton This patch is preparation for modifications to fix the IOMMU segment boundary problem. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Andrew Morton <akpm@linux-foundation.org> --- arch/alpha/kernel/pci_iommu.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 26d3789..bbf9990 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -136,11 +136,11 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) /* Search forward for the first mask-aligned sequence of N free ptes */ ptes = arena->ptes; nent = arena->size >> PAGE_SHIFT; - p = (arena->next_entry + mask) & ~mask; + p = ALIGN(arena->next_entry, mask + 1); i = 0; while (i < n && p+i < nent) { if (ptes[p+i]) - p = (p + i + 1 + mask) & ~mask, i = 0; + p = ALIGN(p + i + 1, mask + 1), i = 0; else i = i + 1; } @@ -153,7 +153,7 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) p = 0, i = 0; while (i < n && p+i < nent) { if (ptes[p+i]) - p = (p + i + 1 + mask) & ~mask, i = 0; + p = ALIGN(p + i + 1, mask + 1), i = 0; else i = i + 1; } -- 1.5.3.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH -mm 2/4] alpha: IOMMU had better access to the free space bitmap at only one place 2008-02-23 6:13 ` [PATCH -mm 1/4] alpha: convert IOMMU to use ALIGN() FUJITA Tomonori @ 2008-02-23 6:13 ` FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 3/4] alpha: make IOMMU respect the segment boundary limits FUJITA Tomonori 0 siblings, 1 reply; 5+ messages in thread From: FUJITA Tomonori @ 2008-02-23 6:13 UTC (permalink / raw) To: linux-kernel Cc: tomof, FUJITA Tomonori, Richard Henderson, Ivan Kokshaysky, Andrew Morton iommu_arena_find_pages duplicates the code to access to the bitmap for free space management. This patch convert the IOMMU code to have only one place to access the bitmap, in the popular way that other IOMMUs (e.g. POWER and SPARC) do. This patch is preparation for modifications to fix the IOMMU segment boundary problem. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Andrew Morton <akpm@linux-foundation.org> --- arch/alpha/kernel/pci_iommu.c | 28 +++++++++++++++------------- 1 files changed, 15 insertions(+), 13 deletions(-) diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index bbf9990..e54f829 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -132,12 +132,15 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) { unsigned long *ptes; long i, p, nent; + int pass = 0; /* Search forward for the first mask-aligned sequence of N free ptes */ ptes = arena->ptes; nent = arena->size >> PAGE_SHIFT; p = ALIGN(arena->next_entry, mask + 1); i = 0; + +again: while (i < n && p+i < nent) { if (ptes[p+i]) p = ALIGN(p + i + 1, mask + 1), i = 0; @@ -146,19 +149,18 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) } if (i < n) { - /* Reached the end. Flush the TLB and restart the - search from the beginning. */ - alpha_mv.mv_pci_tbi(arena->hose, 0, -1); - - p = 0, i = 0; - while (i < n && p+i < nent) { - if (ptes[p+i]) - p = ALIGN(p + i + 1, mask + 1), i = 0; - else - i = i + 1; - } - - if (i < n) + if (pass < 1) { + /* + * Reached the end. Flush the TLB and restart + * the search from the beginning. + */ + alpha_mv.mv_pci_tbi(arena->hose, 0, -1); + + pass++; + p = 0; + i = 0; + goto again; + } else return -1; } -- 1.5.3.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH -mm 3/4] alpha: make IOMMU respect the segment boundary limits 2008-02-23 6:13 ` [PATCH -mm 2/4] alpha: IOMMU had better access to the free space bitmap at only one place FUJITA Tomonori @ 2008-02-23 6:13 ` FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 4/4] alpha: remove unused DEBUG_FORCEDAC define in IOMMU FUJITA Tomonori 0 siblings, 1 reply; 5+ messages in thread From: FUJITA Tomonori @ 2008-02-23 6:13 UTC (permalink / raw) To: linux-kernel Cc: tomof, FUJITA Tomonori, Richard Henderson, Ivan Kokshaysky, Andrew Morton This patch makes the IOMMU code not allocate a memory area spanning LLD's segment boundary. is_span_boundary() judges whether a memory area spans LLD's segment boundary. If iommu_arena_find_pages() finds such a area, it tries to find the next available memory area. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Andrew Morton <akpm@linux-foundation.org> --- arch/alpha/kernel/pci_iommu.c | 40 ++++++++++++++++++++++++++++++++++------ 1 files changed, 34 insertions(+), 6 deletions(-) diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index e54f829..54540c3 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -126,13 +126,34 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base, return iommu_arena_new_node(0, hose, base, window_size, align); } +static inline int is_span_boundary(unsigned int index, unsigned int nr, + unsigned long shift, + unsigned long boundary_size) +{ + shift = (shift + index) & (boundary_size - 1); + return shift + nr > boundary_size; +} + /* Must be called with the arena lock held */ static long -iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) +iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena, + long n, long mask) { unsigned long *ptes; long i, p, nent; int pass = 0; + unsigned long base; + unsigned long boundary_size; + + BUG_ON(arena->dma_base & ~PAGE_MASK); + base = arena->dma_base >> PAGE_SHIFT; + if (dev) + boundary_size = ALIGN(dma_get_max_seg_size(dev) + 1, PAGE_SIZE) + >> PAGE_SHIFT; + else + boundary_size = ALIGN(1UL << 32, PAGE_SIZE) >> PAGE_SHIFT; + + BUG_ON(!is_power_of_2(boundary_size)); /* Search forward for the first mask-aligned sequence of N free ptes */ ptes = arena->ptes; @@ -142,6 +163,11 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) again: while (i < n && p+i < nent) { + if (!i && is_span_boundary(p, n, base, boundary_size)) { + p = ALIGN(p + 1, mask + 1); + goto again; + } + if (ptes[p+i]) p = ALIGN(p + i + 1, mask + 1), i = 0; else @@ -170,7 +196,8 @@ again: } static long -iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align) +iommu_arena_alloc(struct device *dev, struct pci_iommu_arena *arena, long n, + unsigned int align) { unsigned long flags; unsigned long *ptes; @@ -181,7 +208,7 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align) /* Search for N empty ptes */ ptes = arena->ptes; mask = max(align, arena->align_entry) - 1; - p = iommu_arena_find_pages(arena, n, mask); + p = iommu_arena_find_pages(dev, arena, n, mask); if (p < 0) { spin_unlock_irqrestore(&arena->lock, flags); return -1; @@ -231,6 +258,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, unsigned long paddr; dma_addr_t ret; unsigned int align = 0; + struct device *dev = pdev ? &pdev->dev : NULL; paddr = __pa(cpu_addr); @@ -278,7 +306,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, /* Force allocation to 64KB boundary for ISA bridges. */ if (pdev && pdev == isa_bridge) align = 8; - dma_ofs = iommu_arena_alloc(arena, npages, align); + dma_ofs = iommu_arena_alloc(dev, arena, npages, align); if (dma_ofs < 0) { printk(KERN_WARNING "pci_map_single failed: " "could not allocate dma page tables\n"); @@ -565,7 +593,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, paddr &= ~PAGE_MASK; npages = calc_npages(paddr + size); - dma_ofs = iommu_arena_alloc(arena, npages, 0); + dma_ofs = iommu_arena_alloc(dev, arena, npages, 0); if (dma_ofs < 0) { /* If we attempted a direct map above but failed, die. */ if (leader->dma_address == 0) @@ -832,7 +860,7 @@ iommu_reserve(struct pci_iommu_arena *arena, long pg_count, long align_mask) /* Search for N empty ptes. */ ptes = arena->ptes; - p = iommu_arena_find_pages(arena, pg_count, align_mask); + p = iommu_arena_find_pages(NULL, arena, pg_count, align_mask); if (p < 0) { spin_unlock_irqrestore(&arena->lock, flags); return -1; -- 1.5.3.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH -mm 4/4] alpha: remove unused DEBUG_FORCEDAC define in IOMMU 2008-02-23 6:13 ` [PATCH -mm 3/4] alpha: make IOMMU respect the segment boundary limits FUJITA Tomonori @ 2008-02-23 6:13 ` FUJITA Tomonori 0 siblings, 0 replies; 5+ messages in thread From: FUJITA Tomonori @ 2008-02-23 6:13 UTC (permalink / raw) To: linux-kernel Cc: tomof, FUJITA Tomonori, Richard Henderson, Ivan Kokshaysky, Andrew Morton This just removes unused DEBUG_FORCEDAC define in the IOMMU code. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Andrew Morton <akpm@linux-foundation.org> --- arch/alpha/kernel/pci_iommu.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 54540c3..be6fa10 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -31,7 +31,6 @@ #endif #define DEBUG_NODIRECT 0 -#define DEBUG_FORCEDAC 0 #define ISA_DMA_MASK 0x00ffffff -- 1.5.3.4 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-02-23 6:17 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-02-23 6:13 [PATCH -mm 0/4] fix iommu segment boundary problems (alpha) FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 1/4] alpha: convert IOMMU to use ALIGN() FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 2/4] alpha: IOMMU had better access to the free space bitmap at only one place FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 3/4] alpha: make IOMMU respect the segment boundary limits FUJITA Tomonori 2008-02-23 6:13 ` [PATCH -mm 4/4] alpha: remove unused DEBUG_FORCEDAC define in IOMMU FUJITA Tomonori
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).