Re: Questions on Hugetlb for bookE and PHYS_64BIT
On Jun 15, 2012, at 1:11 PM, Scott Wood wrote: On 06/15/2012 09:43 AM, telenn barz wrote: Hi all, CONFIG_PHYS_64BIT enables kernel support for larger than 32-bit physical addresses. Is it this configuration option we have to enable for the support of 36-bit real memory (as are capable the Freescale e500v2 or e500mc cores family) ? Yes. The Hugetlb patch for BookE (https://lists.ozlabs.org/pipermail/linuxppc-dev/2011-June/091315.html) seems to be surbordinated to CONFIG_PHYS_64BIT. Is there any good reason why it is not supported when CONFIG_PHYS_64BIT is disabled ? Because it would be extra work to support that configuration, and nobody's felt enough of a need for it to put in that work. Most of the use-cases we had demanding hugetlb were *also* cases that had large amounts of memory, so this is the model we adopted. Plus, we need some of the code from the 36-bit implementation, including the part that causes the lowest level of the page table to widen to 64 bits; additionally we did not measure much, if any, of a perf hit when enabling PHYS_64BIT. Obviously, it could be made to work without it, although there are real code changes required. But unless you have a case where you have a noticeable performance drop from enabling CONFIG_PHYS_64BIT, it's not worth the effort. -Becky -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix swiotlb ops for ppc64
On Dec 12, 2011, at 10:27 PM, Benjamin Herrenschmidt wrote: On Mon, 2011-12-12 at 21:55 -0600, Becky Bruce wrote: 1) dma_direct_alloc_coherent strips GFP_HIGHMEM out of the flags field when calling the actual allocator and the iotlb version does not. I don't know how much this matters - I did a quick grep and I don't see any users that specify that, but somebody went through the trouble of putting it in there in the first place and without knowing why I wasn't willing to get rid of it. Now, since my patch it looks like someone added a VM_BUG_ON into __get_free_pages() if GFP_HIGHMEM so this would get caught. However, I don't know if we really want to throw a bug there. 2) The iotlb code doesn't deal with the !coherent parts like 8xx. We can work around that by setting up the dma_ops differently for that case instead. Does the rest of it handle them ? I mean swiotlb_map_sg_attrs etc... The non-coherent specialness is in the dma sync stuff and no, I don't think the iotlb stuff deals with that properly. Do you not have a problem with 1)? If not then I think we can look at switching over; 2) was more of a secondary thing. -B ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix swiotlb ops for ppc64
On Dec 7, 2011, at 11:46 PM, Kumar Gala wrote: On Dec 7, 2011, at 9:23 PM, Benjamin Herrenschmidt wrote: On Wed, 2011-12-07 at 11:19 -0600, Kumar Gala wrote: struct dma_map_ops swiotlb_dma_ops = { +#ifdef CONFIG_PPC64 + .alloc_coherent = swiotlb_alloc_coherent, + .free_coherent = swiotlb_free_coherent, +#else .alloc_coherent = dma_direct_alloc_coherent, .free_coherent = dma_direct_free_coherent, +#endif .map_sg = swiotlb_map_sg_attrs, .unmap_sg = swiotlb_unmap_sg_attrs, .dma_supported = swiotlb_dma_supported, Do we really need the ifdef ? What happens if we use swiotlb_alloc_coherent() on ppc32 ? Won't it allocate lowmem, realize that it doesn't need bouncing and be happy ? Cheers, Ben. Becky any comment? I know its been a while, but wondering if you had any reason to not do what Ben's suggesting ? Well, as you say, it's been a while, and but I think: 1) dma_direct_alloc_coherent strips GFP_HIGHMEM out of the flags field when calling the actual allocator and the iotlb version does not. I don't know how much this matters - I did a quick grep and I don't see any users that specify that, but somebody went through the trouble of putting it in there in the first place and without knowing why I wasn't willing to get rid of it. Now, since my patch it looks like someone added a VM_BUG_ON into __get_free_pages() if GFP_HIGHMEM so this would get caught. However, I don't know if we really want to throw a bug there. 2) The iotlb code doesn't deal with the !coherent parts like 8xx. We can work around that by setting up the dma_ops differently for that case instead. -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 04/13] powerpc: Update hugetlb huge_pte_alloc and tablewalk code for FSL BOOKE
On Nov 28, 2011, at 11:25 PM, Benjamin Herrenschmidt wrote: On Mon, 2011-10-10 at 15:50 -0500, Becky Bruce wrote: From: Becky Bruce bec...@kernel.crashing.org This updates the hugetlb page table code to handle 64-bit FSL_BOOKE. The previous 32-bit work counted on the inner levels of the page table collapsing. Seriously, my brain hurts !!! Now you know how I felt when I got the original code from David :) So I've tried to understand that code and so far, what I came up with is this, please reply and let me know if I'm full of crack or what ... - David's code has entire levels branching off into hugepd's which are hugetlb specific page dirs. That requires address space constrainst. Yes. - The hack you do with HUGEPD_PGD_SHIFT defined to PGDIR_SHIFT and HUGEPD_PUD_SHIFT to PUD_SHIFT consists of collasping that back into the normal levels. That exists so Jimi's code for A2 and mine can coexist peacefully without ifdeffing huge blocks because we peel off the page table at different points for a hugepd. In my case, if I have a 4M page, that is handled by having 2 entries at the 2M layer, each of which is a pointer to the same pte stored in a kmem_cache created for that purpose. In the server/A2 case, they peel off at the layer above 4M and have a sub-table kmem_cache that has a bunch of same-size huge page ptes (this is all because of the slice constraint). - I really don't understand what you are doing in __hugepte_alloc(). It seems to me that you are trying to make things still point to some kind of separate hugepd dir with the hugeptes in it and have the page tables point to that but I don't quite get it. In your example below, the alloc code is: 1) allocating a small kmem_cache for the pte 2) filling in 8 entries at the 2M level with the pointers to that pte, with the upper bit munged to indicate huge and bits in the lower region that store the huge page size because it can't be encoded in the book3e pte format - Couldn't we just instead ditch the whole hugepd concept alltogether and simply have the huge ptes in the page table at the right level, using possibly multiple consecutive of them for a single page when needed ? Example: 4K base page size. PMD maps 2M. a 16M page could be representing by having 8 consecutive hugeptes pointing to the same huge page in the PMD directory. We currently have 8 consecutive PMD entries that are pointers to the same kmem_cache that holds the actual PTE. I did this for a few reasons: 1) I was trying to stay as close to what David had done as possible 2) symmetry - in every other case entries at higher levels of the normal page table are pointers to something, and it's easy to identify that something is a pointer to hugepte using David's upper-bit-flipping trick. If we have an actual entry mixed in with the pointers it might be hard to tell that's it's an actual PTE and not a pointer without getting information from somewhere else (i.e. the vma) 3) I was trying to avoid having multiple copies of the actual pte - this way it's easy to do stuff like change the perms on the PTE, since I only have to modify one copy 4) I needed the information laid out for quick TLB miss fault-handling of hugepte tlb misses (see below). I believe we always know when accessing a PTE whether it's going to be huge or not and if it's huge, the page size. IE. All the functions we care about either get the vma (which gets you everything you need) or the size (huge_pte_alloc). An exception is the 32-bit fault hander asm code. It does a walk of the page table to reload the tlb. We need to be able to easily identify that we're walking into a hugepage area so we know to load the tlbcam. Having the pointer there with the munged upper bit that David devised is very convenient for that. Also, the Book3e page table format does not allow us to represent page sizes 32m. So that's encoded in the hugepd instead (and not in the pte). I'm not sure how to get around this without slowing things down. I originally had a slower handler and it turned out to impact performance of several important workloads and my perf guys griped at me. I was actually eventually planning to rewrite the 64b fsl book3e handler to deal with this in asm as well. Large workloads on our systems do a lot of tlbcam entry replacement due to 1) the small size of the tlbcam and 2) the lack of any hardware replacement policy on that array. There are other places where we'd have to modify the code to have the vma available (not that it's hard to do, but it's not floating around everywhere). And there may be other places where this is an issue - I'd have to go dig around a bit to answer that. For the record, I hate the idea of not being able to walk the page table without going elsewhere for information. IMHO I should be able to tell everything I need to load a TLB entry from there without digging up a vma. This should be much
Re: [PATCH 02/13] powerpc: hugetlb: fix huge_ptep_set_access_flags return value
On Nov 28, 2011, at 9:58 PM, Benjamin Herrenschmidt wrote: On Mon, 2011-10-10 at 15:50 -0500, Becky Bruce wrote: diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 8600493..70f9885 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -124,7 +124,18 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty) { +#if defined(CONFIG_PPC_MMU_NOHASH) \ +!(defined(CONFIG_PPC_FSL_BOOK3E) defined(CONFIG_PPC32)) The above conditional makes my brain hurt. Can you change that to instead #ifdef HUGETLB_NEED_PRELOAD ... or something like that, which you then #define in the right mmu-.h header ? Sure. Can I publish this as a followup instead of rebasing? We're trying to stay sync'ed with what's in our BSP and it would be easier for me/Kumar to deal with. Cheers, B Cheers, Ben. +/* + * The return 1 forces a call of update_mmu_cache, which will write a + * TLB entry. Without this, platforms that don't do a write of the TLB + * entry in the TLB miss handler asm will fault ad infinitum. + */ +ptep_set_access_flags(vma, addr, ptep, pte, dirty); +return 1; +#else return ptep_set_access_flags(vma, addr, ptep, pte, dirty); +#endif } static inline pte_t huge_ptep_get(pte_t *ptep) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Define/use HUGETLB_NEED_PRELOAD insead of complicated #if
From: Becky Bruce bec...@kernel.crashing.org Define HUGETLB_NEED_PRELOAD in mmu-book3e.h for CONFIG_PPC64 instead of having a much more complicated #if block. This is easier to read and maintain. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/hugetlb.h|3 +-- arch/powerpc/include/asm/mmu-book3e.h |7 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 863f49d..dfdb95b 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -124,8 +124,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty) { -#if defined(CONFIG_PPC_MMU_NOHASH) \ - !(defined(CONFIG_PPC_FSL_BOOK3E) defined(CONFIG_PPC32)) +#ifdef HUGETLB_NEED_PRELOAD /* * The return 1 forces a call of update_mmu_cache, which will write a * TLB entry. Without this, platforms that don't do a write of the TLB diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index e4d0afc..20d29a5 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h @@ -262,6 +262,13 @@ extern int mmu_vmemmap_psize; #ifdef CONFIG_PPC64 extern unsigned long linear_map_top; + +/* + * 64-bit booke platforms don't load the tlb in the tlb miss handler code. + * HUGETLB_NEED_PRELOAD handles this - it causes huge_ptep_set_access_flags to + * return 1, indicating that the tlb requires preloading. + */ +#define HUGETLB_NEED_PRELOAD #endif #endif /* !__ASSEMBLY__ */ -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 03/13] powerpc: Fix booke hugetlb preload code for PPC_MM_SLICES and 64-bit
On Nov 24, 2011, at 6:43 PM, Benjamin Herrenschmidt wrote: On Mon, 2011-10-10 at 15:50 -0500, Becky Bruce wrote: .../... #ifdef CONFIG_PPC_MM_SLICES -psize = mmu_get_tsize(get_slice_psize(mm, ea)); -tsize = mmu_get_psize(psize); +psize = get_slice_psize(mm, ea); +tsize = mmu_get_tsize(psize); shift = mmu_psize_defs[psize].shift; #else -vma = find_vma(mm, ea); -psize = vma_mmu_pagesize(vma); /* returns actual size in bytes */ -asm (PPC_CNTLZL %0,%1 : =r (lz) : r (psize)); -shift = 31 - lz; -tsize = 21 - lz; +psize = vma_mmu_pagesize(find_vma(mm, ea)); +shift = __ilog2(psize); +tsize = shift - 10; #endif Now, I know it was already there and you are just moving it around in this patch but come on ... find_vma() here ? Really ? And with no result checking nor boundary checking (remember it can return a vma that doesn't enclose the address etc). Now I know in this specific case it -should- be safe but still... Now, the caller is just doing: book3e_hugetlb_preload(vma-vm_mm, address, *ptep); So why not just change the prototype and pass the vma down instead ? There's no reason - I just left the prototype the way it was in the original code, but it makes sense to change it given the changes to the function. Respin coming. -B ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/book3e: Change hugetlb preload to take vma argument
From: Becky Bruce bec...@kernel.crashing.org This avoids an extra find_vma() and is less error-prone. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/hugetlb.h |3 ++- arch/powerpc/mm/hugetlbpage-book3e.c |8 ++-- arch/powerpc/mm/mem.c|2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 555044c..863f49d 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -52,7 +52,8 @@ static inline int is_hugepage_only_range(struct mm_struct *mm, } #endif -void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte); +void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, + pte_t pte); void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr); void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c index 4d6d849..3bc7006 100644 --- a/arch/powerpc/mm/hugetlbpage-book3e.c +++ b/arch/powerpc/mm/hugetlbpage-book3e.c @@ -37,12 +37,14 @@ static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid) return found; } -void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte) +void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, + pte_t pte) { unsigned long mas1, mas2; u64 mas7_3; unsigned long psize, tsize, shift; unsigned long flags; + struct mm_struct *mm; #ifdef CONFIG_PPC_FSL_BOOK3E int index, ncams; @@ -51,12 +53,14 @@ void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte) if (unlikely(is_kernel_addr(ea))) return; + mm = vma-vm_mm; + #ifdef CONFIG_PPC_MM_SLICES psize = get_slice_psize(mm, ea); tsize = mmu_get_tsize(psize); shift = mmu_psize_defs[psize].shift; #else - psize = vma_mmu_pagesize(find_vma(mm, ea)); + psize = vma_mmu_pagesize(vma); shift = __ilog2(psize); tsize = shift - 10; #endif diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 4dbc388..846065c 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -552,6 +552,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, #if (defined(CONFIG_PPC_BOOK3E_64) || defined(CONFIG_PPC_FSL_BOOK3E)) \ defined(CONFIG_HUGETLB_PAGE) if (is_vm_hugetlb_page(vma)) - book3e_hugetlb_preload(vma-vm_mm, address, *ptep); + book3e_hugetlb_preload(vma, address, *ptep); #endif } -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/fsl-booke: Fix settlbcam for 64-bit
From: Becky Bruce bec...@kernel.crashing.org Currently, it does a cntlzd on the size and then subtracts it from 21 this doesn't take into account the varying size of a long. Just use __ilog instead (and subtract the 10 we have to subtract to get to the tsize encoding). Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/mm/fsl_booke_mmu.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index f7802c8..54897c0 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -111,7 +111,7 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, unsigned int tsize, lz; asm (PPC_CNTLZL %0,%1 : =r (lz) : r (size)); - tsize = 21 - lz; + tsize = __ilog2(size) - 10; #ifdef CONFIG_SMP if ((flags _PAGE_NO_CACHE) == 0) -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] powerpc/fsl-booke: Fix settlbcam for 64-bit
From: Becky Bruce bec...@kernel.crashing.org Currently, it does a cntlzd on the size and then subtracts it from 21 this doesn't take into account the varying size of a long. Just use __ilog instead (and subtract the 10 we have to subtract to get to the tsize encoding). Also correct the comment about page sizes supported. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- Sent the wrong version last time; also noticed that the comment is incorrect now that we have 64-bit and added that to the patch. arch/powerpc/mm/fsl_booke_mmu.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index f7802c8..5b8fd3b 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -101,17 +101,17 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) /* * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; - * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus - * that support extended page sizes). Note that while some cpus support a - * page size of 4G, we don't allow its use here. + * in particular size must be a power of 4 between 4k and the max supported by + * an implementation; max may further be limited by what can be represented in + * an unsigned long (for example, 32-bit implementations cannot support a 4GB + * size). */ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, unsigned long size, unsigned long flags, unsigned int pid) { - unsigned int tsize, lz; + unsigned int tsize; - asm (PPC_CNTLZL %0,%1 : =r (lz) : r (size)); - tsize = 21 - lz; + tsize = __ilog2(size) - 10; #ifdef CONFIG_SMP if ((flags _PAGE_NO_CACHE) == 0) -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/13] Hugetlb for 64-bit Freescale Book3E
This series of patches contains mostly cleanup code that allows the enablement of hugetlb for 64-bit Freescale BookE processors. There are also some bits that I dropped from the 32-bit release that are added back, as they are needed by other implementations. Otherwise, it's mostly a bunch of code rearrangement, changes in #include protections, and Kconfig changes. Cheers, Becky arch/powerpc/configs/corenet32_smp_defconfig |9 +-- arch/powerpc/configs/corenet64_smp_defconfig |6 +- arch/powerpc/configs/mpc85xx_defconfig |6 +- arch/powerpc/configs/mpc85xx_smp_defconfig |7 +- arch/powerpc/include/asm/hugetlb.h | 36 ++-- arch/powerpc/include/asm/page_64.h |2 + arch/powerpc/kernel/setup_64.c | 10 ++ arch/powerpc/mm/hugetlbpage-book3e.c | 15 ++-- arch/powerpc/mm/hugetlbpage.c| 116 -- arch/powerpc/mm/tlb_low_64e.S| 36 - arch/powerpc/mm/tlb_nohash.c |2 +- arch/powerpc/platforms/Kconfig.cputype |4 +- 12 files changed, 143 insertions(+), 106 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 01/13] powerpc: Only define HAVE_ARCH_HUGETLB_UNMAPPED_AREA if PPC_MM_SLICES
From: Becky Bruce bec...@kernel.crashing.org If we don't have slices, we should be able to use the generic hugetlb_get_unmapped_area() code Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/page_64.h |2 ++ arch/powerpc/mm/hugetlbpage.c |6 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h index fb40ede..fed85e6 100644 --- a/arch/powerpc/include/asm/page_64.h +++ b/arch/powerpc/include/asm/page_64.h @@ -130,7 +130,9 @@ do {\ #ifdef CONFIG_HUGETLB_PAGE +#ifdef CONFIG_PPC_MM_SLICES #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA +#endif #endif /* !CONFIG_HUGETLB_PAGE */ diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 48b65be..71c6533 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -686,19 +686,17 @@ int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, return 1; } +#ifdef CONFIG_PPC_MM_SLICES unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { -#ifdef CONFIG_PPC_MM_SLICES struct hstate *hstate = hstate_file(file); int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1, 0); -#else - return get_unmapped_area(file, addr, len, pgoff, flags); -#endif } +#endif unsigned long vma_mmu_pagesize(struct vm_area_struct *vma) { -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 02/13] powerpc: hugetlb: fix huge_ptep_set_access_flags return value
From: Becky Bruce bec...@kernel.crashing.org There was an unconditional return of 1 in the original code from David Gibson, and I dropped it because it wasn't needed for FSL BOOKE 32-bit. However, not all systems (including 64-bit FSL BOOKE) do loading of the hpte from the fault handler asm and depend on this function returning 1, which causes a call to update_mmu_cache() that writes an entry into the tlb. Signed-off-by: Becky Bruce bec...@kernel.crashing.org Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- arch/powerpc/include/asm/hugetlb.h | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 8600493..70f9885 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -124,7 +124,18 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty) { +#if defined(CONFIG_PPC_MMU_NOHASH) \ + !(defined(CONFIG_PPC_FSL_BOOK3E) defined(CONFIG_PPC32)) + /* +* The return 1 forces a call of update_mmu_cache, which will write a +* TLB entry. Without this, platforms that don't do a write of the TLB +* entry in the TLB miss handler asm will fault ad infinitum. +*/ + ptep_set_access_flags(vma, addr, ptep, pte, dirty); + return 1; +#else return ptep_set_access_flags(vma, addr, ptep, pte, dirty); +#endif } static inline pte_t huge_ptep_get(pte_t *ptep) -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 03/13] powerpc: Fix booke hugetlb preload code for PPC_MM_SLICES and 64-bit
From: Becky Bruce bec...@kernel.crashing.org This patch does 2 things: It corrects the code that determines the size to write into MAS1 for the PPC_MM_SLICES case (this originally came from David Gibson and I had incorrectly altered it), and it changes the methodolody used to calculate the size for !PPC_MM_SLICES to work for 64-bit as well as 32-bit. Signed-off-by: Becky Bruce bec...@kernel.crashing.org Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- arch/powerpc/mm/hugetlbpage-book3e.c | 15 ++- 1 files changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c index 343ad0b..4d6d849 100644 --- a/arch/powerpc/mm/hugetlbpage-book3e.c +++ b/arch/powerpc/mm/hugetlbpage-book3e.c @@ -45,23 +45,20 @@ void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte) unsigned long flags; #ifdef CONFIG_PPC_FSL_BOOK3E - int index, lz, ncams; - struct vm_area_struct *vma; + int index, ncams; #endif if (unlikely(is_kernel_addr(ea))) return; #ifdef CONFIG_PPC_MM_SLICES - psize = mmu_get_tsize(get_slice_psize(mm, ea)); - tsize = mmu_get_psize(psize); + psize = get_slice_psize(mm, ea); + tsize = mmu_get_tsize(psize); shift = mmu_psize_defs[psize].shift; #else - vma = find_vma(mm, ea); - psize = vma_mmu_pagesize(vma); /* returns actual size in bytes */ - asm (PPC_CNTLZL %0,%1 : =r (lz) : r (psize)); - shift = 31 - lz; - tsize = 21 - lz; + psize = vma_mmu_pagesize(find_vma(mm, ea)); + shift = __ilog2(psize); + tsize = shift - 10; #endif /* -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 04/13] powerpc: Update hugetlb huge_pte_alloc and tablewalk code for FSL BOOKE
From: Becky Bruce bec...@kernel.crashing.org This updates the hugetlb page table code to handle 64-bit FSL_BOOKE. The previous 32-bit work counted on the inner levels of the page table collapsing. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/mm/hugetlbpage.c | 48 +++- 1 files changed, 42 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 71c6533..b4a4884 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -155,11 +155,28 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, hpdp-pd = 0; kmem_cache_free(cachep, new); } +#else + if (!hugepd_none(*hpdp)) + kmem_cache_free(cachep, new); + else + hpdp-pd = ((unsigned long)new ~PD_HUGE) | pshift; #endif spin_unlock(mm-page_table_lock); return 0; } +/* + * These macros define how to determine which level of the page table holds + * the hpdp. + */ +#ifdef CONFIG_PPC_FSL_BOOK3E +#define HUGEPD_PGD_SHIFT PGDIR_SHIFT +#define HUGEPD_PUD_SHIFT PUD_SHIFT +#else +#define HUGEPD_PGD_SHIFT PUD_SHIFT +#define HUGEPD_PUD_SHIFT PMD_SHIFT +#endif + pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) { pgd_t *pg; @@ -172,12 +189,13 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz addr = ~(sz-1); pg = pgd_offset(mm, addr); - if (pshift = PUD_SHIFT) { + + if (pshift = HUGEPD_PGD_SHIFT) { hpdp = (hugepd_t *)pg; } else { pdshift = PUD_SHIFT; pu = pud_alloc(mm, pg, addr); - if (pshift = PMD_SHIFT) { + if (pshift = HUGEPD_PUD_SHIFT) { hpdp = (hugepd_t *)pu; } else { pdshift = PMD_SHIFT; @@ -453,14 +471,23 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, unsigned long start; start = addr; - pmd = pmd_offset(pud, addr); do { + pmd = pmd_offset(pud, addr); next = pmd_addr_end(addr, end); if (pmd_none(*pmd)) continue; +#ifdef CONFIG_PPC_FSL_BOOK3E + /* +* Increment next by the size of the huge mapping since +* there may be more than one entry at this level for a +* single hugepage, but all of them point to +* the same kmem cache that holds the hugepte. +*/ + next = addr + (1 hugepd_shift(*(hugepd_t *)pmd)); +#endif free_hugepd_range(tlb, (hugepd_t *)pmd, PMD_SHIFT, addr, next, floor, ceiling); - } while (pmd++, addr = next, addr != end); + } while (addr = next, addr != end); start = PUD_MASK; if (start floor) @@ -487,8 +514,8 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, unsigned long start; start = addr; - pud = pud_offset(pgd, addr); do { + pud = pud_offset(pgd, addr); next = pud_addr_end(addr, end); if (!is_hugepd(pud)) { if (pud_none_or_clear_bad(pud)) @@ -496,10 +523,19 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling); } else { +#ifdef CONFIG_PPC_FSL_BOOK3E + /* +* Increment next by the size of the huge mapping since +* there may be more than one entry at this level for a +* single hugepage, but all of them point to +* the same kmem cache that holds the hugepte. +*/ + next = addr + (1 hugepd_shift(*(hugepd_t *)pud)); +#endif free_hugepd_range(tlb, (hugepd_t *)pud, PUD_SHIFT, addr, next, floor, ceiling); } - } while (pud++, addr = next, addr != end); + } while (addr = next, addr != end); start = PGDIR_MASK; if (start floor) -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 05/13] powerpc: hugetlb: modify include usage for FSL BookE code
From: Becky Bruce bec...@kernel.crashing.org The original 32-bit hugetlb implementation used PPC64 vs PPC32 to determine which code path to take. However, the final hugetlb implementation for 64-bit FSL ended up shared with the FSL 32-bit code so the actual check needs to be FSL_BOOK3E vs everything else. This patch changes the include protections to reflect this. There are also a couple of related comment fixes. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/hugetlb.h |6 ++-- arch/powerpc/mm/hugetlbpage.c | 54 --- arch/powerpc/mm/tlb_nohash.c |2 +- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 70f9885..273acfa 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -22,14 +22,14 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, unsigned pdshift) { /* -* On 32-bit, we have multiple higher-level table entries that point to -* the same hugepte. Just use the first one since they're all +* On FSL BookE, we have multiple higher-level table entries that +* point to the same hugepte. Just use the first one since they're all * identical. So for that case, idx=0. */ unsigned long idx = 0; pte_t *dir = hugepd_page(*hpdp); -#ifdef CONFIG_PPC64 +#ifndef CONFIG_PPC_FSL_BOOK3E idx = (addr ((1UL pdshift) - 1)) hugepd_shift(*hpdp); #endif diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index b4a4884..9a34606 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -33,17 +33,17 @@ unsigned int HPAGE_SHIFT; * implementations may have more than one gpage size due to limitations * of the memory allocators, so we need multiple arrays */ -#ifdef CONFIG_PPC64 -#define MAX_NUMBER_GPAGES 1024 -static u64 gpage_freearray[MAX_NUMBER_GPAGES]; -static unsigned nr_gpages; -#else +#ifdef CONFIG_PPC_FSL_BOOK3E #define MAX_NUMBER_GPAGES 128 struct psize_gpages { u64 gpage_list[MAX_NUMBER_GPAGES]; unsigned int nr_gpages; }; static struct psize_gpages gpage_freearray[MMU_PAGE_COUNT]; +#else +#define MAX_NUMBER_GPAGES 1024 +static u64 gpage_freearray[MAX_NUMBER_GPAGES]; +static unsigned nr_gpages; #endif static inline int shift_to_mmu_psize(unsigned int shift) @@ -114,12 +114,12 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, struct kmem_cache *cachep; pte_t *new; -#ifdef CONFIG_PPC64 - cachep = PGT_CACHE(pdshift - pshift); -#else +#ifdef CONFIG_PPC_FSL_BOOK3E int i; int num_hugepd = 1 (pshift - pdshift); cachep = hugepte_cache; +#else + cachep = PGT_CACHE(pdshift - pshift); #endif new = kmem_cache_zalloc(cachep, GFP_KERNEL|__GFP_REPEAT); @@ -131,12 +131,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, return -ENOMEM; spin_lock(mm-page_table_lock); -#ifdef CONFIG_PPC64 - if (!hugepd_none(*hpdp)) - kmem_cache_free(cachep, new); - else - hpdp-pd = ((unsigned long)new ~PD_HUGE) | pshift; -#else +#ifdef CONFIG_PPC_FSL_BOOK3E /* * We have multiple higher-level entries that point to the same * actual pte location. Fill in each as we go and backtrack on error. @@ -215,7 +210,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz return hugepte_offset(hpdp, addr, pdshift); } -#ifdef CONFIG_PPC32 +#ifdef CONFIG_PPC_FSL_BOOK3E /* Build list of addresses of gigantic pages. This function is used in early * boot before the buddy or bootmem allocator is setup. */ @@ -335,7 +330,7 @@ void __init reserve_hugetlb_gpages(void) } } -#else /* PPC64 */ +#else /* !PPC_FSL_BOOK3E */ /* Build list of addresses of gigantic pages. This function is used in early * boot before the buddy or bootmem allocator is setup. @@ -373,7 +368,7 @@ int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) return 0; } -#ifdef CONFIG_PPC32 +#ifdef CONFIG_PPC_FSL_BOOK3E #define HUGEPD_FREELIST_SIZE \ ((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t)) @@ -433,11 +428,11 @@ static void free_hugepd_range(struct mmu_gather *tlb, hugepd_t *hpdp, int pdshif unsigned long pdmask = ~((1UL pdshift) - 1); unsigned int num_hugepd = 1; -#ifdef CONFIG_PPC64 - unsigned int shift = hugepd_shift(*hpdp); -#else - /* Note: On 32-bit the hpdp may be the first of several */ +#ifdef CONFIG_PPC_FSL_BOOK3E + /* Note: On fsl the hpdp may be the first of several */ num_hugepd = (1 (hugepd_shift(*hpdp) - pdshift)); +#else + unsigned int shift = hugepd_shift(*hpdp
[PATCH 06/13] powerpc: Whitespace/comment changes to tlb_low_64e.S
From: Becky Bruce bec...@kernel.crashing.org I happened to comment this code while I was digging through it; we might as well commit that. I also made some whitespace changes - the existing code had a lot of unnecessary newlines that I found annoying when I was working on my tiny laptop. No functional changes. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/mm/tlb_low_64e.S | 28 +++- 1 files changed, 11 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index dc4a5f3..71d5d9a 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S @@ -94,11 +94,11 @@ srdir15,r16,60 /* get region */ rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4 - bne-dtlb_miss_fault_bolted + bne-dtlb_miss_fault_bolted /* Bail if fault addr is invalid */ rlwinm r10,r11,32-19,27,27 rlwimi r10,r11,32-16,19,19 - cmpwi r15,0 + cmpwi r15,0 /* user vs kernel check */ ori r10,r10,_PAGE_PRESENT orisr11,r10,_PAGE_ACCESSED@h @@ -120,44 +120,38 @@ tlb_miss_common_bolted: rldicl r15,r16,64-PGDIR_SHIFT+3,64-PGD_INDEX_SIZE-3 cmpldi cr0,r14,0 clrrdi r15,r15,3 - beq tlb_miss_fault_bolted + beq tlb_miss_fault_bolted /* No PGDIR, bail */ BEGIN_MMU_FTR_SECTION /* Set the TLB reservation and search for existing entry. Then load * the entry. */ PPC_TLBSRX_DOT(0,r16) - ldx r14,r14,r15 - beq normal_tlb_miss_done + ldx r14,r14,r15 /* grab pgd entry */ + beq normal_tlb_miss_done/* tlb exists already, bail */ MMU_FTR_SECTION_ELSE - ldx r14,r14,r15 + ldx r14,r14,r15 /* grab pgd entry */ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV) #ifndef CONFIG_PPC_64K_PAGES rldicl r15,r16,64-PUD_SHIFT+3,64-PUD_INDEX_SIZE-3 clrrdi r15,r15,3 - - cmpldi cr0,r14,0 - beq tlb_miss_fault_bolted - - ldx r14,r14,r15 + cmlpdi cr0,r14,0 + beq tlb_miss_fault_bolted /* Bad pgd entry */ + ldx r14,r14,r15 /* grab pud entry */ #endif /* CONFIG_PPC_64K_PAGES */ rldicl r15,r16,64-PMD_SHIFT+3,64-PMD_INDEX_SIZE-3 clrrdi r15,r15,3 - cmpldi cr0,r14,0 beq tlb_miss_fault_bolted - - ldx r14,r14,r15 + ldx r14,r14,r15 /* Grab pmd entry */ rldicl r15,r16,64-PAGE_SHIFT+3,64-PTE_INDEX_SIZE-3 clrrdi r15,r15,3 - cmpldi cr0,r14,0 beq tlb_miss_fault_bolted - - ldx r14,r14,r15 + ldx r14,r14,r15 /* Grab PTE */ /* Check if required permissions are met */ andc. r15,r11,r14 -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 07/13] powerpc: Add hugepage support to 64-bit tablewalk code for FSL_BOOK3E
From: Becky Bruce bec...@kernel.crashing.org Before hugetlb, at each level of the table, we test for !0 to determine if we have a valid table entry. With hugetlb, this compare becomes: 0 is a normal entry 0 is an invalid entry 0 is huge This works because the hugepage code pulls the top bit off the entry (which for non-huge entries always has the top bit set) as an indicator that we have a hugepage. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/mm/tlb_low_64e.S | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index 71d5d9a..ff672bd 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S @@ -136,22 +136,22 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV) #ifndef CONFIG_PPC_64K_PAGES rldicl r15,r16,64-PUD_SHIFT+3,64-PUD_INDEX_SIZE-3 clrrdi r15,r15,3 - cmlpdi cr0,r14,0 - beq tlb_miss_fault_bolted /* Bad pgd entry */ + cmpdi cr0,r14,0 + bge tlb_miss_fault_bolted /* Bad pgd entry or hugepage; bail */ ldx r14,r14,r15 /* grab pud entry */ #endif /* CONFIG_PPC_64K_PAGES */ rldicl r15,r16,64-PMD_SHIFT+3,64-PMD_INDEX_SIZE-3 clrrdi r15,r15,3 - cmpldi cr0,r14,0 - beq tlb_miss_fault_bolted + cmpdi cr0,r14,0 + bge tlb_miss_fault_bolted ldx r14,r14,r15 /* Grab pmd entry */ rldicl r15,r16,64-PAGE_SHIFT+3,64-PTE_INDEX_SIZE-3 clrrdi r15,r15,3 - cmpldi cr0,r14,0 - beq tlb_miss_fault_bolted - ldx r14,r14,r15 /* Grab PTE */ + cmpdi cr0,r14,0 + bge tlb_miss_fault_bolted + ldx r14,r14,r15 /* Grab PTE, normal (!huge) page */ /* Check if required permissions are met */ andc. r15,r11,r14 -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 08/13] powerpc: Add gpages reservation code for 64-bit FSL BOOKE
From: Becky Bruce bec...@kernel.crashing.org For 64-bit FSL_BOOKE implementations, gigantic pages need to be reserved at boot time by the memblock code based on the command line. This adds the call that handles the reservation, and fixes some code comments. It also removes the previous pr_err when reserve_hugetlb_gpages is called on a system without hugetlb enabled - the way the code is structured, the call is unconditional and the resulting error message spurious and confusing. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/hugetlb.h | 19 ++- arch/powerpc/kernel/setup_64.c | 10 ++ arch/powerpc/mm/hugetlbpage.c |8 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 273acfa..555044c 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -5,7 +5,6 @@ #include asm/page.h extern struct kmem_cache *hugepte_cache; -extern void __init reserve_hugetlb_gpages(void); static inline pte_t *hugepd_page(hugepd_t hpd) { @@ -153,14 +152,24 @@ static inline void arch_release_hugepage(struct page *page) } #else /* ! CONFIG_HUGETLB_PAGE */ -static inline void reserve_hugetlb_gpages(void) -{ - pr_err(Cannot reserve gpages without hugetlb enabled\n); -} static inline void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { } +#endif /* CONFIG_HUGETLB_PAGE */ + + +/* + * FSL Book3E platforms require special gpage handling - the gpages + * are reserved early in the boot process by memblock instead of via + * the .dts as on IBM platforms. + */ +#if defined(CONFIG_HUGETLB_PAGE) defined(CONFIG_PPC_FSL_BOOK3E) +extern void __init reserve_hugetlb_gpages(void); +#else +static inline void reserve_hugetlb_gpages(void) +{ +} #endif #endif /* _ASM_POWERPC_HUGETLB_H */ diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index d4168c9..2e334d4 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -35,6 +35,8 @@ #include linux/pci.h #include linux/lockdep.h #include linux/memblock.h +#include linux/hugetlb.h + #include asm/io.h #include asm/kdump.h #include asm/prom.h @@ -64,6 +66,7 @@ #include asm/mmu_context.h #include asm/code-patching.h #include asm/kvm_ppc.h +#include asm/hugetlb.h #include setup.h @@ -217,6 +220,13 @@ void __init early_setup(unsigned long dt_ptr) /* Initialize the hash table or TLB handling */ early_init_mmu(); + /* +* Reserve any gigantic pages requested on the command line. +* memblock needs to have been initialized by the time this is +* called since this will reserve memory. +*/ + reserve_hugetlb_gpages(); + DBG( - early_setup()\n); } diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 9a34606..51855a0 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -28,10 +28,10 @@ unsigned int HPAGE_SHIFT; /* * Tracks gpages after the device tree is scanned and before the - * huge_boot_pages list is ready. On 64-bit implementations, this is - * just used to track 16G pages and so is a single array. 32-bit - * implementations may have more than one gpage size due to limitations - * of the memory allocators, so we need multiple arrays + * huge_boot_pages list is ready. On non-Freescale implementations, this is + * just used to track 16G pages and so is a single array. FSL-based + * implementations may have more than one gpage size, so we need multiple + * arrays */ #ifdef CONFIG_PPC_FSL_BOOK3E #define MAX_NUMBER_GPAGES 128 -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 09/13] powerpc: Kconfig updates for FSL BookE HUGETLB 64-bit
From: Becky Bruce bec...@kernel.crashing.org Allow hugetlb to be enabled on 64b FSL_BOOK3E. No platforms enable it by default yet. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/platforms/Kconfig.cputype |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index a85990c..7e47fd4 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -174,7 +174,6 @@ config BOOKE config FSL_BOOKE bool depends on (E200 || E500) PPC32 - select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT default y # this is for common code between PPC32 PPC64 FSL BOOKE @@ -182,6 +181,7 @@ config PPC_FSL_BOOK3E bool select FSL_EMB_PERFMON select PPC_SMP_MUXED_IPI + select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64 default y if FSL_BOOKE config PTE_64BIT @@ -298,7 +298,7 @@ config PPC_BOOK3E_MMU config PPC_MM_SLICES bool - default y if (PPC64 HUGETLB_PAGE) || (PPC_STD_MMU_64 PPC_64K_PAGES) + default y if (!PPC_FSL_BOOK3E PPC64 HUGETLB_PAGE) || (PPC_STD_MMU_64 PPC_64K_PAGES) default n config VIRT_CPU_ACCOUNTING -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 10/13] powerpc: Update mpc85xx/corenet 32-bit defconfigs
From: Becky Bruce bec...@kernel.crashing.org Results from updates via make savedefconfig. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/configs/corenet32_smp_defconfig |8 arch/powerpc/configs/mpc85xx_defconfig |5 + arch/powerpc/configs/mpc85xx_smp_defconfig |6 +- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index 4311d02..ab4db40 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig @@ -12,9 +12,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_EMBEDDED=y CONFIG_PERF_EVENTS=y CONFIG_SLAB=y @@ -69,7 +67,6 @@ CONFIG_IPV6=y CONFIG_IP_SCTP=m CONFIG_UEVENT_HELPER_PATH=/sbin/hotplug CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y @@ -107,7 +104,6 @@ CONFIG_FSL_PQ_MDIO=y # CONFIG_INPUT_MOUSE is not set CONFIG_SERIO_LIBPS2=y # CONFIG_LEGACY_PTYS is not set -CONFIG_PPC_EPAPR_HV_BYTECHAN=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_EXTENDED=y @@ -136,8 +132,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y CONFIG_USB_STORAGE=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_OF=y -CONFIG_MMC_SDHCI_OF_ESDHC=y CONFIG_EDAC=y CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_MPC85XX=y @@ -146,7 +140,6 @@ CONFIG_RTC_DRV_DS3232=y CONFIG_RTC_DRV_CMOS=y CONFIG_UIO=y CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set CONFIG_VIRT_DRIVERS=y CONFIG_FSL_HV_MANAGER=y CONFIG_EXT2_FS=y @@ -173,7 +166,6 @@ CONFIG_MAC_PARTITION=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_UTF8=m CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index 2500912..a1e5a17 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -10,10 +10,8 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -41,7 +39,6 @@ CONFIG_TQM8560=y CONFIG_SBC8548=y CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y -CONFIG_GPIO_MPC8XXX=y CONFIG_HIGHMEM=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -123,6 +120,7 @@ CONFIG_NVRAM=y CONFIG_I2C=y CONFIG_I2C_CPM=m CONFIG_I2C_MPC=y +CONFIG_GPIO_MPC8XXX=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y @@ -206,7 +204,6 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y CONFIG_CRC_T10DIF=y CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y CONFIG_SYSCTL_SYSCALL_CHECK=y diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index a4ba13b..dd1e413 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -12,10 +12,8 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -42,7 +40,6 @@ CONFIG_TQM8560=y CONFIG_SBC8548=y CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y -CONFIG_GPIO_MPC8XXX=y CONFIG_HIGHMEM=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -124,6 +121,7 @@ CONFIG_NVRAM=y CONFIG_I2C=y CONFIG_I2C_CPM=m CONFIG_I2C_MPC=y +CONFIG_GPIO_MPC8XXX=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y @@ -207,10 +205,8 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y CONFIG_CRC_T10DIF=y CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_VIRQ_DEBUG=y CONFIG_CRYPTO_PCBC=m -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 11/13] powerpc: Enable Hugetlb by default for 32-bit 85xx/corenet
From: Becky Bruce bec...@kernel.crashing.org Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/configs/corenet32_smp_defconfig |1 + arch/powerpc/configs/mpc85xx_defconfig |1 + arch/powerpc/configs/mpc85xx_smp_defconfig |1 + 3 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index ab4db40..1c328da 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig @@ -154,6 +154,7 @@ CONFIG_VFAT_FS=y CONFIG_NTFS_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index a1e5a17..542eaa1 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -182,6 +182,7 @@ CONFIG_VFAT_FS=y CONFIG_NTFS_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y CONFIG_ADFS_FS=m CONFIG_AFFS_FS=m CONFIG_HFS_FS=m diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index dd1e413..c0a9574 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -183,6 +183,7 @@ CONFIG_VFAT_FS=y CONFIG_NTFS_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y CONFIG_ADFS_FS=m CONFIG_AFFS_FS=m CONFIG_HFS_FS=m -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 12/13] powerpc: Update corenet64_smp_defconfig
From: Becky Bruce bec...@kernel.crashing.org Updates from make savedefconfig. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/configs/corenet64_smp_defconfig |5 - 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index c92c204..782822c 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig @@ -11,10 +11,8 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -25,7 +23,6 @@ CONFIG_P5020_DS=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BINFMT_MISC=m -# CONFIG_PCI is not set CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -93,10 +90,8 @@ CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=m CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_VIRQ_DEBUG=y CONFIG_CRYPTO_PCBC=m -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 13/13] powerpc: Enable hugetlb by default for corenet64 platforms
From: Becky Bruce bec...@kernel.crashing.org Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/configs/corenet64_smp_defconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index 782822c..53741f4 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig @@ -81,6 +81,7 @@ CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_PROC_KCORE=y CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y # CONFIG_MISC_FILESYSTEMS is not set CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix hugetlb with CONFIG_PPC_MM_SLICES=y
On Sep 21, 2011, at 12:58 AM, Paul Mackerras wrote: Commit 41151e77a4 (powerpc: Hugetlb for BookE) added some #ifdef CONFIG_MM_SLICES conditionals to hugetlb_get_unmapped_area() and vma_mmu_pagesize(). Unfortunately this is not the correct config symbol; it should be CONFIG_PPC_MM_SLICES. The result is that attempting to use hugetlbfs on 64-bit Power server processors results in an infinite stack recursion between get_unmapped_area() and hugetlb_get_unmapped_area(). This fixes it by changing the #ifdef to use CONFIG_PPC_MM_SLICES in those functions and also in book3e_hugetlb_preload(). Signed-off-by: Paul Mackerras pau...@samba.org Paul, Ben, ACK since it looks like Ben has picked this up already. but FYI I have a different version of this fix in my tree. The get_unmapped_area() shouldn't be there *at all* - we can just use the generic code if we don't have slices. So instead the whole hugetlb_get_unmapped_area function should be wrapped in PPC_MM_SLICES. This is crufty debug stuff that I missed yanking out when I pushed the patch, my apologies. I'll just submit a followup patch to fix this. Cheers, B --- arch/powerpc/mm/hugetlbpage-book3e.c |2 +- arch/powerpc/mm/hugetlbpage.c|4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c index 1295b7c..343ad0b 100644 --- a/arch/powerpc/mm/hugetlbpage-book3e.c +++ b/arch/powerpc/mm/hugetlbpage-book3e.c @@ -52,7 +52,7 @@ void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte) if (unlikely(is_kernel_addr(ea))) return; -#ifdef CONFIG_MM_SLICES +#ifdef CONFIG_PPC_MM_SLICES psize = mmu_get_tsize(get_slice_psize(mm, ea)); tsize = mmu_get_psize(psize); shift = mmu_psize_defs[psize].shift; diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 3a5f59d..48b65be 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -690,7 +690,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { -#ifdef CONFIG_MM_SLICES +#ifdef CONFIG_PPC_MM_SLICES struct hstate *hstate = hstate_file(file); int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate)); @@ -702,7 +702,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long vma_mmu_pagesize(struct vm_area_struct *vma) { -#ifdef CONFIG_MM_SLICES +#ifdef CONFIG_PPC_MM_SLICES unsigned int psize = get_slice_psize(vma-vm_mm, vma-vm_start); return 1UL mmu_psize_to_shift(psize); -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/5] hugetlb: add phys addr to struct huge_bootmem_page
On Jul 21, 2011, at 5:44 PM, Andrew Morton wrote: On Tue, 28 Jun 2011 14:54:45 -0500 Becky Bruce bec...@kernel.crashing.org wrote: From: Becky Bruce bec...@kernel.crashing.org This is needed on HIGHMEM systems - we don't always have a virtual address so store the physical address and map it in as needed. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- include/linux/hugetlb.h |3 +++ mm/hugetlb.c|8 +++- 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 59225ef..19644e0 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -231,6 +231,9 @@ struct hstate { struct huge_bootmem_page { struct list_head list; struct hstate *hstate; +#ifdef CONFIG_HIGHMEM +phys_addr_t phys; +#endif }; struct page *alloc_huge_page_node(struct hstate *h, int nid); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 6402458..2db81ea 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1105,8 +1105,14 @@ static void __init gather_bootmem_prealloc(void) struct huge_bootmem_page *m; list_for_each_entry(m, huge_boot_pages, list) { -struct page *page = virt_to_page(m); struct hstate *h = m-hstate; +#ifdef CONFIG_HIGHMEM +struct page *page = pfn_to_page(m-phys PAGE_SHIFT); +free_bootmem_late((unsigned long)m, + sizeof(struct huge_bootmem_page)); +#else +struct page *page = virt_to_page(m); +#endif __ClearPageReserved(page); WARN_ON(page_count(page) != 1); prep_compound_huge_page(page, h-order); nit: wrapping both definitions and statements in an ifdef like this is a bit nasty from a readability and maintainability point of view - it's inviting people to later make changes which fail to compile when the config option is flipped. This is better: --- a/mm/hugetlb.c~hugetlb-add-phys-addr-to-struct-huge_bootmem_page-fix +++ a/mm/hugetlb.c @@ -1106,12 +1106,14 @@ static void __init gather_bootmem_preall list_for_each_entry(m, huge_boot_pages, list) { struct hstate *h = m-hstate; + struct page *page; + #ifdef CONFIG_HIGHMEM - struct page *page = pfn_to_page(m-phys PAGE_SHIFT); + page = pfn_to_page(m-phys PAGE_SHIFT); free_bootmem_late((unsigned long)m, sizeof(struct huge_bootmem_page)); #else - struct page *page = virt_to_page(m); + page = virt_to_page(m); #endif __ClearPageReserved(page); WARN_ON(page_count(page) != 1); Andrew, I totally agree, this is better, thanks. I see you've put my original patch and your fix into -mm; I'd like it to percolate there for a bit before it goes to Linus to be sure I haven't broken anything. It should be safe, as I don't think this particular function was ever expected to work on highmem platforms, but it's possible I'm overlooking something. Cheers, -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/5] hugetlb: add phys addr to struct huge_bootmem_page
On Jun 28, 2011, at 4:39 PM, Benjamin Herrenschmidt wrote: On Tue, 2011-06-28 at 14:54 -0500, Becky Bruce wrote: struct page *alloc_huge_page_node(struct hstate *h, int nid); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 6402458..2db81ea 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1105,8 +1105,14 @@ static void __init gather_bootmem_prealloc(void) struct huge_bootmem_page *m; list_for_each_entry(m, huge_boot_pages, list) { - struct page *page = virt_to_page(m); struct hstate *h = m-hstate; +#ifdef CONFIG_HIGHMEM + struct page *page = pfn_to_page(m-phys PAGE_SHIFT); + free_bootmem_late((unsigned long)m, + sizeof(struct huge_bootmem_page)); +#else + struct page *page = virt_to_page(m); +#endif __ClearPageReserved(page); Why do you add free_bootmem_late() in the highmem case and not the normal case ? Because there was no bootmem allocation in the normal case - the non-highmem version stores data structure in the huge page itself. This is perfectly fine as long as you have a mapping. Since this isn't true for HIGHMEM pages, I allocate bootmem to store the early data structure that stores information about the hugepage (this happens in arch-specific code in alloc_bootmem_huge_page). -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/5] fs/hugetlbfs/inode.c: Fix pgoff alignment checking on 32-bit
From: Becky Bruce bec...@kernel.crashing.org This: vma-vm_pgoff ~(huge_page_mask(h) PAGE_SHIFT) is incorrect on 32-bit. It causes us to the pgoff with something that looks like this (for a 4m hugepage): 0xfff003ff. The mask should be flipped and *then* shifted, to give you 0x_03fff. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- fs/hugetlbfs/inode.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 7aafeb8..537a209 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -94,7 +94,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) vma-vm_flags |= VM_HUGETLB | VM_RESERVED; vma-vm_ops = hugetlb_vm_ops; - if (vma-vm_pgoff ~(huge_page_mask(h) PAGE_SHIFT)) + if (vma-vm_pgoff (~huge_page_mask(h) PAGE_SHIFT)) return -EINVAL; vma_len = (loff_t)(vma-vm_end - vma-vm_start); -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/5] hugetlb: add phys addr to struct huge_bootmem_page
From: Becky Bruce bec...@kernel.crashing.org This is needed on HIGHMEM systems - we don't always have a virtual address so store the physical address and map it in as needed. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- include/linux/hugetlb.h |3 +++ mm/hugetlb.c|8 +++- 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 59225ef..19644e0 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -231,6 +231,9 @@ struct hstate { struct huge_bootmem_page { struct list_head list; struct hstate *hstate; +#ifdef CONFIG_HIGHMEM + phys_addr_t phys; +#endif }; struct page *alloc_huge_page_node(struct hstate *h, int nid); diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 6402458..2db81ea 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1105,8 +1105,14 @@ static void __init gather_bootmem_prealloc(void) struct huge_bootmem_page *m; list_for_each_entry(m, huge_boot_pages, list) { - struct page *page = virt_to_page(m); struct hstate *h = m-hstate; +#ifdef CONFIG_HIGHMEM + struct page *page = pfn_to_page(m-phys PAGE_SHIFT); + free_bootmem_late((unsigned long)m, + sizeof(struct huge_bootmem_page)); +#else + struct page *page = virt_to_page(m); +#endif __ClearPageReserved(page); WARN_ON(page_count(page) != 1); prep_compound_huge_page(page, h-order); -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/5] powerpc: mem_init should call memblock_is_reserved with phys_addr_t
From: Becky Bruce bec...@kernel.crashing.org This has been broken for a while but hasn't been an issue until now because nobody was reserving regions at high addresses. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/mm/mem.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 57e545b..097b288 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -337,8 +337,9 @@ void __init mem_init(void) highmem_mapnr = lowmem_end_addr PAGE_SHIFT; for (pfn = highmem_mapnr; pfn max_mapnr; ++pfn) { + phys_addr_t paddr = (phys_addr_t)pfn PAGE_SHIFT; struct page *page = pfn_to_page(pfn); - if (memblock_is_reserved(pfn PAGE_SHIFT)) + if (memblock_is_reserved(paddr)) continue; ClearPageReserved(page); init_page_count(page); -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/5] powerpc: Create next_tlbcam_idx percpu variable for FSL_BOOKE
From: Becky Bruce bec...@kernel.crashing.org This is used to round-robin TLBCAM entries. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/mmu.h |5 + arch/powerpc/kernel/smp.c |4 arch/powerpc/mm/mem.c |9 + arch/powerpc/mm/tlb_nohash.c |6 ++ 4 files changed, 24 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 4138b21..b427a55 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -115,6 +115,11 @@ #ifndef __ASSEMBLY__ #include asm/cputable.h +#ifdef CONFIG_PPC_FSL_BOOK3E +#include asm/percpu.h +DECLARE_PER_CPU(int, next_tlbcam_idx); +#endif + static inline int mmu_has_feature(unsigned long feature) { return (cur_cpu_spec-mmu_features feature); diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 2975f64..3c9681a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -313,6 +313,10 @@ struct thread_info *current_set[NR_CPUS]; static void __devinit smp_store_cpu_info(int id) { per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR); +#ifdef CONFIG_PPC_FSL_BOOK3E + per_cpu(next_tlbcam_idx, id) + = (mfspr(SPRN_TLB1CFG) TLBnCFG_N_ENTRY) - 1; +#endif } void __init smp_prepare_cpus(unsigned int max_cpus) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 097b288..7209901 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -353,6 +353,15 @@ void __init mem_init(void) } #endif /* CONFIG_HIGHMEM */ +#if defined(CONFIG_PPC_FSL_BOOK3E) !defined(CONFIG_SMP) + /* +* If smp is enabled, next_tlbcam_idx is initialized in the cpu up +* functions do it here for the non-smp case. +*/ + per_cpu(next_tlbcam_idx, smp_processor_id()) = + (mfspr(SPRN_TLB1CFG) TLBnCFG_N_ENTRY) - 1; +#endif + printk(KERN_INFO Memory: %luk/%luk available (%luk kernel code, %luk reserved, %luk data, %luk bss, %luk init)\n, nr_free_pages() (PAGE_SHIFT-10), diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index 5693499..ea037ba 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c @@ -102,6 +102,12 @@ unsigned long linear_map_top; /* Top of linear mapping */ #endif /* CONFIG_PPC64 */ +#ifdef CONFIG_PPC_FSL_BOOK3E +/* next_tlbcam_idx is used to round-robin tlbcam entry assignment */ +DEFINE_PER_CPU(int, next_tlbcam_idx); +EXPORT_PER_CPU_SYMBOL(next_tlbcam_idx); +#endif + /* * Base TLB flushing operations: * -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 5/5] powerpc: Hugetlb for BookE
From: Becky Bruce bec...@kernel.crashing.org Enable hugepages on Freescale BookE processors. This allows the kernel to use huge TLB entries to map pages, which can greatly reduce the number of TLB misses and the amount of TLB thrashing experienced by applications with large memory footprints. Care should be taken when using this on FSL processors, as the number of large TLB entries supported by the core is low (16-64) on current processors. The supported set of hugepage sizes include 4m, 16m, 64m, 256m, and 1g. Page sizes larger than the max zone size are called gigantic pages and must be allocated on the command line (and cannot be deallocated). This is currently only fully implemented for Freescale 32-bit BookE processors, but there is some infrastructure in the code for 64-bit BooKE. Signed-off-by: Becky Bruce bec...@kernel.crashing.org Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- arch/powerpc/Kconfig |3 +- arch/powerpc/include/asm/hugetlb.h | 63 +- arch/powerpc/include/asm/mmu-book3e.h |7 + arch/powerpc/include/asm/mmu-hash64.h |3 +- arch/powerpc/include/asm/mmu.h | 18 +- arch/powerpc/include/asm/page.h| 31 +++- arch/powerpc/include/asm/page_64.h | 11 - arch/powerpc/include/asm/pte-book3e.h |3 + arch/powerpc/kernel/head_fsl_booke.S | 133 ++-- arch/powerpc/mm/Makefile |1 + arch/powerpc/mm/hash_utils_64.c|3 - arch/powerpc/mm/hugetlbpage-book3e.c | 121 ++ arch/powerpc/mm/hugetlbpage.c | 379 arch/powerpc/mm/init_32.c |9 + arch/powerpc/mm/mem.c |5 + arch/powerpc/mm/mmu_context_nohash.c |5 + arch/powerpc/mm/pgtable.c |3 +- arch/powerpc/mm/tlb_low_64e.S | 24 +- arch/powerpc/mm/tlb_nohash.c | 46 - arch/powerpc/platforms/Kconfig.cputype |4 +- 20 files changed, 766 insertions(+), 106 deletions(-) create mode 100644 arch/powerpc/mm/hugetlbpage-book3e.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2729c66..b7af257 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -426,8 +426,7 @@ config ARCH_POPULATES_NODE_MAP def_bool y config SYS_SUPPORTS_HUGETLBFS - def_bool y - depends on PPC_BOOK3S_64 + bool source mm/Kconfig diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 5856a66..8600493 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -1,15 +1,60 @@ #ifndef _ASM_POWERPC_HUGETLB_H #define _ASM_POWERPC_HUGETLB_H +#ifdef CONFIG_HUGETLB_PAGE #include asm/page.h +extern struct kmem_cache *hugepte_cache; +extern void __init reserve_hugetlb_gpages(void); + +static inline pte_t *hugepd_page(hugepd_t hpd) +{ + BUG_ON(!hugepd_ok(hpd)); + return (pte_t *)((hpd.pd ~HUGEPD_SHIFT_MASK) | PD_HUGE); +} + +static inline unsigned int hugepd_shift(hugepd_t hpd) +{ + return hpd.pd HUGEPD_SHIFT_MASK; +} + +static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, + unsigned pdshift) +{ + /* +* On 32-bit, we have multiple higher-level table entries that point to +* the same hugepte. Just use the first one since they're all +* identical. So for that case, idx=0. +*/ + unsigned long idx = 0; + + pte_t *dir = hugepd_page(*hpdp); +#ifdef CONFIG_PPC64 + idx = (addr ((1UL pdshift) - 1)) hugepd_shift(*hpdp); +#endif + + return dir + idx; +} + pte_t *huge_pte_offset_and_shift(struct mm_struct *mm, unsigned long addr, unsigned *shift); void flush_dcache_icache_hugepage(struct page *page); +#if defined(CONFIG_PPC_MM_SLICES) || defined(CONFIG_PPC_SUBPAGE_PROT) int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len); +#else +static inline int is_hugepage_only_range(struct mm_struct *mm, +unsigned long addr, +unsigned long len) +{ + return 0; +} +#endif + +void book3e_hugetlb_preload(struct mm_struct *mm, unsigned long ea, pte_t pte); +void flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr); void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, unsigned long end, unsigned long floor, @@ -50,8 +95,11 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1); - return __pte(old); +#ifdef CONFIG_PPC64 + return __pte(pte_update(mm, addr, ptep, ~0UL, 1)); +#else + return __pte
[PATCH] powerpc/fsl-booke: Fix comments that refer to BAT registers
There are no BATS on BookE - we have the TLBCAM instead. Also correct the page size information to included extended (1G and 4G) sizes. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- Lame, I know, but this drives me batty every time I see it, and I've had customers get confused because of it. I've finally gotten irritated enough to send a patch. -Becky arch/powerpc/mm/fsl_booke_mmu.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index cdc7526..681429d 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -104,9 +104,9 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) } /* - * Set up one of the I/D BAT (block address translation) register pairs. - * The parameters are not checked; in particular size must be a power - * of 4 between 4k and 256M. + * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; + * in particular size must be a power of 4 between 4k and 256M (or 4G, for cpus + * that support extended page sizes). */ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, unsigned long size, unsigned long flags, unsigned int pid) -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V2] powerpc: Fix comments in fsl_booke_mmu code that mention BATS
There are no BATS on BookE - we have the TLBCAM instead. Also correct the page size information to included extended sizes. We don't actually allow a 4G page size to be used, so comment on that as well. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- Even lamer, I forgot that we don't actually allow use of a 4G page. Update the comment to reflect this. -Becky arch/powerpc/mm/fsl_booke_mmu.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index cdc7526..4b66a1e 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -104,9 +104,10 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) } /* - * Set up one of the I/D BAT (block address translation) register pairs. - * The parameters are not checked; in particular size must be a power - * of 4 between 4k and 256M. + * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; + * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus + * that support extended page sizes). Note that while some cpus support a + * page size of 4G, we don't allow its use here. */ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, unsigned long size, unsigned long flags, unsigned int pid) -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/fsl-booke: Move loadcam_entry back to asm code to fix SMP ftrace
On May 13, 2010, at 11:25 PM, Kumar Gala wrote: When we build with ftrace enabled its possible that loadcam_entry would have used the stack pointer (even though the code doesn't need it). We call loadcam_entry in __secondary_start before the stack is setup. To ensure that loadcam_entry doesn't use the stack pointer the easiest solution is to just have it in asm code. Signed-off-by: Kumar Gala ga...@kernel.crashing.org Looks good on 8572 SMP - both cpus come up properly now with ftrace enabled, and I am able to run the tracers. Tested-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/kernel/asm-offsets.c |8 arch/powerpc/mm/fsl_booke_mmu.c | 25 +++-- arch/powerpc/mm/mmu_decl.h| 10 +- arch/powerpc/mm/tlb_nohash_low.S | 28 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/ asm-offsets.c index c09138d..b894721 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -447,6 +447,14 @@ int main(void) DEFINE(PGD_T_LOG2, PGD_T_LOG2); DEFINE(PTE_T_LOG2, PTE_T_LOG2); #endif +#ifdef CONFIG_FSL_BOOKE + DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam)); + DEFINE(TLBCAM_MAS0, offsetof(struct tlbcam, MAS0)); + DEFINE(TLBCAM_MAS1, offsetof(struct tlbcam, MAS1)); + DEFINE(TLBCAM_MAS2, offsetof(struct tlbcam, MAS2)); + DEFINE(TLBCAM_MAS3, offsetof(struct tlbcam, MAS3)); + DEFINE(TLBCAM_MAS7, offsetof(struct tlbcam, MAS7)); +#endif #ifdef CONFIG_KVM_EXIT_TIMING DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu, diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/ fsl_booke_mmu.c index 1ed6b52..cdc7526 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -2,7 +2,7 @@ * Modifications by Kumar Gala (ga...@kernel.crashing.org) to support * E500 Book E processors. * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright 2004,2010 Freescale Semiconductor, Inc. * * This file contains the routines for initializing the MMU * on the 4xx series of chips. @@ -56,19 +56,13 @@ unsigned int tlbcam_index; -#define NUM_TLBCAMS(64) #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) (CONFIG_LOWMEM_CAM_NUM = NUM_TLBCAMS) #error LOWMEM_CAM_NUM must be less than NUM_TLBCAMS #endif -struct tlbcam { - u32 MAS0; - u32 MAS1; - unsigned long MAS2; - u32 MAS3; - u32 MAS7; -} TLBCAM[NUM_TLBCAMS]; +#define NUM_TLBCAMS(64) +struct tlbcam TLBCAM[NUM_TLBCAMS]; struct tlbcamrange { unsigned long start; @@ -109,19 +103,6 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) return 0; } -void loadcam_entry(int idx) -{ - mtspr(SPRN_MAS0, TLBCAM[idx].MAS0); - mtspr(SPRN_MAS1, TLBCAM[idx].MAS1); - mtspr(SPRN_MAS2, TLBCAM[idx].MAS2); - mtspr(SPRN_MAS3, TLBCAM[idx].MAS3); - - if (mmu_has_feature(MMU_FTR_BIG_PHYS)) - mtspr(SPRN_MAS7, TLBCAM[idx].MAS7); - - asm volatile(isync;tlbwe;isync : : : memory); -} - /* * Set up one of the I/D BAT (block address translation) register pairs. * The parameters are not checked; in particular size must be a power diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index d49a775..0591f25 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -149,7 +149,15 @@ extern unsigned long mmu_mapin_ram(unsigned long top); extern void MMU_init_hw(void); extern unsigned long mmu_mapin_ram(unsigned long top); extern void adjust_total_lowmem(void); - +extern void loadcam_entry(unsigned int index); + +struct tlbcam { + u32 MAS0; + u32 MAS1; + unsigned long MAS2; + u32 MAS3; + u32 MAS7; +}; #elif defined(CONFIG_PPC32) /* anything 32-bit except 4xx or 8xx */ extern void MMU_init_hw(void); diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/ tlb_nohash_low.S index bbdc5b5..8656ecf 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -271,3 +271,31 @@ _GLOBAL(set_context) #else #error Unsupported processor type ! #endif + +#if defined(CONFIG_FSL_BOOKE) +/* + * extern void loadcam_entry(unsigned int index) + * + * Load TLBCAM[index] entry in to the L2 CAM MMU + */ +_GLOBAL(loadcam_entry) + LOAD_REG_ADDR(r4, TLBCAM) + mulli r5,r3,TLBCAM_SIZE + add r3,r5,r4 + lwz r4,TLBCAM_MAS0(r3) + mtspr SPRN_MAS0,r4 + lwz r4,TLBCAM_MAS1(r3) + mtspr SPRN_MAS1,r4 + PPC_LL r4,TLBCAM_MAS2(r3) + mtspr SPRN_MAS2,r4 + lwz r4,TLBCAM_MAS3(r3) + mtspr SPRN_MAS3,r4 +BEGIN_MMU_FTR_SECTION + lwz r4,TLBCAM_MAS7(r3) + mtspr SPRN_MAS7,r4 +END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) + isync + tlbwe + isync + blr +#endif -- 1.6.0.6
[PATCH V2] fsl_booke: Correct test for MMU_FTR_BIG_PHYS
The code was looking for this in cpu_features, not mmu_features. Fix this. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- Switched to mmu_has_feature. arch/powerpc/mm/fsl_booke_mmu.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index c539472..3260fdf 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -116,7 +116,7 @@ void loadcam_entry(int idx) mtspr(SPRN_MAS2, TLBCAM[idx].MAS2); mtspr(SPRN_MAS3, TLBCAM[idx].MAS3); - if (cur_cpu_spec-cpu_features MMU_FTR_BIG_PHYS) + if (mmu_has_feature(MMU_FTR_BIG_PHYS)) mtspr(SPRN_MAS7, TLBCAM[idx].MAS7); asm volatile(isync;tlbwe;isync : : : memory); @@ -152,7 +152,7 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, TLBCAM[index].MAS3 = (phys MAS3_RPN) | MAS3_SX | MAS3_SR; TLBCAM[index].MAS3 |= ((flags _PAGE_RW) ? MAS3_SW : 0); - if (cur_cpu_spec-cpu_features MMU_FTR_BIG_PHYS) + if (mmu_has_feature(MMU_FTR_BIG_PHYS)) TLBCAM[index].MAS7 = (u64)phys 32; #ifndef CONFIG_KGDB /* want user access for breakpoints */ -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] fsl_booke: Correct test for MMU_FTR_BIG_PHYS
The code was looking for this in cpu_features, not mmu_features. Fix this. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/mm/fsl_booke_mmu.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index c539472..533cae5 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -116,7 +116,7 @@ void loadcam_entry(int idx) mtspr(SPRN_MAS2, TLBCAM[idx].MAS2); mtspr(SPRN_MAS3, TLBCAM[idx].MAS3); - if (cur_cpu_spec-cpu_features MMU_FTR_BIG_PHYS) + if (cur_cpu_spec-mmu_features MMU_FTR_BIG_PHYS) mtspr(SPRN_MAS7, TLBCAM[idx].MAS7); asm volatile(isync;tlbwe;isync : : : memory); @@ -152,7 +152,7 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, TLBCAM[index].MAS3 = (phys MAS3_RPN) | MAS3_SX | MAS3_SR; TLBCAM[index].MAS3 |= ((flags _PAGE_RW) ? MAS3_SW : 0); - if (cur_cpu_spec-cpu_features MMU_FTR_BIG_PHYS) + if (cur_cpu_spec-mmu_features MMU_FTR_BIG_PHYS) TLBCAM[index].MAS7 = (u64)phys 32; #ifndef CONFIG_KGDB /* want user access for breakpoints */ -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v4 05/11] swiotlb: add swiotlb_set_default_size()
On Mar 16, 2010, at 5:08 AM, FUJITA Tomonori wrote: On Tue, 16 Mar 2010 06:58:41 +0100 Albert Herranz albert_herr...@yahoo.es wrote: FUJITA Tomonori wrote: On Fri, 12 Mar 2010 20:12:40 +0100 Albert Herranz albert_herr...@yahoo.es wrote: The current SWIOTLB code uses a default of 64MB for the IO TLB area. This size can be influenced using a kernel command line parameter swiotlb. Unfortunately, the parsing of the kernel command line is done _after_ the swiotlb is initialized on some architectures. This patch adds a new function swiotlb_set_default_size() which can be used before swiotlb_init() to indicate the desired IO TLB area size in bytes. This will be used later to implement a smaller IO TLB on the Nintendo Wii video game console which just comes with 24MB + 64MB of RAM. CC: linuxppc-dev@lists.ozlabs.org CC: linux-ker...@vger.kernel.org CC: x...@kernel.org CC: linux-i...@vger.kernel.org Signed-off-by: Albert Herranz albert_herr...@yahoo.es --- include/linux/swiotlb.h |2 ++ lib/swiotlb.c | 20 2 files changed, 22 insertions(+), 0 deletions(-) Please fix the powerpc swiotlb initialization instead. Calling swiotlb_init() before parsing kernel parameters sounds wrong. Any reasons why you can't fix it? I think that this would be better asked by a PowerPC maintainer. Ben? If this is really a problem the swiotlb late init may be a solution too in this particular case. Hmm, why swiotlb_late_init_with_default_size()? Why can't you initialize swiotlb in mem_init() like this (only compile tested)? Any time before freeing bootmem works for swiotlb. This is an oops in the original patchset - I think it should be fine to move the swiotlb_init later as Fujita suggests, at least for 32-bit powerpc. I just booted this on mpc8641 and everything seems OK. -Becky diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/ setup_32.c index b152de3..8f58986 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -39,7 +39,6 @@ #include asm/serial.h #include asm/udbg.h #include asm/mmu_context.h -#include asm/swiotlb.h #include setup.h @@ -343,11 +342,6 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress(arch: exit, 0x3eab); -#ifdef CONFIG_SWIOTLB - if (ppc_swiotlb_enable) - swiotlb_init(1); -#endif - paging_init(); /* Initialize the MMU context management stuff */ diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/ setup_64.c index 6354739..9143891 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -61,7 +61,6 @@ #include asm/xmon.h #include asm/udbg.h #include asm/kexec.h -#include asm/swiotlb.h #include asm/mmu_context.h #include setup.h @@ -541,11 +540,6 @@ void __init setup_arch(char **cmdline_p) if (ppc_md.setup_arch) ppc_md.setup_arch(); -#ifdef CONFIG_SWIOTLB - if (ppc_swiotlb_enable) - swiotlb_init(1); -#endif - paging_init(); /* Initialize the MMU context management stuff */ diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 311224c..448f972 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -48,6 +48,7 @@ #include asm/sparsemem.h #include asm/vdso.h #include asm/fixmap.h +#include asm/swiotlb.h #include mmu_decl.h @@ -320,6 +321,11 @@ void __init mem_init(void) struct page *page; unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; +#ifdef CONFIG_SWIOTLB + if (ppc_swiotlb_enable) + swiotlb_init(1); +#endif + num_physpages = lmb.memory.size PAGE_SHIFT; high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); -- To unsubscribe from this list: send the line unsubscribe linux- kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Fix DEBUG_HIGHMEM build break from d4515646699
Code was added to mm/higmem.c that depends on several kmap types that powerpc does not support. We add dummy invalid definitions for KM_NMI, KM_NM_PTE, and KM_IRQ_PTE. According to list discussion, this fix should not be needed anymore starting with 2.6.33. The code is commented to this effect so hopefully we will remember to remove this. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/kmap_types.h | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h index b6bac6f..9163695 100644 --- a/arch/powerpc/include/asm/kmap_types.h +++ b/arch/powerpc/include/asm/kmap_types.h @@ -29,5 +29,16 @@ enum km_type { KM_TYPE_NR }; +/* + * This is a temporary build fix that (so they say on lkml) should no longer + * be required after 2.6.33, because of changes planned to the kmap code. + * Let's try to remove this cruft then. + */ +#ifdef CONFIG_DEBUG_HIGHMEM +#define KM_NMI (-1) +#define KM_NMI_PTE (-1) +#define KM_IRQ_PTE (-1) +#endif + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_KMAP_TYPES_H */ -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 1/2] powerpc: rename get_dma_direct_offset get_dma_offset
The former is no longer really accurate with the swiotlb case now a possibility. I also move it into dma-mapping.h - it no longer needs to be in dma.c, and there are about to be some more accessors that should all end up in the same place. A comment is added to indicate that this function is not used in configs where there is no simple dma offset, such as the iommu case. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/dma-mapping.h | 21 ++--- arch/powerpc/kernel/dma.c | 15 --- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index cb2ca41..34b919f 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -26,7 +26,6 @@ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, extern void dma_direct_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); -extern unsigned long get_dma_direct_offset(struct device *dev); #ifdef CONFIG_NOT_COHERENT_CACHE /* @@ -90,6 +89,22 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) dev-archdata.dma_ops = ops; } +/* + * get_dma_offset() + * + * Get the dma offset on configurations where the dma address can be determined + * from the physical address by looking at a simple offset. Direct dma and + * swiotlb use this function, but it is typically not used by implementations + * with an iommu. + */ +static inline unsigned long get_dma_offset(struct device *dev) +{ + if (dev) + return (unsigned long)dev-archdata.dma_data; + + return PCI_DRAM_OFFSET; +} + /* this will be removed soon */ #define flush_write_buffers() @@ -181,12 +196,12 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { - return paddr + get_dma_direct_offset(dev); + return paddr + get_dma_offset(dev); } static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { - return daddr - get_dma_direct_offset(dev); + return daddr - get_dma_offset(dev); } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 21b784d..6215062 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -21,13 +21,6 @@ * default the offset is PCI_DRAM_OFFSET. */ -unsigned long get_dma_direct_offset(struct device *dev) -{ - if (dev) - return (unsigned long)dev-archdata.dma_data; - - return PCI_DRAM_OFFSET; -} void *dma_direct_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) @@ -37,7 +30,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, ret = __dma_alloc_coherent(dev, size, dma_handle, flag); if (ret == NULL) return NULL; - *dma_handle += get_dma_direct_offset(dev); + *dma_handle += get_dma_offset(dev); return ret; #else struct page *page; @@ -51,7 +44,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, return NULL; ret = page_address(page); memset(ret, 0, size); - *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev); + *dma_handle = virt_to_abs(ret) + get_dma_offset(dev); return ret; #endif @@ -75,7 +68,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int i; for_each_sg(sgl, sg, nents, i) { - sg-dma_address = sg_phys(sg) + get_dma_direct_offset(dev); + sg-dma_address = sg_phys(sg) + get_dma_offset(dev); sg-dma_length = sg-length; __dma_sync_page(sg_page(sg), sg-offset, sg-length, direction); } @@ -110,7 +103,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, { BUG_ON(dir == DMA_NONE); __dma_sync_page(page, offset, size, dir); - return page_to_phys(page) + offset + get_dma_direct_offset(dev); + return page_to_phys(page) + offset + get_dma_offset(dev); } static inline void dma_direct_unmap_page(struct device *dev, -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 2/2] powerpc: Change archdata dma_data to a union
Sometimes this is used to hold a simple offset, and sometimes it is used to hold a pointer. This patch changes it to a union containing void * and dma_addr_t. get/set accessors are also provided, because it was getting a bit ugly to get to the actual data. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/device.h| 11 ++- arch/powerpc/include/asm/dma-mapping.h | 10 -- arch/powerpc/include/asm/iommu.h | 10 ++ arch/powerpc/kernel/dma-iommu.c | 16 arch/powerpc/kernel/pci-common.c |2 +- arch/powerpc/kernel/vio.c|2 +- arch/powerpc/platforms/cell/beat_iommu.c |2 +- arch/powerpc/platforms/cell/iommu.c |9 +++-- arch/powerpc/platforms/iseries/iommu.c |2 +- arch/powerpc/platforms/pasemi/iommu.c|2 +- arch/powerpc/platforms/pseries/iommu.c |8 arch/powerpc/sysdev/dart_iommu.c |2 +- 12 files changed, 49 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 67fcd7f..07ca8b5 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -15,7 +15,16 @@ struct dev_archdata { /* DMA operations on that device */ struct dma_map_ops *dma_ops; - void*dma_data; + + /* +* When an iommu is in use, dma_data is used as a ptr to the base of the +* iommu_table. Otherwise, it is a simple numerical offset. +*/ + union { + dma_addr_t dma_offset; + void*iommu_table_base; + } dma_data; + #ifdef CONFIG_SWIOTLB dma_addr_t max_direct_dma_addr; #endif diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 34b919f..e281dae 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -97,14 +97,20 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) * swiotlb use this function, but it is typically not used by implementations * with an iommu. */ -static inline unsigned long get_dma_offset(struct device *dev) +static inline dma_addr_t get_dma_offset(struct device *dev) { if (dev) - return (unsigned long)dev-archdata.dma_data; + return dev-archdata.dma_data.dma_offset; return PCI_DRAM_OFFSET; } +static inline void set_dma_offset(struct device *dev, dma_addr_t off) +{ + if (dev) + dev-archdata.dma_data.dma_offset = off; +} + /* this will be removed soon */ #define flush_write_buffers() diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 7464c0d..edfc980 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -70,6 +70,16 @@ struct iommu_table { struct scatterlist; +static inline void set_iommu_table_base(struct device *dev, void *base) +{ + dev-archdata.dma_data.iommu_table_base = base; +} + +static inline void *get_iommu_table_base(struct device *dev) +{ + return dev-archdata.dma_data.iommu_table_base; +} + /* Frees table for an individual device node */ extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 87ddb3f..37771a5 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -18,7 +18,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - return iommu_alloc_coherent(dev, dev-archdata.dma_data, size, + return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, dma_handle, device_to_mask(dev), flag, dev_to_node(dev)); } @@ -26,7 +26,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, static void dma_iommu_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { - iommu_free_coherent(dev-archdata.dma_data, size, vaddr, dma_handle); + iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); } /* Creates TCEs for a user provided buffer. The user buffer must be @@ -39,8 +39,8 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, enum dma_data_direction direction, struct dma_attrs *attrs) { - return iommu_map_page(dev, dev-archdata.dma_data, page, offset, size, - device_to_mask(dev), direction, attrs); + return iommu_map_page(dev, get_iommu_table_base(dev), page, offset, + size, device_to_mask(dev
[PATCH 1/2] powerpc: rename get_dma_direct_offset get_dma_offset
The former is no longer really accurate with the swiotlb case now a possibility. I also move it into dma-mapping.h - it no longer needs to be in dma.c, and there are about to be some more accessors that should all end up in the same place. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/dma-mapping.h | 13 ++--- arch/powerpc/kernel/dma.c | 15 --- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index cb2ca41..eef4db1 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -26,7 +26,6 @@ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, extern void dma_direct_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); -extern unsigned long get_dma_direct_offset(struct device *dev); #ifdef CONFIG_NOT_COHERENT_CACHE /* @@ -90,6 +89,14 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) dev-archdata.dma_ops = ops; } +static inline unsigned long get_dma_offset(struct device *dev) +{ + if (dev) + return (unsigned long)dev-archdata.dma_data; + + return PCI_DRAM_OFFSET; +} + /* this will be removed soon */ #define flush_write_buffers() @@ -181,12 +188,12 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { - return paddr + get_dma_direct_offset(dev); + return paddr + get_dma_offset(dev); } static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { - return daddr - get_dma_direct_offset(dev); + return daddr - get_dma_offset(dev); } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 21b784d..6215062 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -21,13 +21,6 @@ * default the offset is PCI_DRAM_OFFSET. */ -unsigned long get_dma_direct_offset(struct device *dev) -{ - if (dev) - return (unsigned long)dev-archdata.dma_data; - - return PCI_DRAM_OFFSET; -} void *dma_direct_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) @@ -37,7 +30,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, ret = __dma_alloc_coherent(dev, size, dma_handle, flag); if (ret == NULL) return NULL; - *dma_handle += get_dma_direct_offset(dev); + *dma_handle += get_dma_offset(dev); return ret; #else struct page *page; @@ -51,7 +44,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, return NULL; ret = page_address(page); memset(ret, 0, size); - *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev); + *dma_handle = virt_to_abs(ret) + get_dma_offset(dev); return ret; #endif @@ -75,7 +68,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int i; for_each_sg(sgl, sg, nents, i) { - sg-dma_address = sg_phys(sg) + get_dma_direct_offset(dev); + sg-dma_address = sg_phys(sg) + get_dma_offset(dev); sg-dma_length = sg-length; __dma_sync_page(sg_page(sg), sg-offset, sg-length, direction); } @@ -110,7 +103,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, { BUG_ON(dir == DMA_NONE); __dma_sync_page(page, offset, size, dir); - return page_to_phys(page) + offset + get_dma_direct_offset(dev); + return page_to_phys(page) + offset + get_dma_offset(dev); } static inline void dma_direct_unmap_page(struct device *dev, -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/2] powerpc: Change archdata dma_data to a union
Sometimes this is used to hold a simple offset, and sometimes it is used to hold a pointer. This patch changes it to a union containing void * and dma_addr_t. get/set accessors are also provided, because it was getting a bit ugly to get to the actual data. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/device.h| 11 ++- arch/powerpc/include/asm/dma-mapping.h | 10 -- arch/powerpc/include/asm/iommu.h | 10 ++ arch/powerpc/kernel/dma-iommu.c | 16 arch/powerpc/kernel/pci-common.c |2 +- arch/powerpc/kernel/vio.c|2 +- arch/powerpc/platforms/cell/beat_iommu.c |2 +- arch/powerpc/platforms/cell/iommu.c |9 +++-- arch/powerpc/platforms/iseries/iommu.c |2 +- arch/powerpc/platforms/pasemi/iommu.c|2 +- arch/powerpc/platforms/pseries/iommu.c |8 arch/powerpc/sysdev/dart_iommu.c |2 +- 12 files changed, 49 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 67fcd7f..07ca8b5 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -15,7 +15,16 @@ struct dev_archdata { /* DMA operations on that device */ struct dma_map_ops *dma_ops; - void*dma_data; + + /* +* When an iommu is in use, dma_data is used as a ptr to the base of the +* iommu_table. Otherwise, it is a simple numerical offset. +*/ + union { + dma_addr_t dma_offset; + void*iommu_table_base; + } dma_data; + #ifdef CONFIG_SWIOTLB dma_addr_t max_direct_dma_addr; #endif diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index eef4db1..e9f4fe9 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -89,14 +89,20 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) dev-archdata.dma_ops = ops; } -static inline unsigned long get_dma_offset(struct device *dev) +static inline dma_addr_t get_dma_offset(struct device *dev) { if (dev) - return (unsigned long)dev-archdata.dma_data; + return dev-archdata.dma_data.dma_offset; return PCI_DRAM_OFFSET; } +static inline void set_dma_offset(struct device *dev, dma_addr_t off) +{ + if (dev) + dev-archdata.dma_data.dma_offset = off; +} + /* this will be removed soon */ #define flush_write_buffers() diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 7464c0d..edfc980 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -70,6 +70,16 @@ struct iommu_table { struct scatterlist; +static inline void set_iommu_table_base(struct device *dev, void *base) +{ + dev-archdata.dma_data.iommu_table_base = base; +} + +static inline void *get_iommu_table_base(struct device *dev) +{ + return dev-archdata.dma_data.iommu_table_base; +} + /* Frees table for an individual device node */ extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 87ddb3f..37771a5 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -18,7 +18,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - return iommu_alloc_coherent(dev, dev-archdata.dma_data, size, + return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, dma_handle, device_to_mask(dev), flag, dev_to_node(dev)); } @@ -26,7 +26,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, static void dma_iommu_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { - iommu_free_coherent(dev-archdata.dma_data, size, vaddr, dma_handle); + iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); } /* Creates TCEs for a user provided buffer. The user buffer must be @@ -39,8 +39,8 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, enum dma_data_direction direction, struct dma_attrs *attrs) { - return iommu_map_page(dev, dev-archdata.dma_data, page, offset, size, - device_to_mask(dev), direction, attrs); + return iommu_map_page(dev, get_iommu_table_base(dev), page, offset, + size, device_to_mask(dev), direction, attrs); } @@ -48,7 +48,7 @@ static void
Re: [PATCH] powerpc: Change archdata dma_data type to dma_addr_t
On Aug 26, 2009, at 9:08 AM, Michael Ellerman wrote: On Wed, 2009-08-26 at 22:29 +1000, Benjamin Herrenschmidt wrote: On Mon, 2009-08-24 at 21:48 +0200, Christoph Hellwig wrote: On Mon, Aug 24, 2009 at 11:17:14AM -0500, Becky Bruce wrote: Previously, this was specified as a void *, but that's not large enough on 32-bit systems with 36-bit physical addressing support. Change the type to dma_addr_t so it will scale based on the size of a dma address. This looks extreml ugly to me. It seems like the typical use is to store a pointer to a structure. So what about making the direct dma case follow that general scheme instead? E.g. declare a struct direct_dma_data { dma_addr_t direct_dma_offset; }; and have one normal instace of it, and one per weird cell device. Right, but we want to avoid a structure for the classic case of 32- bit systems with no iommu... I wouldn't mind doing a union here. That might be best, the patch as it stands is a horrible mess of casts. Let's be fair - the code before was a horrible mess of casts, I've just moved them :) Stashing a dma_addr_t into a void * is sort of gross, but storing a pointer to some struct (a void *) in a dma_addr_t is _really_ gross :) Both are revolting (and storing a dma_addr_t into a void * is really gross when the void * is smaller than the dma_addr_t!!). A union might not be a bad idea, though. I'll look at doing that instead. -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Name xpn x fields in HW pte format
Previously, the 36-bit code was using these bits, but they had never been named in the pte format definition. This patch just gives those fields their proper names and adds a comment that they are only present on some processors. There is no functional code change. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/mmu-hash32.h | 10 +++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/mmu-hash32.h b/arch/powerpc/include/asm/mmu-hash32.h index 382fc68..16f513e 100644 --- a/arch/powerpc/include/asm/mmu-hash32.h +++ b/arch/powerpc/include/asm/mmu-hash32.h @@ -55,21 +55,25 @@ struct ppc_bat { #ifndef __ASSEMBLY__ -/* Hardware Page Table Entry */ +/* + * Hardware Page Table Entry + * Note that the xpn and x bitfields are used only by processors that + * support extended addressing; otherwise, those bits are reserved. + */ struct hash_pte { unsigned long v:1; /* Entry is valid */ unsigned long vsid:24; /* Virtual segment identifier */ unsigned long h:1; /* Hash algorithm indicator */ unsigned long api:6;/* Abbreviated page index */ unsigned long rpn:20; /* Real (physical) page number */ - unsigned long:3;/* Unused */ + unsigned long xpn:3;/* Real page number bits 0-2, optional */ unsigned long r:1; /* Referenced */ unsigned long c:1; /* Changed */ unsigned long w:1; /* Write-thru cache mode */ unsigned long i:1; /* Cache inhibited */ unsigned long m:1; /* Memory coherence */ unsigned long g:1; /* Guarded */ - unsigned long :1; /* Unused */ + unsigned long x:1; /* Real page number bit 3, optional */ unsigned long pp:2; /* Page protection */ }; -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Change archdata dma_data type to dma_addr_t
Previously, this was specified as a void *, but that's not large enough on 32-bit systems with 36-bit physical addressing support. Change the type to dma_addr_t so it will scale based on the size of a dma address. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/device.h|2 +- arch/powerpc/include/asm/dma-mapping.h |2 +- arch/powerpc/kernel/dma-iommu.c | 21 + arch/powerpc/kernel/dma.c|6 +++--- arch/powerpc/kernel/pci-common.c |2 +- arch/powerpc/kernel/vio.c|3 ++- arch/powerpc/platforms/cell/beat_iommu.c |2 +- arch/powerpc/platforms/cell/iommu.c |6 +++--- arch/powerpc/platforms/iseries/iommu.c |2 +- arch/powerpc/platforms/pasemi/iommu.c|2 +- arch/powerpc/platforms/pseries/iommu.c | 11 +++ arch/powerpc/sysdev/dart_iommu.c |2 +- 12 files changed, 35 insertions(+), 26 deletions(-) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 67fcd7f..07818ae 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -15,7 +15,7 @@ struct dev_archdata { /* DMA operations on that device */ struct dma_map_ops *dma_ops; - void*dma_data; + dma_addr_t dma_data; #ifdef CONFIG_SWIOTLB dma_addr_t max_direct_dma_addr; #endif diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index cb2ca41..cf65ebb 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -26,7 +26,7 @@ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, extern void dma_direct_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); -extern unsigned long get_dma_direct_offset(struct device *dev); +extern dma_addr_t get_dma_direct_offset(struct device *dev); #ifdef CONFIG_NOT_COHERENT_CACHE /* diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 87ddb3f..13eef19 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -11,6 +11,11 @@ * Generic iommu implementation */ +static inline struct iommu_table *get_iommu_table_base(struct device *dev) +{ + return (struct iommu_table *)dev-archdata.dma_data; +} + /* Allocates a contiguous real buffer and creates mappings over it. * Returns the virtual address of the buffer and sets dma_handle * to the dma address (mapping) of the first page. @@ -18,7 +23,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - return iommu_alloc_coherent(dev, dev-archdata.dma_data, size, + return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, dma_handle, device_to_mask(dev), flag, dev_to_node(dev)); } @@ -26,7 +31,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, static void dma_iommu_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { - iommu_free_coherent(dev-archdata.dma_data, size, vaddr, dma_handle); + iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); } /* Creates TCEs for a user provided buffer. The user buffer must be @@ -39,8 +44,8 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, enum dma_data_direction direction, struct dma_attrs *attrs) { - return iommu_map_page(dev, dev-archdata.dma_data, page, offset, size, - device_to_mask(dev), direction, attrs); + return iommu_map_page(dev, get_iommu_table_base(dev), page, offset, + size, device_to_mask(dev), direction, attrs); } @@ -48,7 +53,7 @@ static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) { - iommu_unmap_page(dev-archdata.dma_data, dma_handle, size, direction, + iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction, attrs); } @@ -57,7 +62,7 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction, struct dma_attrs *attrs) { - return iommu_map_sg(dev, dev-archdata.dma_data, sglist, nelems, + return iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems, device_to_mask(dev), direction, attrs
Re: [PATCH/RFC] powerpc/mm: Cleanup handling of execute permission
On Aug 18, 2009, at 5:33 PM, Benjamin Herrenschmidt wrote: On Tue, 2009-08-18 at 16:56 -0400, Josh Boyer wrote: On Fri, Aug 14, 2009 at 05:39:42PM -0500, Becky Bruce wrote: Ben, This breaks the boot on 8572. I don't know why yet (and I'm probably not going to figure it out before I go home, because, frankly, it's late on a Friday afternoon and I need a glass of wine or, perhaps, a beer). Kumar and I will poke into this more and let you know what we find out - in the meantime, if you have any brilliant flashes, pony up! I tested this on a 440EPx NFS rootfs boot too. It doesn't cause init itself to crap out with a SIGILL like Becky's board, but it does do weird things and cause a SIGILL elsewhere during my boot. Reverting this patch from your testing branch allows things to work just fine. Becky found my thinko, I'll send a new patch later today. Ben, FYI, I pulled your updated test branch this morning, booted, and did a full LTP run on 8572. The results are consistent with the baseline I have, so it looks like the issue is properly fixed. -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Poll: Rebasing of powerpc-next
On Aug 15, 2009, at 5:20 PM, Benjamin Herrenschmidt wrote: Hi ! I'd like to rebase powerpc-next ... a few bugs have been found that it would be nice to fix in the original patch rather than introducing a bisection breakage, and Kumar also just noticed a potentially misleading error in a commit message from his tree. So who is not ok with me doing that tomorrow or tuesday ? Sounds like a swell idea to me I hate bisection breakage. -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Fix __tlb_remove_tlb_entry for PPC_STD_MMU_32
Ben's recent patches are missing the CONFIG_ prefix to PPC_STD_MMU_32, which results in not properly flushing hash entries. On 8641, this showed up as a platform that would boot, but deny logins. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/tlb.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h index 5db9910..e2b428b 100644 --- a/arch/powerpc/include/asm/tlb.h +++ b/arch/powerpc/include/asm/tlb.h @@ -39,7 +39,7 @@ extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long address) { -#ifdef PPC_STD_MMU_32 +#ifdef CONFIG_PPC_STD_MMU_32 if (pte_val(*ptep) _PAGE_HASHPTE) flush_hash_entry(tlb-mm, ptep, address); #endif -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH/RFC] powerpc/mm: Cleanup handling of execute permission
Ben, This breaks the boot on 8572. I don't know why yet (and I'm probably not going to figure it out before I go home, because, frankly, it's late on a Friday afternoon and I need a glass of wine or, perhaps, a beer). Kumar and I will poke into this more and let you know what we find out - in the meantime, if you have any brilliant flashes, pony up! -Becky On Jul 28, 2009, at 2:32 AM, Benjamin Herrenschmidt wrote: This is an attempt at cleaning up a bit the way we handle execute permission on powerpc (again !). _PAGE_HWEXEC is gone, _PAGE_EXEC is now only defined by CPUs that can do something with it, and the myriad of #ifdef's in the I$/D$ coherency code is reduced to 2 cases that hopefully should cover everything. The logic on BookE is a little bit different than what it was though not by much. Since now, _PAGE_EXEC will be set by the generic code for executable pages, we need to filter out if they are unclean and recover it. However, I don't expect the code to be more bloated than it already was in that area due to that change. Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- I could boast that this brings proper enforcing of per-page execute permissions to all BookE and 40x but in fact, we've had that now for some time as a side effect of my previous rework in that area (and I didn't even know it :-) We would only enable execute permission if the page was cache clean and we would only cache clean it if we took and exec fault. Since we now enforce that the later only work if VM_EXEC is part of the VMA flags, we de-fact already enforce per-page execute permissions... Unless I missed something Kumar, Becky, I could really use some review here :-) I tested on 440 and that's about it, I'll do more testing tomorrow. Basically, I _think_ we already enforce execute permission fully on all BookE today (test case welcome) but at least after that patch it becomes more obvious what is happening in the code. arch/powerpc/include/asm/pgtable-ppc32.h |7 +- arch/powerpc/include/asm/pgtable-ppc64.h |3 +- arch/powerpc/include/asm/pte-40x.h |2 +- arch/powerpc/include/asm/pte-44x.h |2 +- arch/powerpc/include/asm/pte-8xx.h |1 - arch/powerpc/include/asm/pte-book3e.h| 13 ++- arch/powerpc/include/asm/pte-common.h| 22 ++-- arch/powerpc/include/asm/pte-fsl-booke.h |2 +- arch/powerpc/include/asm/pte-hash32.h|1 - arch/powerpc/kernel/head_44x.S |2 +- arch/powerpc/kernel/head_fsl_booke.S |4 +- arch/powerpc/mm/40x_mmu.c|4 +- arch/powerpc/mm/pgtable.c| 148 +++ +-- arch/powerpc/mm/pgtable_32.c |2 +- arch/powerpc/mm/tlb_low_64e.S|4 +- 15 files changed, 132 insertions(+), 85 deletions(-) diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/ include/asm/pgtable-ppc32.h index c9ff9d7..f2c52e2 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h @@ -186,7 +186,7 @@ static inline unsigned long pte_update(pte_t *p, #endif /* !PTE_ATOMIC_UPDATES */ #ifdef CONFIG_44x - if ((old _PAGE_USER) (old _PAGE_HWEXEC)) + if ((old _PAGE_USER) (old _PAGE_EXEC)) icache_44x_need_flush = 1; #endif return old; @@ -217,7 +217,7 @@ static inline unsigned long long pte_update(pte_t *p, #endif /* !PTE_ATOMIC_UPDATES */ #ifdef CONFIG_44x - if ((old _PAGE_USER) (old _PAGE_HWEXEC)) + if ((old _PAGE_USER) (old _PAGE_EXEC)) icache_44x_need_flush = 1; #endif return old; @@ -267,8 +267,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) { unsigned long bits = pte_val(entry) - (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | -_PAGE_HWEXEC | _PAGE_EXEC); + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); pte_update(ptep, 0, bits); } diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/ include/asm/pgtable-ppc64.h index 200ec2d..806abe7 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -313,8 +313,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) { unsigned long bits = pte_val(entry) - (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | -_PAGE_EXEC | _PAGE_HWEXEC); + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); #ifdef PTE_ATOMIC_UPDATES unsigned long old, tmp; diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/ include/asm/pte-40x.h index 07630fa..6c3e1f4 100644 --- a/arch/powerpc/include/asm/pte-40x.h +++ b/arch/powerpc/include/asm/pte-40x.h @@ -46,7 +46,7 @@ #define _PAGE_RW0x040 /* software:
Re: [PATCH 1/5] powerpc: remove addr_needs_map in struct dma_mapping_ops
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote: This patch adds max_direct_dma_addr to struct dev_archdata to remove addr_needs_map in struct dma_mapping_ops. It also converts dma_capable() to use max_direct_dma_addr. max_direct_dma_addr is initialized in pci_dma_dev_setup_swiotlb(), called via ppc_md.pci_dma_dev_setup hook. For further information: http://marc.info/?t=12471906021r=1w=2 Signed-off-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp Acked-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/device.h |3 ++ arch/powerpc/include/asm/dma-mapping.h |8 +++--- arch/powerpc/include/asm/swiotlb.h |5 +-- arch/powerpc/kernel/dma-swiotlb.c | 36 ++ + arch/powerpc/platforms/85xx/mpc8536_ds.c |1 + arch/powerpc/platforms/85xx/mpc85xx_ds.c |1 + arch/powerpc/platforms/85xx/mpc85xx_mds.c |1 + arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |1 + 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/ include/asm/device.h index 7d2277c..0086f8d 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -16,6 +16,9 @@ struct dev_archdata { /* DMA operations on that device */ struct dma_mapping_ops *dma_ops; void*dma_data; +#ifdef CONFIG_SWIOTLB + dma_addr_t max_direct_dma_addr; +#endif }; static inline void dev_archdata_set_node(struct dev_archdata *ad, diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/ include/asm/dma-mapping.h index 0c34371..1765c37 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -87,8 +87,6 @@ struct dma_mapping_ops { dma_addr_t dma_address, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs); - int (*addr_needs_map)(struct device *dev, dma_addr_t addr, - size_t size); #ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS void(*sync_single_range_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, @@ -426,10 +424,12 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) { - struct dma_mapping_ops *ops = get_dma_ops(dev); +#ifdef CONFIG_SWIOTLB + struct dev_archdata *sd = dev-archdata; - if (ops-addr_needs_map ops-addr_needs_map(dev, addr, size)) + if (sd-max_direct_dma_addr addr + size sd- max_direct_dma_addr) return 0; +#endif if (!dev-dma_mask) return 0; diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/ include/asm/swiotlb.h index 30891d6..31e0e43 100644 --- a/arch/powerpc/include/asm/swiotlb.h +++ b/arch/powerpc/include/asm/swiotlb.h @@ -16,12 +16,11 @@ extern struct dma_mapping_ops swiotlb_dma_ops; extern struct dma_mapping_ops swiotlb_pci_dma_ops; -int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t, - size_t size); - static inline void dma_mark_clean(void *addr, size_t size) {} extern unsigned int ppc_swiotlb_enable; int __init swiotlb_setup_bus_notifier(void); +extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev); + #endif /* __ASM_SWIOTLB_H */ diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/ dma-swiotlb.c index e8a57de..c9f6a30 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -25,26 +25,6 @@ int swiotlb __read_mostly; unsigned int ppc_swiotlb_enable; /* - * Determine if an address is reachable by a pci device, or if we must bounce. - */ -static int -swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) -{ - dma_addr_t max; - struct pci_controller *hose; - struct pci_dev *pdev = to_pci_dev(hwdev); - - hose = pci_bus_to_host(pdev-bus); - max = hose-dma_window_base_cur + hose-dma_window_size; - - /* check that we're within mapped pci window space */ - if ((addr + size max) | (addr hose-dma_window_base_cur)) - return 1; - - return 0; -} - -/* * At the moment, all platforms that use this code only require * swiotlb to be used if we're operating on HIGHMEM. Since * we don't ever call anything other than map_sg, unmap_sg, @@ -73,22 +53,36 @@ struct dma_mapping_ops swiotlb_pci_dma_ops = { .dma_supported = swiotlb_dma_supported, .map_page = swiotlb_map_page, .unmap_page = swiotlb_unmap_page, - .addr_needs_map = swiotlb_pci_addr_needs_map, .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, .sync_single_range_for_device = swiotlb_sync_single_range_for_device
Re: [PATCH 2/5] powerpc: remove swiotlb_pci_dma_ops
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote: Now swiotlb_pci_dma_ops is identical to swiotlb_dma_ops; we can use swiotlb_dma_ops with any devices. This removes swiotlb_pci_dma_ops. Signed-off-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp Acked-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/swiotlb.h |1 - arch/powerpc/kernel/dma-swiotlb.c | 14 -- arch/powerpc/platforms/85xx/mpc8536_ds.c |2 +- arch/powerpc/platforms/85xx/mpc85xx_ds.c |2 +- arch/powerpc/platforms/85xx/mpc85xx_mds.c |2 +- arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |2 +- 6 files changed, 4 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/ include/asm/swiotlb.h index 31e0e43..21ce0a3 100644 --- a/arch/powerpc/include/asm/swiotlb.h +++ b/arch/powerpc/include/asm/swiotlb.h @@ -14,7 +14,6 @@ #include linux/swiotlb.h extern struct dma_mapping_ops swiotlb_dma_ops; -extern struct dma_mapping_ops swiotlb_pci_dma_ops; static inline void dma_mark_clean(void *addr, size_t size) {} diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/ dma-swiotlb.c index c9f6a30..ca141e1 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -45,20 +45,6 @@ struct dma_mapping_ops swiotlb_dma_ops = { .sync_sg_for_device = swiotlb_sync_sg_for_device }; -struct dma_mapping_ops swiotlb_pci_dma_ops = { - .alloc_coherent = dma_direct_alloc_coherent, - .free_coherent = dma_direct_free_coherent, - .map_sg = swiotlb_map_sg_attrs, - .unmap_sg = swiotlb_unmap_sg_attrs, - .dma_supported = swiotlb_dma_supported, - .map_page = swiotlb_map_page, - .unmap_page = swiotlb_unmap_page, - .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, - .sync_single_range_for_device = swiotlb_sync_single_range_for_device, - .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, - .sync_sg_for_device = swiotlb_sync_sg_for_device -}; - void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev) { struct pci_controller *hose; diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/ platforms/85xx/mpc8536_ds.c index bf052c0..004b7d3 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -96,7 +96,7 @@ static void __init mpc8536_ds_setup_arch(void) #ifdef CONFIG_SWIOTLB if (lmb_end_of_DRAM() max) { ppc_swiotlb_enable = 1; - set_pci_dma_ops(swiotlb_pci_dma_ops); + set_pci_dma_ops(swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; } #endif diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/ platforms/85xx/mpc85xx_ds.c index c6f92cc..544011a 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -192,7 +192,7 @@ static void __init mpc85xx_ds_setup_arch(void) #ifdef CONFIG_SWIOTLB if (lmb_end_of_DRAM() max) { ppc_swiotlb_enable = 1; - set_pci_dma_ops(swiotlb_pci_dma_ops); + set_pci_dma_ops(swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; } #endif diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/ powerpc/platforms/85xx/mpc85xx_mds.c index 8b8e5f9..c4961ed 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -241,7 +241,7 @@ static void __init mpc85xx_mds_setup_arch(void) #ifdef CONFIG_SWIOTLB if (lmb_end_of_DRAM() max) { ppc_swiotlb_enable = 1; - set_pci_dma_ops(swiotlb_pci_dma_ops); + set_pci_dma_ops(swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; } #endif diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/ powerpc/platforms/86xx/mpc86xx_hpcn.c index 8032301..2aa69a6 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -105,7 +105,7 @@ mpc86xx_hpcn_setup_arch(void) #ifdef CONFIG_SWIOTLB if (lmb_end_of_DRAM() max) { ppc_swiotlb_enable = 1; - set_pci_dma_ops(swiotlb_pci_dma_ops); + set_pci_dma_ops(swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; } #endif -- 1.6.0.6 -- To unsubscribe from this list: send the line unsubscribe linux- kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 3/5] add set_dma_mask hook to struct dma_map_ops
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote: POWERPC needs this hook. SPARC could use it too. Signed-off-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp Acked-by: Becky Bruce bec...@kernel.crashing.org --- include/linux/dma-mapping.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index c0f6c3c..91b7618 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -58,6 +58,7 @@ struct dma_map_ops { enum dma_data_direction dir); int (*mapping_error)(struct device *dev, dma_addr_t dma_addr); int (*dma_supported)(struct device *dev, u64 mask); + int (*set_dma_mask)(struct device *dev, u64 mask); int is_phys; }; -- 1.6.0.6 -- To unsubscribe from this list: send the line unsubscribe linux- kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 4/5] powerpc: use dma_map_ops struct
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote: This converts uses dma_map_ops struct (in include/linux/dma-mapping.h) instead of POWERPC homegrown dma_mapping_ops. Signed-off-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp Acked-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/device.h |4 +- arch/powerpc/include/asm/dma-mapping.h | 84 +++ +--- arch/powerpc/include/asm/pci.h |4 +- arch/powerpc/include/asm/swiotlb.h |2 +- arch/powerpc/kernel/dma-iommu.c |2 +- arch/powerpc/kernel/dma-swiotlb.c |2 +- arch/powerpc/kernel/dma.c |2 +- arch/powerpc/kernel/ibmebus.c |2 +- arch/powerpc/kernel/pci-common.c|6 +- arch/powerpc/kernel/vio.c |2 +- arch/powerpc/platforms/cell/iommu.c |2 +- arch/powerpc/platforms/ps3/system-bus.c |4 +- 12 files changed, 37 insertions(+), 79 deletions(-) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/ include/asm/device.h index 0086f8d..67fcd7f 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -6,7 +6,7 @@ #ifndef _ASM_POWERPC_DEVICE_H #define _ASM_POWERPC_DEVICE_H -struct dma_mapping_ops; +struct dma_map_ops; struct device_node; struct dev_archdata { @@ -14,7 +14,7 @@ struct dev_archdata { struct device_node *of_node; /* DMA operations on that device */ - struct dma_mapping_ops *dma_ops; + struct dma_map_ops *dma_ops; void*dma_data; #ifdef CONFIG_SWIOTLB dma_addr_t max_direct_dma_addr; diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/ include/asm/dma-mapping.h index 1765c37..8ca2b51 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -64,56 +64,14 @@ static inline unsigned long device_to_mask(struct device *dev) } /* - * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO - */ -struct dma_mapping_ops { - void * (*alloc_coherent)(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag); - void(*free_coherent)(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle); - int (*map_sg)(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - struct dma_attrs *attrs); - void(*unmap_sg)(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - struct dma_attrs *attrs); - int (*dma_supported)(struct device *dev, u64 mask); - int (*set_dma_mask)(struct device *dev, u64 dma_mask); - dma_addr_t (*map_page)(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs); - void(*unmap_page)(struct device *dev, - dma_addr_t dma_address, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs); -#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS - void(*sync_single_range_for_cpu)(struct device *hwdev, - dma_addr_t dma_handle, unsigned long offset, - 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, - enum dma_data_direction direction); - void(*sync_sg_for_cpu)(struct device *hwdev, - struct scatterlist *sg, int nelems, - enum dma_data_direction direction); - void(*sync_sg_for_device)(struct device *hwdev, - struct scatterlist *sg, int nelems, - enum dma_data_direction direction); -#endif -}; - -/* * Available generic sets of operations */ #ifdef CONFIG_PPC64 -extern struct dma_mapping_ops dma_iommu_ops; +extern struct dma_map_ops dma_iommu_ops; #endif -extern struct dma_mapping_ops dma_direct_ops; +extern struct dma_map_ops dma_direct_ops; -static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) +static inline struct dma_map_ops *get_dma_ops(struct device *dev) { /* We don't handle the NULL dev case for ISA for now. We could * do it via an out of line call but it is not needed for now. The @@ -126,14
Re: [PATCH 5/5] powerpc: use asm-generic/dma-mapping-common.h
On Jul 23, 2009, at 10:24 PM, FUJITA Tomonori wrote: Signed-off-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp Fujita, Since you're removing all the uses of it, you should probably remove PPC_NEED_DMA_SYNC_OPS from arch/powerpc/Kconfig: diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0603b6c..fb3f4ff 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -307,10 +307,6 @@ config SWIOTLB platforms where the size of a physical address is larger than the bus address. Not all platforms support this. -config PPC_NEED_DMA_SYNC_OPS - def_bool y - depends on (NOT_COHERENT_CACHE || SWIOTLB) - config HOTPLUG_CPU bool Support for enabling/disabling CPUs depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || PPC_PMAC) Otherwise, this looks good to me. I also think you want an ACK from Ben - making this switch does add slight overhead to platforms that don't need sync ops, but I think it's worth it. IIRC, it was Ben who asked for the optimization of NEED_DMA_SYNC_OPS, so I'd like him to weigh in here. Cheers, Becky --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/dma-mapping.h | 242 +--- 2 files changed, 7 insertions(+), 237 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d00131c..0603b6c 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -120,7 +120,7 @@ config PPC select HAVE_KRETPROBES select HAVE_ARCH_TRACEHOOK select HAVE_LMB - select HAVE_DMA_ATTRS if PPC64 + select HAVE_DMA_ATTRS select USE_GENERIC_SMP_HELPERS if SMP select HAVE_OPROFILE select HAVE_SYSCALL_WRAPPERS if PPC64 diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/ include/asm/dma-mapping.h index 8ca2b51..91217e4 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -14,6 +14,7 @@ #include linux/mm.h #include linux/scatterlist.h #include linux/dma-attrs.h +#include linux/dma-debug.h #include asm/io.h #include asm/swiotlb.h @@ -89,6 +90,11 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) dev-archdata.dma_ops = ops; } +/* this will be removed soon */ +#define flush_write_buffers() + +#include asm-generic/dma-mapping-common.h + static inline int dma_supported(struct device *dev, u64 mask) { struct dma_map_ops *dma_ops = get_dma_ops(dev); @@ -117,87 +123,6 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } -/* - * map_/unmap_single actually call through to map/unmap_page now that all the - * dma_map_ops have been converted over. We just have to get the page and - * offset to pass through to map_page - */ -static inline dma_addr_t dma_map_single_attrs(struct device *dev, - void *cpu_addr, - size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) -{ - struct dma_map_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - return dma_ops-map_page(dev, virt_to_page(cpu_addr), -(unsigned long)cpu_addr % PAGE_SIZE, size, -direction, attrs); -} - -static inline void dma_unmap_single_attrs(struct device *dev, - dma_addr_t dma_addr, - size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) -{ - struct dma_map_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - dma_ops-unmap_page(dev, dma_addr, size, direction, attrs); -} - -static inline dma_addr_t dma_map_page_attrs(struct device *dev, - struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) -{ - struct dma_map_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - return dma_ops-map_page(dev, page, offset, size, direction, attrs); -} - -static inline void dma_unmap_page_attrs(struct device *dev, - dma_addr_t dma_address, - size_t size, - enum dma_data_direction direction, - struct dma_attrs *attrs) -{ - struct dma_map_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - dma_ops-unmap_page(dev, dma_address, size, direction, attrs); -} - -static inline int dma_map_sg_attrs(struct device
Re: [00/15] swiotlb cleanup
On Jul 13, 2009, at 10:13 PM, Becky Bruce wrote: On Jul 10, 2009, at 12:12 AM, Ingo Molnar wrote: * FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp wrote: - removes unused (and unnecessary) hooks in swiotlb. - adds dma_capable() and converts swiotlb to use it. It can be used to know if a memory area is dma capable or not. I added is_buffer_dma_capable() for the same purpose long ago but it turned out that the function doesn't work on POWERPC. This can be applied cleanly to linux-next, -mm, and mainline. This patchset touches multiple architectures (ia64, powerpc, x86) so I guess that -mm is appropriate for this patchset (I don't care much what tree would merge this though). This is tested on x86 but only compile tested on POWERPC and IA64. Thanks, = arch/ia64/include/asm/dma-mapping.h| 18 ++ arch/powerpc/include/asm/dma-mapping.h | 23 +++ arch/powerpc/kernel/dma-swiotlb.c | 48 +--- arch/x86/include/asm/dma-mapping.h | 18 ++ arch/x86/kernel/pci-dma.c |2 +- arch/x86/kernel/pci-gart_64.c |5 +- arch/x86/kernel/pci-nommu.c|2 +- arch/x86/kernel/pci-swiotlb.c | 25 include/linux/dma-mapping.h|5 -- include/linux/swiotlb.h| 11 lib/swiotlb.c | 102 +--- 11 files changed, 92 insertions(+), 167 deletions(-) Hm, the functions and facilities you remove here were added as part of preparatory patches for Xen guest support. You were aware of them, you were involved in discussions about those aspects with Ian and Jeremy but still you chose not to Cc: either of them and you failed to address that aspect in the changelogs. I'd like the Xen code to become cleaner more than anyone else here i guess, but patch submission methods like this are not really helpful. A far better method is to be open about such disagreements, to declare them, to Cc: everyone who disagrees, and to line out the arguments in the changelogs as well - instead of just curtly declaring those APIs 'unused' and failing to Cc: involved parties. Alas, on the technical level the cleanups themselves look mostly fine to me. Ian, Jeremy, the changes will alter Xen's use of swiotlb, but can the Xen side still live with these new methods - in particular is dma_capable() sufficient as a mechanism and can the Xen side filter out DMA allocations to make them physically continuous? Ben, Tony, Becky, any objections wrt. the PowerPC / IA64 impact? If everyone agrees i can apply them to the IOMMU tree, test it and push it out to -next, etc. Ingo, With the exception of the patch I commented on, I think these look OK from the powerpc point of view. I've successfully booted one of my test platforms with the entire series applied and will run some more extensive (i.e. not Whee! A prompt!) tests tomorrow. Well, I am still testing. I've observed one unexpected LTP testcase failure with these patches applied, but so far have been unable to reproduce it. So these patches are probably OK, but I will look into this some more next week. -Becky -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: removing addr_needs_map in struct dma_mapping_ops
On Jul 13, 2009, at 7:49 PM, FUJITA Tomonori wrote: On Mon, 13 Jul 2009 16:50:43 -0500 Becky Bruce bec...@kernel.crashing.org wrote: talked about defining something like struct dma_data. Then we could struct dev_archdata { ... struct dma_data *ddata; }; or struct dev_archdata { ... struct dma_data ddata; }; struct dma_data needs dma_direct_offset, iommu_table, dma_base, and dma_window_size, anything else? IIRC, what we had talked about was simpler - we talked about changing the current dev_archdata from this: struct dev_archdata { struct device_node *of_node; struct dma_mapping_ops *dma_ops; void*dma_data; }; to this: struct dev_archdata { struct device_node *of_node; struct dma_mapping_ops *dma_ops; unsigned long long dma_data; #ifdef CONFIG_SWIOTLB dma_addr_t max_direct_dma_addr; #endif }; Where max_direct_dma_addr is the address beyond which a specific device must use swiotlb, and dma_data is the offset like it is now (but wider on 32-bit systems than void *). I believe Ben had mentioned wanting to make the max_direct_dma_addr part conditional so we don't bloat archdata on platforms that don't ever bounce. Only maximum address is enough? The minimum (dma_window_base_cur in swiotlb_pci_addr_needs_map) is not necessary? The change to the type of dma_data is actually in preparation for an optimization I have planned for 64-bit PCI devices (and which probably requires more discussion), so that doesn't need to happen now - just leave it as a void *, and I can post a followup patch. Let me know if I can help or do any testing - I've been meaning to look into switching to dma_map_ops for a while now but it hasn't managed to pop off my todo stack. Ok, how about this? I'm not familiar with POWERPC so I might misunderstand something. This is close, but it misses the setup for non-pci devices. We have a bus notifier that we use to set up archdata for those devices - ppc_swiotlb_bus_notify() in arch/powerpc/kernel/dma-swiotlb.c. It won't cause breakage to not have this set up, because those will fall through to the dma_capable(), but I think we should initialize it anyway (who knows what it will end up used for later). diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/ include/asm/device.h index 7d2277c..0086f8d 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -16,6 +16,9 @@ struct dev_archdata { /* DMA operations on that device */ struct dma_mapping_ops *dma_ops; void*dma_data; +#ifdef CONFIG_SWIOTLB + dma_addr_t max_direct_dma_addr; +#endif }; static inline void dev_archdata_set_node(struct dev_archdata *ad, diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/ include/asm/swiotlb.h index 30891d6..b23a4f1 100644 --- a/arch/powerpc/include/asm/swiotlb.h +++ b/arch/powerpc/include/asm/swiotlb.h @@ -24,4 +24,6 @@ static inline void dma_mark_clean(void *addr, size_t size) {} extern unsigned int ppc_swiotlb_enable; int __init swiotlb_setup_bus_notifier(void); +extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev); + #endif /* __ASM_SWIOTLB_H */ diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/ dma-swiotlb.c index 68ccf11..e21359e 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -56,39 +56,16 @@ swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) { struct dma_mapping_ops *dma_ops = get_dma_ops(hwdev); + struct dev_archdata *sd = hwdev-archdata; BUG_ON(!dma_ops); - return dma_ops-addr_needs_map(hwdev, addr, size); -} You can get rid of the dma_ops stuff here it's no longer needed. -/* - * Determine if an address is reachable by a pci device, or if we must bounce. - */ -static int -swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) -{ - u64 mask = dma_get_mask(hwdev); - dma_addr_t max; - struct pci_controller *hose; - struct pci_dev *pdev = to_pci_dev(hwdev); - - hose = pci_bus_to_host(pdev-bus); - max = hose-dma_window_base_cur + hose-dma_window_size; - - /* check that we're within mapped pci window space */ - if ((addr + size max) | (addr hose-dma_window_base_cur)) + if (sd-max_direct_dma_addr addr + size sd- max_direct_dma_addr) return 1; - return !is_buffer_dma_capable(mask, addr, size); -} - -static int -swiotlb_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) -{ return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size); } - /* * At the moment, all platforms that use this code only require * swiotlb to be used if we're operating on HIGHMEM. Since @@ -104,7 +81,6 @@ struct dma_mapping_ops swiotlb_dma_ops
Re: removing addr_needs_map in struct dma_mapping_ops
On Jul 9, 2009, at 8:47 PM, FUJITA Tomonori wrote: I'm trying to convert POWERPC to use asm-generic/dma-mapping-common.h. POWERPC needs addr_needs_map() in struct dma_mapping_ops for SWIOTLB support but I want to avoid add addr_needs_map() in struct dma_map_ops. IIRC, you guys think it as a temporary solution and That is correct - I was planning to update when the iotlb folks had decided on a final scheme for this. We don't like the additional indirection we're getting with the current implementation. talked about defining something like struct dma_data. Then we could struct dev_archdata { ... struct dma_data *ddata; }; or struct dev_archdata { ... struct dma_data ddata; }; struct dma_data needs dma_direct_offset, iommu_table, dma_base, and dma_window_size, anything else? IIRC, what we had talked about was simpler - we talked about changing the current dev_archdata from this: struct dev_archdata { struct device_node *of_node; struct dma_mapping_ops *dma_ops; void*dma_data; }; to this: struct dev_archdata { struct device_node *of_node; struct dma_mapping_ops *dma_ops; unsigned long long dma_data; #ifdef CONFIG_SWIOTLB dma_addr_t max_direct_dma_addr; #endif }; Where max_direct_dma_addr is the address beyond which a specific device must use swiotlb, and dma_data is the offset like it is now (but wider on 32-bit systems than void *). I believe Ben had mentioned wanting to make the max_direct_dma_addr part conditional so we don't bloat archdata on platforms that don't ever bounce. The change to the type of dma_data is actually in preparation for an optimization I have planned for 64-bit PCI devices (and which probably requires more discussion), so that doesn't need to happen now - just leave it as a void *, and I can post a followup patch. Let me know if I can help or do any testing - I've been meaning to look into switching to dma_map_ops for a while now but it hasn't managed to pop off my todo stack. Cheers, Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 04/15] swiotlb: remove unnecessary swiotlb_bus_to_virt
On Jul 9, 2009, at 8:04 PM, FUJITA Tomonori wrote: swiotlb_bus_to_virt is unncessary; we can use swiotlb_bus_to_phys and phys_to_virt instead. phys_to_virt (also, virt_to_phys) is invalid for highmem addresses on ppc. In most of the uses in this file, it doesn't matter, as the iotlb buffers themselves are alloc'd out of lowmem, but the dma_mark_clean() calls could happen on a highmem addr. Currently, on powerpc, dma_mark_clean() doesn't do anything, so it isn't a functional problem. I'm fine with the bulk of this patch, because in reality, if I need to do something with a virtual address of a highmem page, I have to get a kmap for the page. So the existing swiotlb_bus_to_virt isn't really helping. What is dma_mark_clean used for? Could it be made to take a paddr, and let the implementation deal with making sure there's a valid vaddr for the actual clean operation? I'd also like to see a comment with swiotlb_virt_to_bus() that notes that it should only be called on addresses in lowmem. Cheers, Becky Signed-off-by: FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp --- arch/powerpc/kernel/dma-swiotlb.c | 10 -- lib/swiotlb.c | 34 +++ +-- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/ dma-swiotlb.c index 68ccf11..41534ae 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -24,16 +24,6 @@ int swiotlb __read_mostly; unsigned int ppc_swiotlb_enable; -void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t addr) -{ - unsigned long pfn = PFN_DOWN(swiotlb_bus_to_phys(hwdev, addr)); - void *pageaddr = page_address(pfn_to_page(pfn)); - - if (pageaddr != NULL) - return pageaddr + (addr % PAGE_SIZE); - return NULL; -} - dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) { return paddr + get_dma_direct_offset(hwdev); diff --git a/lib/swiotlb.c b/lib/swiotlb.c index dc1cd1f..1a89c84 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -130,11 +130,6 @@ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, return swiotlb_phys_to_bus(hwdev, virt_to_phys(address)); } -void * __weak swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t address) -{ - return phys_to_virt(swiotlb_bus_to_phys(hwdev, address)); -} - int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) { @@ -307,9 +302,10 @@ address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) return swiotlb_arch_address_needs_mapping(hwdev, addr, size); } -static int is_swiotlb_buffer(char *addr) +static int is_swiotlb_buffer(phys_addr_t paddr) { - return addr = io_tlb_start addr io_tlb_end; + return paddr = virt_to_phys(io_tlb_start) + paddr virt_to_phys(io_tlb_end); } /* @@ -582,11 +578,13 @@ EXPORT_SYMBOL(swiotlb_alloc_coherent); void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, - dma_addr_t dma_handle) + dma_addr_t dev_addr) { + phys_addr_t paddr = swiotlb_bus_to_phys(hwdev, dev_addr); + WARN_ON(irqs_disabled()); - if (!is_swiotlb_buffer(vaddr)) - free_pages((unsigned long) vaddr, get_order(size)); + if (!is_swiotlb_buffer(paddr)) + free_pages((unsigned long)vaddr, get_order(size)); else /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ do_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); @@ -671,19 +669,19 @@ EXPORT_SYMBOL_GPL(swiotlb_map_page); static void unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir) { - char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr); + phys_addr_t paddr = swiotlb_bus_to_phys(hwdev, dev_addr); BUG_ON(dir == DMA_NONE); - if (is_swiotlb_buffer(dma_addr)) { - do_unmap_single(hwdev, dma_addr, size, dir); + if (is_swiotlb_buffer(paddr)) { + do_unmap_single(hwdev, phys_to_virt(paddr), size, dir); return; } if (dir != DMA_FROM_DEVICE) return; - dma_mark_clean(dma_addr, size); + dma_mark_clean(phys_to_virt(paddr), size); } void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, @@ -708,19 +706,19 @@ static void swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, int dir, int target) { - char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr); + phys_addr_t paddr = swiotlb_bus_to_phys(hwdev, dev_addr); BUG_ON(dir == DMA_NONE); - if (is_swiotlb_buffer(dma_addr)) { - sync_single(hwdev, dma_addr, size, dir, target); + if (is_swiotlb_buffer(paddr)) { +
Re: [00/15] swiotlb cleanup
On Jul 10, 2009, at 12:12 AM, Ingo Molnar wrote: * FUJITA Tomonori fujita.tomon...@lab.ntt.co.jp wrote: - removes unused (and unnecessary) hooks in swiotlb. - adds dma_capable() and converts swiotlb to use it. It can be used to know if a memory area is dma capable or not. I added is_buffer_dma_capable() for the same purpose long ago but it turned out that the function doesn't work on POWERPC. This can be applied cleanly to linux-next, -mm, and mainline. This patchset touches multiple architectures (ia64, powerpc, x86) so I guess that -mm is appropriate for this patchset (I don't care much what tree would merge this though). This is tested on x86 but only compile tested on POWERPC and IA64. Thanks, = arch/ia64/include/asm/dma-mapping.h| 18 ++ arch/powerpc/include/asm/dma-mapping.h | 23 +++ arch/powerpc/kernel/dma-swiotlb.c | 48 +--- arch/x86/include/asm/dma-mapping.h | 18 ++ arch/x86/kernel/pci-dma.c |2 +- arch/x86/kernel/pci-gart_64.c |5 +- arch/x86/kernel/pci-nommu.c|2 +- arch/x86/kernel/pci-swiotlb.c | 25 include/linux/dma-mapping.h|5 -- include/linux/swiotlb.h| 11 lib/swiotlb.c | 102 +--- 11 files changed, 92 insertions(+), 167 deletions(-) Hm, the functions and facilities you remove here were added as part of preparatory patches for Xen guest support. You were aware of them, you were involved in discussions about those aspects with Ian and Jeremy but still you chose not to Cc: either of them and you failed to address that aspect in the changelogs. I'd like the Xen code to become cleaner more than anyone else here i guess, but patch submission methods like this are not really helpful. A far better method is to be open about such disagreements, to declare them, to Cc: everyone who disagrees, and to line out the arguments in the changelogs as well - instead of just curtly declaring those APIs 'unused' and failing to Cc: involved parties. Alas, on the technical level the cleanups themselves look mostly fine to me. Ian, Jeremy, the changes will alter Xen's use of swiotlb, but can the Xen side still live with these new methods - in particular is dma_capable() sufficient as a mechanism and can the Xen side filter out DMA allocations to make them physically continuous? Ben, Tony, Becky, any objections wrt. the PowerPC / IA64 impact? If everyone agrees i can apply them to the IOMMU tree, test it and push it out to -next, etc. Ingo, With the exception of the patch I commented on, I think these look OK from the powerpc point of view. I've successfully booted one of my test platforms with the entire series applied and will run some more extensive (i.e. not Whee! A prompt!) tests tomorrow. -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: dma_ops-map_page == NULL
On Jul 7, 2009, at 9:37 AM, Kumar Gala wrote: On Jul 7, 2009, at 6:08 AM, Benjamin Herrenschmidt wrote: On Tue, 2009-07-07 at 10:15 +1000, Mark Nelson wrote: When the 32 and 64bit DMA code was merged in .28 , map_/ unmap_page() was added in favour of map_/unmap_single() (which was later removed in .29) so you'll have to replace your calls to dma_map_single() with dma_map_page(). Just pass it the page and offset rather than the address. Wait a minute ... dma_map_single() should still work, it will just call dma_map_page() underneath. All dma_ops should have a -map page callback. Do you have any dma_ops set for your device at all ? I wonder how we set the dma_ops for platform devices nowadays ... We use to have this fallback to direct ops when the dma_ops are NULL but that is gone and I see no suitable replacement to set them on platform devices for embedded archs ... oops... There is a platform/of bus notifier that sets the dma_ops to a default value in arch/powerpc/kernel/setup-common.c. Kumar, Becky, what's the situation there ? Cheers, Ben. Is it possible the dev pointer is not valid? I can't remember if that was a .29 or .30 change that requires us to start passing a valid dev pointer to get the proper dma_ops. I'm pretty sure that went into .29. And invalid dev pointer is the most likely culprit. IIRC, the usual cause of this is that you're passing in the *wrong* dev pointer. There are often struct hierarchies with, confusingly, multiple struct device pointers. You need the one which has archdata dma_ops setup properly. For an of device, you want the dev pointer that is part of the of_device struct. If this isn't your problem, then please post some code so we can look at this further, and post a log of what's happening. Cheers, Becky ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
On May 22, 2009, at 6:11 AM, Ian Campbell wrote: BTW do you need swiotlb_bus_to_virt to be __weak or is the fact that it is implemented in terms of swiotlb_bus_to_phys sufficient? The default one in swiotlb calls phys_to_virt on the result of swiotlb_bus_to_phys, which only works on lowmem. I have an appointment all afternoon and it's a bank holiday on Monday but here is my WIP patch as an example of what I'm thinking. Obviously some cleanups are still very much required: * The Xen specific stuff in arch/x86/include/asm/dma-mapping.h clearly needs to be properly abstracted away (I just stuck it there for testing). * swiotlb_phys_to_bus and swiotlb_bus_to_phys need to move to arch/*/include/asm/dma-mapping.h instead of being __weak * Maybe swiotlb_bus_to_virt can become static again. * Need to finish auditing the handful of non-swiotlb users of is_buffer_dma_capable. * It might be possible to implement swiolb_dma_mapping_error and/or swiotlb_dma_supported in terms of dma_map_range. * Minor detail: it doesn't actually work at the moment ;-) Minor detail :) I'm in the same boat- been offline most of the week and will continue to be offline (I'm sneaking in an hour here to read emails) until sometime next week. I'm in the middle of a big lab construction and move project. I'll take a look as soon as I can - thanks! -Becky Ian. diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/ asm/dma-mapping.h index 36c0009..026667f 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -174,4 +174,12 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size, #define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */ +static inline dma_addr_t dma_map_range(struct device *dev, u64 mask, + phys_addr_t addr, size_t size) +{ + if (addr + size = mask) + return addr; + return 0; +} + #endif /* _ASM_IA64_DMA_MAPPING_H */ diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/ asm/dma-mapping.h index 916cbb6..b2813ab 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -309,4 +309,20 @@ static inline void dma_free_coherent(struct device *dev, size_t size, ops-free_coherent(dev, size, vaddr, bus); } +static inline dma_addr_t dma_map_range(struct device *dev, u64 mask, + phys_addr_t addr, size_t size) +{ + dma_addr_t dma_addr; +#ifdef CONFIG_XEN + extern int xen_range_needs_mapping(phys_addr_t paddr, size_t size); + if (xen_pv_domain() xen_range_needs_mapping(addr, size)) + return 0; +#endif + + dma_addr = swiotlb_phys_to_bus(dev, addr); + if (dma_addr + size = mask) + return 0; + return dma_addr; +} + #endif diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 2fffc22..c2b4196 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -145,8 +145,8 @@ again: if (!page) return NULL; - addr = page_to_phys(page); - if (!is_buffer_dma_capable(dma_mask, addr, size)) { + addr = dma_map_range(dev, dma_mask, page_to_phys(page), size); + if (!(addr == 0)) { __free_pages(page, get_order(size)); if (dma_mask DMA_BIT_MASK(32) !(flag GFP_DMA)) { diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci- gart_64.c index 1e8920d..6a55770 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -191,13 +191,13 @@ static inline int need_iommu(struct device *dev, unsigned long addr, size_t size) { return force_iommu || - !is_buffer_dma_capable(*dev-dma_mask, addr, size); + dma_map_range(dev, *dev-dma_mask, addr, size) == 0; } static inline int nonforced_iommu(struct device *dev, unsigned long addr, size_t size) { - return !is_buffer_dma_capable(*dev-dma_mask, addr, size); + return dma_map_range(dev, *dev-dma_mask, addr, size) == 0; } /* Map a single continuous physical area into the IOMMU. diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 71d412a..712ce59 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -12,13 +12,13 @@ #include asm/dma.h static int -check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) +check_addr(char *name, struct device *hwdev, phys_addr_t phys, size_t size) { - if (hwdev !is_buffer_dma_capable(*hwdev-dma_mask, bus, size)) { + if (hwdev dma_map_range(hwdev, *hwdev-dma_mask, phys, size) == 0) { if (*hwdev-dma_mask = DMA_BIT_MASK(32)) printk(KERN_ERR nommu_%s: overflow %Lx+%zu of device mask %Lx\n, - name, (long long)bus,
Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
On May 22, 2009, at 5:51 AM, FUJITA Tomonori wrote: On Thu, 21 May 2009 13:18:54 -0700 Jeremy Fitzhardinge jer...@goop.org wrote: Becky Bruce wrote: I can work with that, but it's going to be a bit inefficient, as I actually need the dma_addr_t, not the phys_addr_t, so I'll have to convert. In every case, this is a conversion I've already done and that I need in the calling code as well. Can we pass in both the phys_addr_t and the dma_addr_t? The Xen implementation would needs to do the phys to bus conversion page by page anyway, so it wouldn't help much. But it also wouldn't hurt. How expensive is the phys-to-bus conversion on power? Is it worth making the interface more complex for? Would passing phys+bus mean that we wouldn't also need to pass dev? I don't think so. POWERPC needs it. Hrm, it looks like my response to this got dropped. Fujita is correct - we still need the dev on powerpc because we use it to get device- specific information that is used to determining when we need to actually bounce. Cheers, B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
On May 26, 2009, at 7:51 AM, Ian Campbell wrote: On Fri, 2009-05-22 at 19:55 -0400, Jeremy Fitzhardinge wrote: Ian Campbell wrote: On Thu, 2009-05-21 at 14:27 -0400, Becky Bruce wrote: I can work with that, but it's going to be a bit inefficient, as I actually need the dma_addr_t, not the phys_addr_t, so I'll have to convert. In every case, this is a conversion I've already done and that I need in the calling code as well. Does dma_addr_t dma_map_range(struct device *hwdev, phys_addr_t addr, size_t size); work for you? If the range does not need mapping then it returns the dma address, if you needed to calculate the dma address anyway to figure out if mapping is required then this is fine. If the range does need mapping then it returns NULL. My only concern is whether dma_addr_t == 0 is actually equivalent to NULL. That is, can we be sure that address 0 will never be used? It seems not, ~0UL might have been an option, but... Taking dma_alloc_coherent as a model, we could have something like: int dma_map_range(struct device *hwdev, phys_addr_t addr, size_t size, dma_addr_t *dma_addrp); where *dma_addrp is set if the function returns success (bool return type might be clearer). ... this sounds like a good idea to me. I agree. This will work for me as well. -becky ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
On May 27, 2009, at 3:29 PM, Ian Campbell wrote: On Wed, 2009-05-27 at 15:05 -0400, Becky Bruce wrote: On May 22, 2009, at 6:11 AM, Ian Campbell wrote: BTW do you need swiotlb_bus_to_virt to be __weak or is the fact that it is implemented in terms of swiotlb_bus_to_phys sufficient? The default one in swiotlb calls phys_to_virt on the result of swiotlb_bus_to_phys, which only works on lowmem. Perhaps we can simply enhance the default one to handle highmem instead of making it arch specific? That's fine by me - as long as what I've got will work for you guys I'm happy to stick it in the standard one (inside a nice pretty #ifdef CONFIG_HIGHMEM, of course). Cheers, B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH V2 2/3] powerpc: Add support for swiotlb on 32-bit
On May 21, 2009, at 12:43 PM, Jeremy Fitzhardinge wrote: Becky Bruce wrote: If we have something like in arch/{x86|ia64|powerpc}/dma-mapping.h: static inline int is_buffer_dma_capable(struct device *dev, dma_addr_t addr, size_t size) then we don't need two checking functions, address_needs_mapping and range_needs_mapping. It's never been clear to me *why* we had both in the first place - if you can explain this, I'd be grateful :) I was about to ask the same thing. It seems that range_needs_mapping should be able to do both jobs. I think range_needs_mapping came from the Xen swiotlb changes, and address_needs_mapping came from your powerpc changes. Many of the changes were exact overlaps; I think this was one of the few instances where there was a difference. I think address_needs_mapping was already there and I added the ability for an arch to provide its own version. Ian added range_needs_mapping in commit b81ea27b2329bf44b. At the time, it took a virtual address as its argument, so we couldn't use it for highmem. That's since been changed to phys_addr_t, so I think we should be able to merge the two. We need a range check in Xen (rather than iterating over individual pages) because we want to check that the underlying pages are machine contiguous, but I think that's also sufficient to do whatever checks you need to do. Yes. The other difference is that is_buffer_dma_capable operates on a dma_addr_t, which presumes that you can generate a dma address and then test for its validity. For Xen, it doesn't make much sense to talk about the dma_addr_t for memory which isn't actually dma- capable; we need the test to be in terms of phys_addr_t. Given that the two functions are always called from the same place, that doesn't seem to pose a problem. So I think the unified function would be something like: int range_needs_mapping(struct device *hwdev, phys_addr_t addr, size_t size); which would be defined somewhere under asm/*.h. Would that work for powerpc? I can work with that, but it's going to be a bit inefficient, as I actually need the dma_addr_t, not the phys_addr_t, so I'll have to convert. In every case, this is a conversion I've already done and that I need in the calling code as well. Can we pass in both the phys_addr_t and the dma_addr_t? We have both in every case but one, which is in swiotlb_map_page where we call address_needs_mapping() without calling range_needs_mapping. It's not actually clear to me that we need that check, though. Can someone explain what case that was designed to catch? Cheers, Becky ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH V2 1/3] powerpc: Use sg-dma_length in sg_dma_len() macro on 32-bit
Currently, the 32-bit code uses sg-length instead of sg-dma_lentgh to report sg_dma_len. However, since the default dma code for 32-bit (the dma_direct case) sets dma_length and length to the same thing, we should be able to use dma_length there as well. This gets rid of some 32-vs-64-bit ifdefs, and is needed by the swiotlb code which actually distinguishes between dma_length and length. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/scatterlist.h |6 +- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/scatterlist.h b/arch/powerpc/include/asm/scatterlist.h index fcf7d55..912bf59 100644 --- a/arch/powerpc/include/asm/scatterlist.h +++ b/arch/powerpc/include/asm/scatterlist.h @@ -21,7 +21,7 @@ struct scatterlist { unsigned int offset; unsigned int length; - /* For TCE support */ + /* For TCE or SWIOTLB support */ dma_addr_t dma_address; u32 dma_length; }; @@ -34,11 +34,7 @@ struct scatterlist { * is 0. */ #define sg_dma_address(sg) ((sg)-dma_address) -#ifdef __powerpc64__ #define sg_dma_len(sg) ((sg)-dma_length) -#else -#define sg_dma_len(sg) ((sg)-length) -#endif #ifdef __powerpc64__ #define ISA_DMA_THRESHOLD (~0UL) -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH V2 3/3] powerpc: Add 86xx support for SWIOTLB
This is the final bit of code to allow enabling swiotlb on mpc86xx. The platform-specific code is very small and consists of enabling SWIOTLB in the config file, registering the swiotlb_setup_bus_notifier initcall, and setting pci_dma_ops to point to swiotlb_pci_dma_ops if we have more memory than can be mapped by the inbound PCI windows. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/platforms/86xx/Kconfig|1 + arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 15 +++ 2 files changed, 16 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index fdaf4dd..9c7b64a 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -15,6 +15,7 @@ config MPC8641_HPCN select DEFAULT_UIMAGE select FSL_ULI1575 select HAS_RAPIDIO + select SWIOTLB help This option enables support for the MPC8641 HPCN board. diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 7e9e83c..6632702 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -19,6 +19,7 @@ #include linux/delay.h #include linux/seq_file.h #include linux/of_platform.h +#include linux/lmb.h #include asm/system.h #include asm/time.h @@ -27,6 +28,7 @@ #include asm/prom.h #include mm/mmu_decl.h #include asm/udbg.h +#include asm/swiotlb.h #include asm/mpic.h @@ -70,7 +72,9 @@ mpc86xx_hpcn_setup_arch(void) { #ifdef CONFIG_PCI struct device_node *np; + struct pci_controller *hose; #endif + dma_addr_t max = 0x; if (ppc_md.progress) ppc_md.progress(mpc86xx_hpcn_setup_arch(), 0); @@ -83,6 +87,9 @@ mpc86xx_hpcn_setup_arch(void) fsl_add_bridge(np, 1); else fsl_add_bridge(np, 0); + hose = pci_find_hose_for_OF_device(np); + max = min(max, hose-dma_window_base_cur + + hose-dma_window_size); } ppc_md.pci_exclude_device = mpc86xx_exclude_device; @@ -94,6 +101,13 @@ mpc86xx_hpcn_setup_arch(void) #ifdef CONFIG_SMP mpc86xx_smp_init(); #endif + +#ifdef CONFIG_SWIOTLB + if (lmb_end_of_DRAM() max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(swiotlb_pci_dma_ops); + } +#endif } @@ -158,6 +172,7 @@ static int __init declare_of_platform_devices(void) return 0; } machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices); +machine_arch_initcall(mpc86xx_hpcn, swiotlb_setup_bus_notifier); define_machine(mpc86xx_hpcn) { .name = MPC86xx HPCN, -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] sata_fsl: Fix compile warnings
On May 13, 2009, at 4:12 PM, Kumar Gala wrote: We we build with dma_addr_t as a 64-bit quantity we get: drivers/ata/sata_fsl.c: In function 'sata_fsl_fill_sg': drivers/ata/sata_fsl.c:340: warning: format '%x' expects type 'unsigned int', but argument 4 has type 'dma_addr_t' Signed-off-by: Kumar Gala ga...@kernel.crashing.org --- drivers/ata/sata_fsl.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index c2e90e1..c7ee52d 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -332,13 +332,14 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, dma_addr_t sg_addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); - VPRINTK(SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n, - sg_addr, sg_len); + VPRINTK(SATA FSL : fill_sg, sg_addr = 0x%llx, sg_len = %d\n, + (unsigned long long)sg_addr, sg_len); /* warn if each s/g element is not dword aligned */ if (sg_addr 0x03) ata_port_printk(qc-ap, KERN_ERR, - s/g addr unaligned : 0x%x\n, sg_addr); + s/g addr unaligned : 0x%llxx\n, You have an extra x in there Cheers, B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH] powerpc: Allow mem=x cmdline to work with 4G+
We're currently choking on mem=4g (and above) due to memory_limit being specified as an unsigned long. Make memory_limit phys_addr_t to fix this. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- Ben, This is a fix for something I missed in the earlier large physical patches. I've tested it on MPC8641 both with and without PHYS_64BIT; I've build tested on ppc64_defconfig as well. Cheers, B arch/powerpc/include/asm/system.h |2 +- arch/powerpc/kernel/machine_kexec.c |4 ++-- arch/powerpc/kernel/prom.c |8 arch/powerpc/mm/mem.c |2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h index f612798..2b2420a 100644 --- a/arch/powerpc/include/asm/system.h +++ b/arch/powerpc/include/asm/system.h @@ -212,7 +212,7 @@ extern struct task_struct *_switch(struct thread_struct *prev, extern unsigned int rtas_data; extern int mem_init_done; /* set on boot once kmalloc can be called */ extern int init_bootmem_done; /* set on !NUMA once bootmem is available */ -extern unsigned long memory_limit; +extern phys_addr_t memory_limit; extern unsigned long klimit; extern void *alloc_maybe_bootmem(size_t size, gfp_t mask); diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index d59e2b1..bb3d893 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -125,8 +125,8 @@ void __init reserve_crashkernel(void) /* Crash kernel trumps memory limit */ if (memory_limit memory_limit = crashk_res.end) { memory_limit = crashk_res.end + 1; - printk(Adjusted memory limit for crashkernel, now 0x%lx\n, - memory_limit); + printk(Adjusted memory limit for crashkernel, now 0x%llx\n, + (unsigned long long)memory_limit); } printk(KERN_INFO Reserving %ldMB of memory at %ldMB diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 5ec6a9e..ce01ff2 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -426,7 +426,7 @@ static int __init early_parse_mem(char *p) return 1; memory_limit = PAGE_ALIGN(memparse(p, p)); - DBG(memory limit = 0x%lx\n, memory_limit); + DBG(memory limit = 0x%llx\n, (unsigned long long)memory_limit); return 0; } @@ -1160,7 +1160,7 @@ static inline void __init phyp_dump_reserve_mem(void) {} void __init early_init_devtree(void *params) { - unsigned long limit; + phys_addr_t limit; DBG( - early_init_devtree(%p)\n, params); @@ -1204,7 +1204,7 @@ void __init early_init_devtree(void *params) limit = memory_limit; if (! limit) { - unsigned long memsize; + phys_addr_t memsize; /* Ensure that total memory size is page-aligned, because * otherwise mark_bootmem() gets upset. */ @@ -1218,7 +1218,7 @@ void __init early_init_devtree(void *params) lmb_analyze(); lmb_dump_all(); - DBG(Phys. mem: %lx\n, lmb_phys_mem_size()); + DBG(Phys. mem: %llx\n, lmb_phys_mem_size()); /* We may need to relocate the flat tree, do it now. * FIXME .. and the initrd too? */ diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index f668fa9..d0602a7 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -57,7 +57,7 @@ int init_bootmem_done; int mem_init_done; -unsigned long memory_limit; +phys_addr_t memory_limit; #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 1/5] powerpc: Use sg-dma_length in sg_dma_len() macro on 32-bit
On Apr 20, 2009, at 3:06 PM, Kumar Gala wrote: On Apr 20, 2009, at 11:26 AM, Becky Bruce wrote: Currently, the 32-bit code uses sg-length instead of sg-dma_lentgh to report sg_dma_len. However, since the default dma code for 32-bit (the dma_direct case) sets dma_length and length to the same thing, we should be able to use dma_length there as well. This gets rid of some 32-vs-64-bit ifdefs, and is needed by the swiotlb code which actually distinguishes between dma_length and length. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/scatterlist.h |6 +- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/scatterlist.h b/arch/powerpc/ include/asm/scatterlist.h index fcf7d55..912bf59 100644 --- a/arch/powerpc/include/asm/scatterlist.h +++ b/arch/powerpc/include/asm/scatterlist.h @@ -21,7 +21,7 @@ struct scatterlist { unsigned int offset; unsigned int length; can we get rid of length? No - they're both used by the iotlb code and are conceptually different. dma_length can get set to less than length to indicate that something went wrong with a dma request - the iotlb code sets it to 0 if we can't allocate a bounce buffer, for example. It probably has other uses as well - this is just the one I'm familiar with. In most cases they are equal. Cheers, B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 2/5] powerpc: Add 36-bit device tree for mpc8641hpcn
On Apr 20, 2009, at 8:10 PM, David Gibson wrote: On Mon, Apr 20, 2009 at 11:26:47AM -0500, Becky Bruce wrote: The new dts places most of the devices in physical address space above 32-bits, which allows us to have more than 4GB of RAM present. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts | 597 ++ ++ 1 files changed, 597 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/ powerpc/boot/dts/mpc8641_hpcn_36b.dts new file mode 100644 index 000..baa3dba --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts @@ -0,0 +1,597 @@ +/* + * MPC8641 HPCN Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ [snip] + soc8...@fffe0 { + #address-cells = 1; + #size-cells = 1; + device_type = soc; + compatible = simple-bus; Uh, you definitely need something more specific in the compatible property before simple-bus. This is a copy of the existing mpc8641hpcn dts file, with just physical address changes, so if there's a problem here it definitely exists in the current 8641hpcn dts, and possibly other dts files as well. I think the correct solution is for me to go look at that .dts (and any others that may be similar), and put out a followup to fix them all. Thanks, Becky ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 0/5] Allow swiotlb use on ppc/mpc86xx
GIT: Please enter your email below. GIT: Lines beginning in GIT: will be removed. GIT: Consider including an overall diffstat or table of contents GIT: for the patch you are writing. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 0/5] enable swiotlb on ppc/86xx
GIT: Please enter your email below. GIT: Lines beginning in GIT: will be removed. GIT: Consider including an overall diffstat or table of contents GIT: for the patch you are writing. ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 3/5] powerpc: make dma_window_* in pci_controller struct avail on 32b
Also, convert them to resource_size_t (which is unsigned long on 64-bit, so it's not a change there). We will be using these on fsl 32b to indicate the start and size address of memory that the pci controller can actually reach - this is needed to determine if an address requires bounce buffering. For now, initialize them to a standard value; in the near future, the value will be calculated based on how the inbound windows are programmed. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/pci-bridge.h |6 -- arch/powerpc/sysdev/fsl_pci.c |4 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 84007af..9861258 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -140,10 +140,12 @@ struct pci_controller { struct resource io_resource; struct resource mem_resources[3]; int global_number; /* PCI domain number */ + + resource_size_t dma_window_base_cur; + resource_size_t dma_window_size; + #ifdef CONFIG_PPC64 unsigned long buid; - unsigned long dma_window_base_cur; - unsigned long dma_window_size; void *private_data; #endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 78021d8..376603d 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -152,6 +152,10 @@ static void __init setup_pci_atmu(struct pci_controller *hose, out_be32(pci-piw[2].piwbar,0x); out_be32(pci-piw[2].piwar, PIWAR_2G); + /* Save the base address and size covered by inbound window mappings */ + hose-dma_window_base_cur = 0x; + hose-dma_window_size = 0x8000; + iounmap(pci); } -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 1/5] powerpc: Use sg-dma_length in sg_dma_len() macro on 32-bit
Currently, the 32-bit code uses sg-length instead of sg-dma_lentgh to report sg_dma_len. However, since the default dma code for 32-bit (the dma_direct case) sets dma_length and length to the same thing, we should be able to use dma_length there as well. This gets rid of some 32-vs-64-bit ifdefs, and is needed by the swiotlb code which actually distinguishes between dma_length and length. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/include/asm/scatterlist.h |6 +- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/scatterlist.h b/arch/powerpc/include/asm/scatterlist.h index fcf7d55..912bf59 100644 --- a/arch/powerpc/include/asm/scatterlist.h +++ b/arch/powerpc/include/asm/scatterlist.h @@ -21,7 +21,7 @@ struct scatterlist { unsigned int offset; unsigned int length; - /* For TCE support */ + /* For TCE or SWIOTLB support */ dma_addr_t dma_address; u32 dma_length; }; @@ -34,11 +34,7 @@ struct scatterlist { * is 0. */ #define sg_dma_address(sg) ((sg)-dma_address) -#ifdef __powerpc64__ #define sg_dma_len(sg) ((sg)-dma_length) -#else -#define sg_dma_len(sg) ((sg)-length) -#endif #ifdef __powerpc64__ #define ISA_DMA_THRESHOLD (~0UL) -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 0/5] SWIOTLB for ppc/mpc86xx
This patch series allows the use of swiotlb on mpc86xx, with 85xx support soon to follow. The most notable change here is the addition of addr_needs_map to dma_ops. This is used to tell if a device can reach an address without bounce buffering. I believe that patches will be coming out soon to make dma_ops non-arch-specific, and I expect to see something similar there as well. I've also changed sg_dma_len to be the same on both 32 and 64-bit. We now look at sg-dma_length in both cases (see patch log). The dma_window* elements in the pci_controller struct are hoisted out of an #ifdef CONFIG_PPC64 so we can use them to store off information about how much memory is mapped via the inbound pci windows. A dma-swiotlb.c is created in arch/powerpc/kernel to contain all the platform-specific iotlb code. Finally, hooks are provided to allow enabling of this feature on 86xx via Kconfig, and a 36-bit device tree for 8641hpcn is provided. Ye Olde Diffstat: arch/powerpc/Kconfig |2 +- arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts | 597 arch/powerpc/include/asm/dma-mapping.h | 11 + arch/powerpc/include/asm/pci-bridge.h |6 +- arch/powerpc/include/asm/scatterlist.h |6 +- arch/powerpc/include/asm/swiotlb.h | 24 ++ arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/dma-swiotlb.c | 161 arch/powerpc/kernel/dma.c |2 +- arch/powerpc/kernel/setup_32.c |4 + arch/powerpc/sysdev/fsl_pci.c |4 + 11 files changed, 809 insertions(+), 9 deletions(-) Cheers, Becky ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 5/5] powerpc: Add 86xx support for SWIOTLB
Minor code to allow enabling swiotlb on mpc86xx, including Kconfig addition for SWIOTLB. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/Kconfig | 10 ++ arch/powerpc/kernel/dma-swiotlb.c |2 ++ arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |3 +++ 3 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 197f6a3..e47c81d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -292,6 +292,16 @@ config IOMMU_VMERGE config IOMMU_HELPER def_bool PPC64 +config SWIOTLB + bool SWIOTLB support + depends on PPC_86xx + select IOMMU_HELPER + ---help--- + Support for IO bounce buffering for systems without an IOMMU. + This allows us to DMA to the full physical address space on + platforms where the size of a physical address is larger + than the bus address. + config PPC_NEED_DMA_SYNC_OPS def_bool y depends on (NOT_COHERENT_CACHE || SWIOTLB) diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 29a68e6..3065d03 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -159,3 +159,5 @@ static int __init setup_bus_notifier(void) return 0; } + +machine_arch_initcall(mpc86xx_hpcn, setup_bus_notifier); diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index c4ec49b..f7b88b9 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -88,6 +88,9 @@ mpc86xx_hpcn_setup_arch(void) ppc_md.pci_exclude_device = mpc86xx_exclude_device; +#ifdef CONFIG_SWIOTLB + set_pci_dma_ops(swiotlb_pci_dma_ops); +#endif #endif printk(MPC86xx HPCN board from Freescale Semiconductor\n); -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH 2/5] powerpc: Add 36-bit device tree for mpc8641hpcn
The new dts places most of the devices in physical address space above 32-bits, which allows us to have more than 4GB of RAM present. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts | 597 1 files changed, 597 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts new file mode 100644 index 000..baa3dba --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts @@ -0,0 +1,597 @@ +/* + * MPC8641 HPCN Device Tree Source + * + * Copyright 2006 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/dts-v1/; + +/ { + model = MPC8641HPCN; + compatible = fsl,mpc8641hpcn; + #address-cells = 2; + #size-cells = 2; + + aliases { + ethernet0 = enet0; + ethernet1 = enet1; + ethernet2 = enet2; + ethernet3 = enet3; + serial0 = serial0; + serial1 = serial1; + pci0 = pci0; + pci1 = pci1; + }; + + cpus { + #address-cells = 1; + #size-cells = 0; + + PowerPC,8...@0 { + device_type = cpu; + reg = 0; + d-cache-line-size = 32; // 32 bytes + i-cache-line-size = 32; // 32 bytes + d-cache-size = 32768; // L1, 32K + i-cache-size = 32768; // L1, 32K + timebase-frequency = 0; // 33 MHz, from uboot + bus-frequency = 0;// From uboot + clock-frequency = 0; // From uboot + }; + PowerPC,8...@1 { + device_type = cpu; + reg = 1; + d-cache-line-size = 32; // 32 bytes + i-cache-line-size = 32; // 32 bytes + d-cache-size = 32768; // L1, 32K + i-cache-size = 32768; // L1, 32K + timebase-frequency = 0; // 33 MHz, from uboot + bus-frequency = 0;// From uboot + clock-frequency = 0; // From uboot + }; + }; + + memory { + device_type = memory; + reg = 0x0 0x 0x0 0x4000; // 1G at 0x0 + }; + + local...@fffe05000 { + #address-cells = 2; + #size-cells = 1; + compatible = fsl,mpc8641-localbus, simple-bus; + reg = 0x0f 0xffe05000 0x0 0x1000; + interrupts = 19 2; + interrupt-parent = mpic; + + ranges = 0 0 0xf 0xef80 0x0080 + 2 0 0xf 0xffdf8000 0x8000 + 3 0 0xf 0xffdf 0x8000; + + fl...@0,0 { + compatible = cfi-flash; + reg = 0 0 0x0080; + bank-width = 2; + device-width = 2; + #address-cells = 1; + #size-cells = 1; + partit...@0 { + label = kernel; + reg = 0x 0x0030; + }; + partit...@30 { + label = firmware b; + reg = 0x0030 0x0010; + read-only; + }; + partit...@40 { + label = fs; + reg = 0x0040 0x0030; + }; + partit...@70 { + label = firmware a; + reg = 0x0070 0x0010; + read-only; + }; + }; + }; + + soc8...@fffe0 { + #address-cells = 1; + #size-cells = 1; + device_type = soc; + compatible = simple-bus; + ranges = 0x 0x0f 0xffe0 0x0010; + reg = 0x0f 0xffe0 0x0 0x1000; // CCSRBAR + bus-frequency = 0; + + i...@3000 { + #address-cells = 1; + #size-cells = 0; + cell-index = 0; + compatible = fsl-i2c
[PATCH 4/5] powerpc: Add support for swiotlb on 32-bit
This patch includes the basic infrastructure to use swiotlb bounce buffering on 32-bit powerpc. It is not yet enabled on any platforms. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/dma-mapping.h | 11 ++ arch/powerpc/include/asm/swiotlb.h | 24 + arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/dma-swiotlb.c | 161 arch/powerpc/kernel/dma.c |2 +- arch/powerpc/kernel/setup_32.c |4 + 7 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/include/asm/swiotlb.h create mode 100644 arch/powerpc/kernel/dma-swiotlb.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5b50e1a..197f6a3 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -294,7 +294,7 @@ config IOMMU_HELPER config PPC_NEED_DMA_SYNC_OPS def_bool y - depends on NOT_COHERENT_CACHE + depends on (NOT_COHERENT_CACHE || SWIOTLB) config HOTPLUG_CPU bool Support for enabling/disabling CPUs diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index c69f2b5..71bbc17 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -15,9 +15,18 @@ #include linux/scatterlist.h #include linux/dma-attrs.h #include asm/io.h +#include asm/swiotlb.h #define DMA_ERROR_CODE (~(dma_addr_t)0x0) +/* Some dma direct funcs must be visible for use in other dma_ops */ +extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag); +extern void dma_direct_free_coherent(struct device *dev, size_t size, +void *vaddr, dma_addr_t dma_handle); + +extern unsigned long get_dma_direct_offset(struct device *dev); + #ifdef CONFIG_NOT_COHERENT_CACHE /* * DMA-consistent mapping functions for PowerPCs that don't support @@ -76,6 +85,8 @@ struct dma_mapping_ops { dma_addr_t dma_address, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs); + int (*addr_needs_map)(struct device *dev, dma_addr_t addr, + size_t size); #ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS void(*sync_single_range_for_cpu)(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/include/asm/swiotlb.h new file mode 100644 index 000..6440fdf --- /dev/null +++ b/arch/powerpc/include/asm/swiotlb.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef __ASM_SWIOTLB_H +#define __ASM_SWIOTLB_H + +#include linux/swiotlb.h + +extern struct dma_mapping_ops swiotlb_dma_ops; +extern struct dma_mapping_ops swiotlb_pci_dma_ops; + +int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t, + size_t size); + +static inline void dma_mark_clean(void *addr, size_t size) {} + +#endif /* __ASM_SWIOTLB_H */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 71901fb..34c0a95 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -82,6 +82,7 @@ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c new file mode 100644 index 000..29a68e6 --- /dev/null +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -0,0 +1,161 @@ +/* + * Contains routines needed to support swiotlb for ppc. + * + * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include linux/dma-mapping.h +#include linux/pfn.h +#include linux/of_platform.h +#include linux/platform_device.h +#include linux/pci.h + +#include asm/machdep.h +#include asm/swiotlb.h +#include asm/dma.h +#include asm/abs_addr.h + +int swiotlb __read_mostly; + +void
Re: [PATCH 0/5] Allow swiotlb use on ppc/mpc86xx
FAIL. Here's the text that should have been there :) -B This patch series allows the use of swiotlb on mpc86xx, with 85xx upport soon to follow. The most notable change here is the addition of addr_needs_map to dma_ops. This is used to tell if a device can reach an address without bounce buffering. I believe that patches will be coming out soon to make dma_ops non-arch-specific, and I expect to see something similar there as well. I've also changed sg_dma_len to be the same on both 32 and 64-bit. We now look at sg-dma_length in both cases (see patch log). The dma_window* elements in the pci_controller struct are hoisted out of an #ifdef CONFIG_PPC64 so we can use them to store off information about how much memory is mapped via the inbound pci windows. A dma-swiotlb.c is created in arch/powerpc/kernel to contain all the platform-specific iotlb code. Finally, hooks are provided to allow enabling of this feature on 86xx via Kconfig, and a 36-bit device tree for 8641hpcn is provided. Ye Olde Diffstat: arch/powerpc/Kconfig |2 +- arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts | 597 +++ + arch/powerpc/include/asm/dma-mapping.h | 11 + arch/powerpc/include/asm/pci-bridge.h |6 +- arch/powerpc/include/asm/scatterlist.h |6 +- arch/powerpc/include/asm/swiotlb.h | 24 ++ arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/dma-swiotlb.c | 161 arch/powerpc/kernel/dma.c |2 +- arch/powerpc/kernel/setup_32.c |4 + arch/powerpc/sysdev/fsl_pci.c |4 + 11 files changed, 809 insertions(+), 9 deletions(-) Cheers, Becky ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 5/5] powerpc: Add 86xx support for SWIOTLB
On Apr 20, 2009, at 12:00 PM, Kumar Gala wrote: On Apr 20, 2009, at 11:26 AM, Becky Bruce wrote: Minor code to allow enabling swiotlb on mpc86xx, including Kconfig addition for SWIOTLB. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/Kconfig | 10 ++ arch/powerpc/kernel/dma-swiotlb.c |2 ++ arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |3 +++ 3 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 197f6a3..e47c81d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -292,6 +292,16 @@ config IOMMU_VMERGE config IOMMU_HELPER def_bool PPC64 +config SWIOTLB + bool SWIOTLB support + depends on PPC_86xx + select IOMMU_HELPER + ---help--- + Support for IO bounce buffering for systems without an IOMMU. + This allows us to DMA to the full physical address space on + platforms where the size of a physical address is larger + than the bus address. + As stated on previous patch, move the bulk of this into 4/5. Yep. config PPC_NEED_DMA_SYNC_OPS def_bool y depends on (NOT_COHERENT_CACHE || SWIOTLB) diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/ kernel/dma-swiotlb.c index 29a68e6..3065d03 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -159,3 +159,5 @@ static int __init setup_bus_notifier(void) return 0; } + +machine_arch_initcall(mpc86xx_hpcn, setup_bus_notifier); Hmm, not sure what we chatted about here, but I don't want to have to add every board into this file to register the bus notifiers. We talked about this, and this was what we decided on - I don't really like the idea, either, but there's a lot of precedent for it. I'd like to do this differently, but Im not sure what the solution is - we'd need to look into that more (or perhaps someone here will have some sage advice). Cheers, B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 4/5] powerpc: Add support for swiotlb on 32-bit
On Apr 20, 2009, at 11:57 AM, Kumar Gala wrote: On Apr 20, 2009, at 11:26 AM, Becky Bruce wrote: This patch includes the basic infrastructure to use swiotlb bounce buffering on 32-bit powerpc. It is not yet enabled on any platforms. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/Kconfig |2 +- arch/powerpc/include/asm/dma-mapping.h | 11 ++ arch/powerpc/include/asm/swiotlb.h | 24 + arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/dma-swiotlb.c | 161 ++ ++ arch/powerpc/kernel/dma.c |2 +- arch/powerpc/kernel/setup_32.c |4 + 7 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/include/asm/swiotlb.h create mode 100644 arch/powerpc/kernel/dma-swiotlb.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5b50e1a..197f6a3 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -294,7 +294,7 @@ config IOMMU_HELPER config PPC_NEED_DMA_SYNC_OPS def_bool y - depends on NOT_COHERENT_CACHE + depends on (NOT_COHERENT_CACHE || SWIOTLB) This isn't right, since you haven't introduced the SWIOTLB Kconfig. Why don't we just put the SWIOTLB Kconfig option in here and default it no (and remove the dep on 86xx). Sure. I'll probably add a comment or something though so people don't think they can just enable it on anything and expect it to work. Too many people seem to read the config files and decide things are possible that actually aren't :) config HOTPLUG_CPU bool Support for enabling/disabling CPUs diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/ kernel/dma-swiotlb.c new file mode 100644 index 000..29a68e6 --- /dev/null +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -0,0 +1,161 @@ +/* + * Contains routines needed to support swiotlb for ppc. + * + * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ [snip] + +static int ppc_swiotlb_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + + /* We are only intereted in device addition */ + if (action != BUS_NOTIFY_ADD_DEVICE) + return 0; + + if (dma_get_mask(dev) DMA_BIT_MASK(36)) + set_dma_ops(dev, swiotlb_dma_ops); + this isn't right. Isn't possible for a PCI dev to have a DMA_BIT_MASK(64) but us still not be able to dma to it? Also, I dont like the assumption of 36-bit physical here. You're right - this is just handling the basic case and for now I'm assuming that we don't bounce 64-bit devices (or any device that can handle 36 bits). We'll need to talk in more detail about a solution to that problem, because knowing if a 64b dev *might* need to bounce (which is all this is really saying) requires more information. We also don't really have infrastructure to deal with holes in the visible dev memory, and I don't know if we want to handle that as well. I don't want to set the dma_ops to swiotlb unless we have to because there's a slight perf hit in running all the checks to see if an address needs to be bounced. Thanks, B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 4/5] powerpc: Add support for swiotlb on 32-bit
On Apr 20, 2009, at 1:31 PM, Kumar Gala wrote: On Apr 20, 2009, at 11:26 AM, Becky Bruce wrote: +static int ppc_swiotlb_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + + /* We are only intereted in device addition */ + if (action != BUS_NOTIFY_ADD_DEVICE) + return 0; + + if (dma_get_mask(dev) DMA_BIT_MASK(36)) + set_dma_ops(dev, swiotlb_dma_ops); + + return NOTIFY_DONE; +} + +static struct notifier_block ppc_swiotlb_plat_bus_notifier = { + .notifier_call = ppc_swiotlb_bus_notify, + .priority = 0, +}; + +static struct notifier_block ppc_swiotlb_of_bus_notifier = { + .notifier_call = ppc_swiotlb_bus_notify, + .priority = 0, +}; + +static int __init setup_bus_notifier(void) +{ + bus_register_notifier(platform_bus_type, + ppc_swiotlb_plat_bus_notifier); + bus_register_notifier(of_platform_bus_type, + ppc_swiotlb_of_bus_notifier); + + return 0; +} I think we should move all this into the platform code for now. I don't like having to duplicate it but that gives us the proper flexibility for now. Ugh, gross. I'd like to think about this some more. -B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] net/fec_mpc52xx: fix BUG on missing dma_ops
On Mar 30, 2009, at 9:25 PM, Grant Likely wrote: From: Grant Likely grant.lik...@secretlab.ca The driver triggers a BUG_ON() when allocating DMA buffers if the arch/powerpc dma_ops from the of_platform device are not copied into net_device structure. Signed-off-by: Grant Likely grant.lik...@secretlab.ca --- Becky, does this look better to you? Reviewed-by: Becky Bruce bec...@kernel.crashing.org I think this is OK now, and Kumar agrees Thanks! B g. drivers/net/fec_mpc52xx.c | 19 --- 1 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 049b0a7..f99463f 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -129,7 +129,8 @@ static void mpc52xx_fec_free_rx_buffers(struct net_device *dev, struct bcom_task struct sk_buff *skb; skb = bcom_retrieve_buffer(s, NULL, (struct bcom_bd **)bd); - dma_unmap_single(dev-dev, bd-skb_pa, skb-len, DMA_FROM_DEVICE); + dma_unmap_single(dev-dev.parent, bd-skb_pa, skb-len, +DMA_FROM_DEVICE); kfree_skb(skb); } } @@ -150,7 +151,7 @@ static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task bd = (struct bcom_fec_bd *)bcom_prepare_next_buffer(rxtsk); bd-status = FEC_RX_BUFFER_SIZE; - bd-skb_pa = dma_map_single(dev-dev, skb-data, + bd-skb_pa = dma_map_single(dev-dev.parent, skb-data, FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE); bcom_submit_next_buffer(rxtsk, skb); @@ -388,7 +389,8 @@ static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *d bcom_prepare_next_buffer(priv-tx_dmatsk); bd-status = skb-len | BCOM_FEC_TX_BD_TFD | BCOM_FEC_TX_BD_TC; - bd-skb_pa = dma_map_single(dev-dev, skb-data, skb-len, DMA_TO_DEVICE); + bd-skb_pa = dma_map_single(dev-dev.parent, skb-data, skb-len, + DMA_TO_DEVICE); bcom_submit_next_buffer(priv-tx_dmatsk, skb); @@ -430,7 +432,8 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id) struct bcom_fec_bd *bd; skb = bcom_retrieve_buffer(priv-tx_dmatsk, NULL, (struct bcom_bd **)bd); - dma_unmap_single(dev-dev, bd-skb_pa, skb-len, DMA_TO_DEVICE); + dma_unmap_single(dev-dev.parent, bd-skb_pa, skb-len, +DMA_TO_DEVICE); dev_kfree_skb_irq(skb); } @@ -455,7 +458,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) rskb = bcom_retrieve_buffer(priv-rx_dmatsk, status, (struct bcom_bd **)bd); - dma_unmap_single(dev-dev, bd-skb_pa, rskb-len, DMA_FROM_DEVICE); + dma_unmap_single(dev-dev.parent, bd-skb_pa, rskb-len, +DMA_FROM_DEVICE); /* Test for errors in received frame */ if (status BCOM_FEC_RX_BD_ERRORS) { @@ -464,7 +468,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) bcom_prepare_next_buffer(priv-rx_dmatsk); bd-status = FEC_RX_BUFFER_SIZE; - bd-skb_pa = dma_map_single(dev-dev, rskb-data, + bd-skb_pa = dma_map_single(dev-dev.parent, + rskb-data, FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE); bcom_submit_next_buffer(priv-rx_dmatsk, rskb); @@ -499,7 +504,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) bcom_prepare_next_buffer(priv-rx_dmatsk); bd-status = FEC_RX_BUFFER_SIZE; - bd-skb_pa = dma_map_single(dev-dev, skb-data, + bd-skb_pa = dma_map_single(dev-dev.parent, skb-data, FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE); bcom_submit_next_buffer(priv-rx_dmatsk, skb); ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: 8641D with linux 2.6.29 did'n show second cpu
On Mar 31, 2009, at 10:06 AM, Eduard Fuchs wrote: Hi, Am Dienstag 31 März 2009 15:20:21 schrieb Kumar Gala: On Mar 31, 2009, at 5:15 AM, Eduard Fuchs wrote: Hi, I'm testing the evaluation board from freescale (MPC8641DHPCN) with the latest linux kernel (2.6.29) and the second core seems disabled. CONFIG_SPM is enabled but the /proc/cpuinfo shows only one cpu. With original 2.6.27 kernel both cpu cores appears in /proc/cpuinfo. Has anyone an idea how can i enable the second core? Are you using u-boot? I can't remember if you need a newer u-boot to deal with changes in how we bring up the second core. Yes. My u-boot version is 2009.03. Are there some additional config keys for SMP support in u-boot? Hrm, I am able to reproduce this here - the second processor is reported as stuck and once we're booted, I only see one CPU online. Let me poke around and see if I can figure out what's going on here. Cheers, Becky ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] net/fec_mpc52xx: fix BUG on missing dma_ops
On Mar 30, 2009, at 1:53 PM, Grant Likely wrote: From: Grant Likely grant.lik...@secretlab.ca The driver triggers a BUG_ON() when allocating DMA buffers if the arch/powerpc dma_ops from the of_platform device are not copied into net_device structure. Signed-off-by: Grant Likely grant.lik...@secretlab.ca --- David, do you want to pick this one up right away, or should I merge it through Ben's powerpc tree? Grant, I really think you need to do what Kumar did for gianfar (http://patchwork.ozlabs.org/patch/24562/ ) - your patch just fixes the dma_ops problem, not the problem with getting to the correct archdata, which contains an offset (dma_data) that is used to form a bus address used in the various dma operations. Grep for get_dma_direct_offset in arch/powerpc and you'll see it used in the various dma operations. Cheers, B g. drivers/net/fec_mpc52xx.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 049b0a7..215207d 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -928,6 +928,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) if (!request_mem_region(mem.start, sizeof(struct mpc52xx_fec), DRIVER_NAME)) return -EBUSY; + /* Copy the PowerPC dma_ops from the of_device */ + set_dma_ops(ndev-dev, get_dma_ops(op-dev)); + /* Init ether ndev with what we have */ ndev-open = mpc52xx_fec_open; ndev-stop = mpc52xx_fec_close; ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] gianfar: pass the proper dev to DMA ops
On Mar 17, 2009, at 11:16 AM, Kumar Gala wrote: We need to be passing the of_platform device struct into the DMA ops as its the one that has the archdata setup to know which low-level DMA ops we should be using (not the net_device one). This isn't an issue until we expect the archdata to be setup correctly. Signed-off-by: Kumar Gala ga...@kernel.crashing.org Boots on 8641D stock config and gets rid of the panic I was seeing. Acked-by: Becky Bruce bec...@kernel.crashing.org Cheers, Becky --- Dave, This is for net-next. We are working on having per device dma ops for .30 and expect the struct device archdata to be setup properly but in .29 we still default to a direct DMA ops on ppc32 so this bug will never show up. - k drivers/net/gianfar.c | 34 ++ drivers/net/gianfar.h |3 ++- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index bed30ef..8659833 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -365,8 +365,10 @@ static int gfar_probe(struct of_device *ofdev, return -ENOMEM; priv = netdev_priv(dev); - priv-dev = dev; + priv-ndev = dev; + priv-ofdev = ofdev; priv-node = ofdev-node; + SET_NETDEV_DEV(dev, ofdev-dev); err = gfar_of_init(dev); @@ -538,7 +540,7 @@ static int gfar_remove(struct of_device *ofdev) dev_set_drvdata(ofdev-dev, NULL); iounmap(priv-regs); - free_netdev(priv-dev); + free_netdev(priv-ndev); return 0; } @@ -870,7 +872,7 @@ void stop_gfar(struct net_device *dev) free_skb_resources(priv); - dma_free_coherent(dev-dev, + dma_free_coherent(priv-ofdev-dev, sizeof(struct txbd8)*priv-tx_ring_size + sizeof(struct rxbd8)*priv-rx_ring_size, priv-tx_bd_base, @@ -892,12 +894,12 @@ static void free_skb_resources(struct gfar_private *priv) if (!priv-tx_skbuff[i]) continue; - dma_unmap_single(priv-dev-dev, txbdp-bufPtr, + dma_unmap_single(priv-ofdev-dev, txbdp-bufPtr, txbdp-length, DMA_TO_DEVICE); txbdp-lstatus = 0; for (j = 0; j skb_shinfo(priv-tx_skbuff[i])-nr_frags; j++) { txbdp++; - dma_unmap_page(priv-dev-dev, txbdp-bufPtr, + dma_unmap_page(priv-ofdev-dev, txbdp-bufPtr, txbdp-length, DMA_TO_DEVICE); } txbdp++; @@ -914,7 +916,7 @@ static void free_skb_resources(struct gfar_private *priv) if(priv-rx_skbuff != NULL) { for (i = 0; i priv-rx_ring_size; i++) { if (priv-rx_skbuff[i]) { - dma_unmap_single(priv-dev-dev, rxbdp-bufPtr, + dma_unmap_single(priv-ofdev-dev, rxbdp-bufPtr, priv-rx_buffer_size, DMA_FROM_DEVICE); @@ -980,7 +982,7 @@ int startup_gfar(struct net_device *dev) gfar_write(regs-imask, IMASK_INIT_CLEAR); /* Allocate memory for the buffer descriptors */ - vaddr = (unsigned long) dma_alloc_coherent(dev-dev, + vaddr = (unsigned long) dma_alloc_coherent(priv-ofdev-dev, sizeof (struct txbd8) * priv-tx_ring_size + sizeof (struct rxbd8) * priv-rx_ring_size, addr, GFP_KERNEL); @@ -1192,7 +1194,7 @@ err_rxalloc_fail: rx_skb_fail: free_skb_resources(priv); tx_skb_fail: - dma_free_coherent(dev-dev, + dma_free_coherent(priv-ofdev-dev, sizeof(struct txbd8)*priv-tx_ring_size + sizeof(struct rxbd8)*priv-rx_ring_size, priv-tx_bd_base, @@ -1345,7 +1347,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) if (i == nr_frags - 1) lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT); - bufaddr = dma_map_page(dev-dev, + bufaddr = dma_map_page(priv-ofdev-dev, skb_shinfo(skb)-frags[i].page, skb_shinfo(skb)-frags[i].page_offset, length, @@ -1377,7 +1379,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* setup the TxBD length and buffer pointer for the first BD */ priv-tx_skbuff[priv-skb_curtx] = skb; - txbdp_start-bufPtr = dma_map_single(dev-dev, skb-data, + txbdp_start-bufPtr = dma_map_single(priv-ofdev-dev, skb-data, skb_headlen(skb), DMA_TO_DEVICE); lstatus |= BD_LFLAG(TXBD_CRC
Re: [PATCH 1/3] powerpc/pci: Default to dma_direct_ops for pci dma_ops
On Feb 19, 2009, at 4:08 PM, Benjamin Krill wrote: * Kumar Gala | 2009-02-19 14:49:15 [-0600]: This will allow us to remove the ppc32 specific checks in get_dma_ops() that defaults to dma_direct_ops if the archdata is NULL. We really should always have archdata set to something going forward. Signed-off-by: Kumar Gala ga...@kernel.crashing.org Acked-by: Benjamin Krill b...@codiert.org Tested on ppc 86xx, looks good. Acked-by: Becky Bruce bec...@kernel.crashing.org -B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 2/3] powerpc: setup archdata for {of_}platform via a single platform_notify
On Feb 19, 2009, at 4:08 PM, Benjamin Krill wrote: * Kumar Gala | 2009-02-19 14:49:16 [-0600]: Since a number of powerpc chips are SoCs we end up having dma-able devices that are registered as platform or of_platform devices. We need to hook the archdata to setup proper dma_ops for these devices. In the short term the majority of these devices only need the direct_dma_ops as the platforms don't have any IOMMUs. In the future to enable 4G DMA support on ppc32 we can hook swiotlb ops. Signed-off-by: Kumar Gala ga...@kernel.crashing.org Acked-by: Benjamin Krill b...@codiert.org Tested on ppc 86xx, looks good. Acked-by: Becky Bruce bec...@kernel.crashing.org -B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH 3/3] powerpc: expect all devices calling dma ops to have archdata set
On Feb 19, 2009, at 4:08 PM, Benjamin Krill wrote: * Kumar Gala | 2009-02-19 14:49:17 [-0600]: Now that we set archdata for of_platform and platform devices via platform_notify() we no longer need to special case having a NULL device pointer or NULL archdata. It should be a driver error if this condition shows up and the driver should be fixed. Signed-off-by: Kumar Gala ga...@kernel.crashing.org Acked-by: Benjamin Krill b...@codiert.org Tested on ppc 86xx, looks good. Acked-by: Becky Bruce bec...@kernel.crashing.org -B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] powerpc/mm: Fix _PAGE_COHERENT support on classic ppc32 HW
On Feb 10, 2009, at 2:57 PM, Kumar Gala wrote: The following commit: commit 64b3d0e8122b422e879b23d42f9e0e8efbbf9744 Author: Benjamin Herrenschmidt b...@kernel.crashing.org Date: Thu Dec 18 19:13:51 2008 + powerpc/mm: Rework usage of _PAGE_COHERENT/NO_CACHE/GUARDED broke setting of the _PAGE_COHERENT bit in the PPC HW PTE. Since we now actually set _PAGE_COHERENT in the Linux PTE we shouldn't be clearing it out before we propogate it to the PPC HW PTE. Reported-by: Martyn Welch martyn.we...@gefanuc.com Signed-off-by: Kumar Gala ga...@kernel.crashing.org I've booted 8641 dual-core and run LTP to completion with an expected number of fails. So Acked-by: Becky Bruce bec...@kernel.crashing.org -B --- arch/powerpc/mm/hash_low_32.S |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/ hash_low_32.S index 67850ec..14af8ce 100644 --- a/arch/powerpc/mm/hash_low_32.S +++ b/arch/powerpc/mm/hash_low_32.S @@ -320,7 +320,7 @@ _GLOBAL(create_hpte) and r8,r8,r0/* writable if _RW _DIRTY */ rlwimi r5,r5,32-1,30,30/* _PAGE_USER - PP msb */ rlwimi r5,r5,32-2,31,31/* _PAGE_USER - PP lsb */ - ori r8,r8,0xe14 /* clear out reserved bits and M */ + ori r8,r8,0xe04 /* clear out reserved bits */ andcr8,r5,r8/* PP = user? (rwdirty? 2: 3): 0 */ BEGIN_FTR_SECTION rlwinm r8,r8,0,~_PAGE_COHERENT /* clear M (coherence not required) */ -- 1.5.6.6 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: Booting 2.6.29-rc3 on mpc8661d_hpcn failing
On Jan 30, 2009, at 8:42 AM, Kumar Gala wrote: On Jan 30, 2009, at 6:31 AM, Martyn Welch wrote: Hi Guys, It seems that 2.6.29-rc3 is not booting on the MPC8641 HPCN. I have just updated u-boot to the latest git to see if that improved matters, however I get stuck at the following. Any ideas? did you update your .dtb as well? We've changed the memory map for that board in the latest u-boot, which is why you need a new .dtb. If this still failing, let me know, and I'll give it a try on my board and see what's up since this is probably my fault :) Cheers, B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH] powerpc: Update 8641hpcn dts file to match latest u-boot
The newest revision of uboot reworks the memory map for this board to look more like the 85xx boards. Also, some regions which were far larger than the actual hardware have been scaled back to match the board, and the imaginary second flash bank has been removed. Rapidio and PCI are mutually exclusive in the hardware, and they now are occupying the same space in the address map. The Rapidio node is commented out of the .dts since PCI is the common use case. Signed-off-by: Becky Bruce bec...@kernel.crashing.org --- arch/powerpc/boot/dts/mpc8641_hpcn.dts | 56 ++- 1 files changed, 32 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts index d665e76..e79af90 100644 --- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts +++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts @@ -26,7 +26,7 @@ serial1 = serial1; pci0 = pci0; pci1 = pci1; - rapidio0 = rapidio0; + /* rapidio0 = rapidio0; */ }; cpus { @@ -62,18 +62,17 @@ reg = 0x 0x4000; // 1G at 0x0 }; - local...@f8005000 { + local...@ffe05000 { #address-cells = 2; #size-cells = 1; compatible = fsl,mpc8641-localbus, simple-bus; - reg = 0xf8005000 0x1000; + reg = 0xffe05000 0x1000; interrupts = 19 2; interrupt-parent = mpic; - ranges = 0 0 0xff80 0x0080 - 1 0 0xfe00 0x0100 - 2 0 0xf820 0x0010 - 3 0 0xf810 0x0010; + ranges = 0 0 0xef80 0x0080 + 2 0 0xffdf8000 0x8000 + 3 0 0xffdf 0x8000; fl...@0,0 { compatible = cfi-flash; @@ -103,13 +102,13 @@ }; }; - soc8...@f800 { + soc8...@ffe0 { #address-cells = 1; #size-cells = 1; device_type = soc; compatible = simple-bus; - ranges = 0x 0xf800 0x0010; - reg = 0xf800 0x1000; // CCSRBAR + ranges = 0x 0xffe0 0x0010; + reg = 0xffe0 0x1000; // CCSRBAR bus-frequency = 0; i...@3000 { @@ -295,17 +294,17 @@ }; }; - pci0: p...@f8008000 { + pci0: p...@ffe08000 { cell-index = 0; compatible = fsl,mpc8641-pcie; device_type = pci; #interrupt-cells = 1; #size-cells = 2; #address-cells = 3; - reg = 0xf8008000 0x1000; + reg = 0xffe08000 0x1000; bus-range = 0x0 0xff; ranges = 0x0200 0x0 0x8000 0x8000 0x0 0x2000 - 0x0100 0x0 0x 0xe200 0x0 0x0010; + 0x0100 0x0 0x 0xffc0 0x0 0x0001; clock-frequency = ; interrupt-parent = mpic; interrupts = 24 2; @@ -436,7 +435,7 @@ 0x0100 0x0 0x 0x0100 0x0 0x - 0x0 0x0010; + 0x0 0x0001; uli1...@0 { reg = 0 0 0 0 0; #size-cells = 2; @@ -446,7 +445,7 @@ 0x0 0x2000 0x0100 0x0 0x 0x0100 0x0 0x - 0x0 0x0010; + 0x0 0x0001; i...@1e { device_type = isa; #interrupt-cells = 2; @@ -504,17 +503,17 @@ }; - pci1: p...@f8009000 { + pci1: p...@ffe09000 { cell-index = 1; compatible = fsl,mpc8641-pcie; device_type = pci; #interrupt-cells = 1; #size-cells = 2; #address-cells = 3; - reg = 0xf8009000 0x1000; + reg = 0xffe09000 0x1000; bus-range = 0 0xff; ranges = 0x0200 0x0 0xa000 0xa000 0x0 0x2000 - 0x0100 0x0 0x 0xe300 0x0 0x0010; + 0x0100 0x0 0x 0xffc1 0x0 0x0001; clock-frequency = ; interrupt-parent = mpic; interrupts = 25 2; @@ -537,18
[PATCH] powerpc: Fix !CONFIG_PPC_NEED_DMA_SYNC_OPS build warning
Change #define stubs of dma_sync ops to be empty static inlines to avoid build warning. Signed-off-by: Becky Bruce [EMAIL PROTECTED] --- arch/powerpc/include/asm/dma-mapping.h | 41 +++ 1 files changed, 35 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 9063184..86cef7d 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -363,12 +363,41 @@ static inline void dma_sync_single_range_for_device(struct device *dev, size, direction); } #else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */ -#define dma_sync_single_for_cpu(d, h, s, dir) ((void)0) -#define dma_sync_single_for_device(d, h, s, dir) ((void)0) -#define dma_sync_single_range_for_cpu(d, h, o, s, dir) ((void)0) -#define dma_sync_single_range_for_device(d, h, o, s, dir) ((void)0) -#define dma_sync_sg_for_cpu(d, s, n, dir) ((void)0) -#define dma_sync_sg_for_device(d, s, n, dir) ((void)0) +static inline void dma_sync_single_for_cpu(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ +} + +static inline void dma_sync_single_for_device(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ +} + +static inline void dma_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sgl, int nents, + enum dma_data_direction direction) +{ +} + +static inline void dma_sync_sg_for_device(struct device *dev, + struct scatterlist *sgl, int nents, + enum dma_data_direction direction) +{ +} + +static inline void dma_sync_single_range_for_cpu(struct device *dev, + dma_addr_t dma_handle, unsigned long offset, size_t size, + enum dma_data_direction direction) +{ +} + +static inline void dma_sync_single_range_for_device(struct device *dev, + dma_addr_t dma_handle, unsigned long offset, size_t size, + enum dma_data_direction direction) +{ +} #endif static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -- 1.5.6.5 ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix dma_map_sg() cache flushing on non coherent platforms
On Nov 30, 2008, at 10:53 PM, Benjamin Herrenschmidt wrote: On PowerPC 4xx or other non cache coherent platforms, we lost the appropriate cache flushing in dma_map_sg() when merging the 32 and 64-bit DMA code. Signed-off-by: Benjamin Herrenschmidt [EMAIL PROTECTED] Acked-by: Becky Bruce [EMAIL PROTECTED] Sins of omission are always the hardest to catch. My apologies, and thanks! -B --- Oops .. nobody spotted that when Becky patches went in ! Paul: This is a 2.6.28 regression and should be merged asap arch/powerpc/kernel/dma.c |1 + 1 file changed, 1 insertion(+) --- linux-work.orig/arch/powerpc/kernel/dma.c 2008-12-01 15:44:55.0 +1100 +++ linux-work/arch/powerpc/kernel/dma.c 2008-12-01 15:45:13.0 +1100 @@ -75,6 +75,7 @@ static int dma_direct_map_sg(struct devi for_each_sg(sgl, sg, nents, i) { sg-dma_address = sg_phys(sg) + get_dma_direct_offset(dev); sg-dma_length = sg-length; + __dma_sync_page(sg_page(sg), sg-offset, sg-length, direction); } return nents; ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH V2] powerpc: Add sync_*_for_* to dma_ops
We need to swap these out once we start using swiotlb, so add them to dma_ops. Create CONFIG_PPC_NEED_DMA_SYNC_OPS Kconfig option; this is currently enabled automatically if we're CONFIG_NOT_COHERENT_CACHE. In the future, this will also be enabled for builds that need swiotlb. If PPC_NEED_DMA_SYNC_OPS is not defined, the dma_sync_*_for_* ops compile to nothing. Otherwise, they access the dma_ops pointers for the sync ops. This patch also changes dma_sync_single_range_* to actually sync the range - previously it was using a generous dma_sync_single. dma_sync_single_* is now implemented as a dma_sync_single_range with an offset of 0. Signed-off-by: Becky Bruce [EMAIL PROTECTED] --- arch/powerpc/Kconfig |4 ++ arch/powerpc/include/asm/dma-mapping.h | 93 +--- arch/powerpc/kernel/dma.c | 26 + 3 files changed, 92 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 525c13a..be4f99b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -285,6 +285,10 @@ config IOMMU_VMERGE config IOMMU_HELPER def_bool PPC64 +config PPC_NEED_DMA_SYNC_OPS + def_bool y + depends on NOT_COHERENT_CACHE + config HOTPLUG_CPU bool Support for enabling/disabling CPUs depends on SMP HOTPLUG EXPERIMENTAL (PPC_PSERIES || PPC_PMAC) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 3c4a2c2..9063184 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -76,6 +76,22 @@ struct dma_mapping_ops { dma_addr_t dma_address, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs); +#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS + void(*sync_single_range_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, unsigned long offset, + 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, + enum dma_data_direction direction); + void(*sync_sg_for_cpu)(struct device *hwdev, + struct scatterlist *sg, int nelems, + enum dma_data_direction direction); + void(*sync_sg_for_device)(struct device *hwdev, + struct scatterlist *sg, int nelems, + enum dma_data_direction direction); +#endif }; /* @@ -282,47 +298,78 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL); } +#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); - __dma_sync(bus_to_virt(dma_handle), size, direction); + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + dma_ops-sync_single_range_for_cpu(dev, dma_handle, 0, + size, direction); } static inline void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); - __dma_sync(bus_to_virt(dma_handle), size, direction); + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + dma_ops-sync_single_range_for_device(dev, dma_handle, + 0, size, direction); } static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { - struct scatterlist *sg; - int i; - - BUG_ON(direction == DMA_NONE); + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - for_each_sg(sgl, sg, nents, i) - __dma_sync_page(sg_page(sg), sg-offset, sg-length, direction); + BUG_ON(!dma_ops); + dma_ops-sync_sg_for_cpu(dev, sgl, nents, direction); } static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { - struct scatterlist *sg; - int i; + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - BUG_ON(direction == DMA_NONE); + BUG_ON(!dma_ops); + dma_ops-sync_sg_for_device(dev, sgl, nents, direction); +} + +static inline void
Re: [PATCH] powerpc: Add sync_*_for_* to dma_ops
On Nov 18, 2008, at 6:22 AM, Benjamin Herrenschmidt wrote: dma_addr_t dma_address, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs); + void(*sync_single_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction); + void(*sync_single_for_device)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + 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, + 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, + enum dma_data_direction direction); Can't we implement the first 2 using the next 2 and passing a 0 offset ? I mean, we're going to go through a function pointer, it's not like handling the offset was going to cost us something :-) Looking at the swiotlb code; I think that's a reasonable thing to do. Will respin. + void(*sync_sg_for_cpu)(struct device *hwdev, + struct scatterlist *sg, int nelems, + enum dma_data_direction direction); + void(*sync_sg_for_device)(struct device *hwdev, + struct scatterlist *sg, int nelems, + enum dma_data_direction direction); }; /* @@ -286,42 +306,75 @@ static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); - __dma_sync(bus_to_virt(dma_handle), size, direction); + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + if (dma_ops-sync_single_for_cpu != NULL) + dma_ops-sync_single_for_cpu(dev, dma_handle, size, +direction); } .../... The only objection that comes to mind here is that generally, you know that your platform is going to be coherent or not at compile time, and you don't want the above at all when it is (or won't need swiotlb). So maybe we could have a Kconfig trickery so that CONFIG_PPC_DMA_NEED_SYNC_OPS is set when either non coherent DMA is select'ed or swiotlb support is select'ed by one of the enabled platform. So if I enable only powermac, I get neither and don't get the bloody inlines :-) I thought about doing something like this, but didn't know if it was worth the ifdeffing/CONFIG foo that would ensue; I guess your response answers that question :) Thanks! B ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Add sync_*_for_* to dma_ops
On Nov 18, 2008, at 10:57 AM, Segher Boessenkool wrote: @@ -286,42 +306,75 @@ static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); Did you intend to remove this here? It would be nice to test for it even on platforms where the op is a nop; if there is an equivalent test in every implementation of the ops, remove it there instead (that's more source + binary code to remove, always a good thing ;-) ) You're right that we have lost this test in platforms which do not implement the sync ops, and if the test is useful, I can certainly move it. However, it will actually result in more code on the current ppc kernel, as there are 3x more dma_sync_* instances than there are actual dma_direct_* instances (and nobody else implements dma_sync_* :) Not that we're talking about a lot of code here, but it definitely won't make the kernel smaller since we just don't need a sync unless we're noncoherent which, thank insert deity here, is rare. With the swiotlb case, the check needs to be in the swiotlb code because there are other architectures that use the swiotlb code that do not use a structure to get to their dma_ops like we do. IA64, for example, sets up its dma_ops using config options and #defines the names of the various dma_ functions. They don't go through a dma_ops dereference, so the (possibly redundant for us) check in the swiotlb code would need to remain. So, the reason for moving it would be that we think it's still a useful check to have. I'm happy to move it in that case. Thanks, -Becky ___ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev
[PATCH] powerpc: Add sync_*_for_* to dma_ops
We need to swap these out once we start using swiotlb, so add them to dma_ops. When these are called, if the dma_op pointer for the specific function is NULL, we just do nothing - most of the 64-bit platforms don't actually need to do anything with the sync so we don't require a sync function to be implemented. Signed-off-by: Becky Bruce [EMAIL PROTECTED] --- arch/powerpc/include/asm/dma-mapping.h | 97 ++-- arch/powerpc/kernel/dma.c | 35 +++ 2 files changed, 102 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 3c4a2c2..7edab27 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -76,6 +76,26 @@ struct dma_mapping_ops { dma_addr_t dma_address, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs); + void(*sync_single_for_cpu)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction); + void(*sync_single_for_device)(struct device *hwdev, + dma_addr_t dma_handle, size_t size, + 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, + 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, + enum dma_data_direction direction); + void(*sync_sg_for_cpu)(struct device *hwdev, + struct scatterlist *sg, int nelems, + enum dma_data_direction direction); + void(*sync_sg_for_device)(struct device *hwdev, + struct scatterlist *sg, int nelems, + enum dma_data_direction direction); }; /* @@ -286,42 +306,75 @@ static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); - __dma_sync(bus_to_virt(dma_handle), size, direction); + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + if (dma_ops-sync_single_for_cpu != NULL) + dma_ops-sync_single_for_cpu(dev, dma_handle, size, +direction); } static inline void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - BUG_ON(direction == DMA_NONE); - __dma_sync(bus_to_virt(dma_handle), size, direction); + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + + if (dma_ops-sync_single_for_device != NULL) + dma_ops-sync_single_for_device(dev, dma_handle, + size, direction); } static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { - struct scatterlist *sg; - int i; + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - BUG_ON(direction == DMA_NONE); + BUG_ON(!dma_ops); - for_each_sg(sgl, sg, nents, i) - __dma_sync_page(sg_page(sg), sg-offset, sg-length, direction); + if (dma_ops-sync_sg_for_cpu != NULL) + dma_ops-sync_sg_for_cpu(dev, sgl, nents, direction); } static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { - struct scatterlist *sg; - int i; + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - BUG_ON(direction == DMA_NONE); + BUG_ON(!dma_ops); - for_each_sg(sgl, sg, nents, i) - __dma_sync_page(sg_page(sg), sg-offset, sg-length, direction); + if (dma_ops-sync_sg_for_device != NULL) + dma_ops-sync_sg_for_device(dev, sgl, nents, direction); +} + +static inline void dma_sync_single_range_for_cpu(struct device *dev, + dma_addr_t dma_handle, unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + + if (dma_ops-sync_single_range_for_cpu != NULL