aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2013-10-11 20:22:39 -0400
committerScott Wood <scottwood@freescale.com>2014-01-09 18:52:20 -0500
commitbbead78c06e0ddda3cc53f81ecdaa2062a56247a (patch)
treeca0f0b945e697febcc710931269c722d3f512715 /arch
parent28efc35fe68dacbddc4b12c2fa8f2df1593a4ad3 (diff)
powerpc/fsl-book3e-64: Use paca for hugetlb TLB1 entry selection
This keeps usage coordinated for hugetlb and indirect entries, which should make entry selection more predictable and probably improve overall performance when mixing the two. Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/mm/hugetlbpage-book3e.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c
index 646c4bffaeba..5e4ee2573903 100644
--- a/arch/powerpc/mm/hugetlbpage-book3e.c
+++ b/arch/powerpc/mm/hugetlbpage-book3e.c
@@ -8,6 +8,44 @@
8#include <linux/mm.h> 8#include <linux/mm.h>
9#include <linux/hugetlb.h> 9#include <linux/hugetlb.h>
10 10
11#ifdef CONFIG_PPC_FSL_BOOK3E
12#ifdef CONFIG_PPC64
13static inline int tlb1_next(void)
14{
15 struct paca_struct *paca = get_paca();
16 struct tlb_core_data *tcd;
17 int this, next;
18
19 tcd = paca->tcd_ptr;
20 this = tcd->esel_next;
21
22 next = this + 1;
23 if (next >= tcd->esel_max)
24 next = tcd->esel_first;
25
26 tcd->esel_next = next;
27 return this;
28}
29#else
30static inline int tlb1_next(void)
31{
32 int index, ncams;
33
34 ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
35
36 index = __get_cpu_var(next_tlbcam_idx);
37
38 /* Just round-robin the entries and wrap when we hit the end */
39 if (unlikely(index == ncams - 1))
40 __get_cpu_var(next_tlbcam_idx) = tlbcam_index;
41 else
42 __get_cpu_var(next_tlbcam_idx)++;
43
44 return index;
45}
46#endif /* !PPC64 */
47#endif /* FSL */
48
11static inline int mmu_get_tsize(int psize) 49static inline int mmu_get_tsize(int psize)
12{ 50{
13 return mmu_psize_defs[psize].enc; 51 return mmu_psize_defs[psize].enc;
@@ -47,7 +85,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
47 struct mm_struct *mm; 85 struct mm_struct *mm;
48 86
49#ifdef CONFIG_PPC_FSL_BOOK3E 87#ifdef CONFIG_PPC_FSL_BOOK3E
50 int index, ncams; 88 int index;
51#endif 89#endif
52 90
53 if (unlikely(is_kernel_addr(ea))) 91 if (unlikely(is_kernel_addr(ea)))
@@ -77,18 +115,11 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
77 } 115 }
78 116
79#ifdef CONFIG_PPC_FSL_BOOK3E 117#ifdef CONFIG_PPC_FSL_BOOK3E
80 ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
81
82 /* We have to use the CAM(TLB1) on FSL parts for hugepages */ 118 /* We have to use the CAM(TLB1) on FSL parts for hugepages */
83 index = __get_cpu_var(next_tlbcam_idx); 119 index = tlb1_next();
84 mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1)); 120 mtspr(SPRN_MAS0, MAS0_ESEL(index) | MAS0_TLBSEL(1));
85
86 /* Just round-robin the entries and wrap when we hit the end */
87 if (unlikely(index == ncams - 1))
88 __get_cpu_var(next_tlbcam_idx) = tlbcam_index;
89 else
90 __get_cpu_var(next_tlbcam_idx)++;
91#endif 121#endif
122
92 mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize); 123 mas1 = MAS1_VALID | MAS1_TID(mm->context.id) | MAS1_TSIZE(tsize);
93 mas2 = ea & ~((1UL << shift) - 1); 124 mas2 = ea & ~((1UL << shift) - 1);
94 mas2 |= (pte_val(pte) >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK; 125 mas2 |= (pte_val(pte) >> PTE_WIMGE_SHIFT) & MAS2_WIMGE_MASK;