diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2013-04-28 05:37:29 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-04-30 01:59:53 -0400 |
commit | cf9427b85e90bb1ff90e2397ff419691d983c68b (patch) | |
tree | 023cfcfe1875f79398dfa6028e23a245140d60dc /arch/powerpc/mm | |
parent | 0e5f35d0e4a8179cdfac115023f418126419e659 (diff) |
powerpc: New hugepage directory format
Change the hugepage directory format so that we can have leaf ptes directly
at page directory avoiding the allocation of hugepage directory.
With the new table format we have 3 cases for pgds and pmds:
(1) invalid (all zeroes)
(2) pointer to next table, as normal; bottom 6 bits == 0
(4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size of table
Instead of storing shift value in hugepd pointer we use mmu_psize_def index
so that we can fit all the supported hugepage size in 4 bits
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r-- | arch/powerpc/mm/hugetlbpage.c | 26 | ||||
-rw-r--r-- | arch/powerpc/mm/init_64.c | 3 |
2 files changed, 9 insertions, 20 deletions
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 5dc52d803ed8..b4e2f24a9b8f 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -48,23 +48,6 @@ static u64 gpage_freearray[MAX_NUMBER_GPAGES]; | |||
48 | static unsigned nr_gpages; | 48 | static unsigned nr_gpages; |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | static inline int shift_to_mmu_psize(unsigned int shift) | ||
52 | { | ||
53 | int psize; | ||
54 | |||
55 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) | ||
56 | if (mmu_psize_defs[psize].shift == shift) | ||
57 | return psize; | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) | ||
62 | { | ||
63 | if (mmu_psize_defs[mmu_psize].shift) | ||
64 | return mmu_psize_defs[mmu_psize].shift; | ||
65 | BUG(); | ||
66 | } | ||
67 | |||
68 | #define hugepd_none(hpd) ((hpd).pd == 0) | 51 | #define hugepd_none(hpd) ((hpd).pd == 0) |
69 | 52 | ||
70 | pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) | 53 | pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift) |
@@ -145,6 +128,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
145 | if (unlikely(!hugepd_none(*hpdp))) | 128 | if (unlikely(!hugepd_none(*hpdp))) |
146 | break; | 129 | break; |
147 | else | 130 | else |
131 | /* We use the old format for PPC_FSL_BOOK3E */ | ||
148 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; | 132 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; |
149 | } | 133 | } |
150 | /* If we bailed from the for loop early, an error occurred, clean up */ | 134 | /* If we bailed from the for loop early, an error occurred, clean up */ |
@@ -156,9 +140,15 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, | |||
156 | #else | 140 | #else |
157 | if (!hugepd_none(*hpdp)) | 141 | if (!hugepd_none(*hpdp)) |
158 | kmem_cache_free(cachep, new); | 142 | kmem_cache_free(cachep, new); |
159 | else | 143 | else { |
144 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
145 | hpdp->pd = (unsigned long)new | | ||
146 | (shift_to_mmu_psize(pshift) << 2); | ||
147 | #else | ||
160 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; | 148 | hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; |
161 | #endif | 149 | #endif |
150 | } | ||
151 | #endif | ||
162 | spin_unlock(&mm->page_table_lock); | 152 | spin_unlock(&mm->page_table_lock); |
163 | return 0; | 153 | return 0; |
164 | } | 154 | } |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 7e2246fb2f31..a56de85ad3b7 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -129,8 +129,7 @@ void pgtable_cache_add(unsigned shift, void (*ctor)(void *)) | |||
129 | align = max_t(unsigned long, align, minalign); | 129 | align = max_t(unsigned long, align, minalign); |
130 | name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); | 130 | name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); |
131 | new = kmem_cache_create(name, table_size, align, 0, ctor); | 131 | new = kmem_cache_create(name, table_size, align, 0, ctor); |
132 | PGT_CACHE(shift) = new; | 132 | pgtable_cache[shift - 1] = new; |
133 | |||
134 | pr_debug("Allocated pgtable cache for order %d\n", shift); | 133 | pr_debug("Allocated pgtable cache for order %d\n", shift); |
135 | } | 134 | } |
136 | 135 | ||