diff options
author | Li Zhong <zhong@linux.vnet.ibm.com> | 2013-04-15 12:53:19 -0400 |
---|---|---|
committer | Michael Ellerman <michael@ellerman.id.au> | 2013-04-18 01:59:59 -0400 |
commit | b170bd3de6a7f6fbfba331e300751450f55d8822 (patch) | |
tree | d703646cc3179549eb40eb99741f04b887ec0637 /arch/powerpc/mm | |
parent | 2c3c0693d9cf06d7baf99cfdc10f9c4d40198c6b (diff) |
powerpc: Split the code trying to insert hpte repeatedly as an helper function
Move the logic trying to insert hpte in __hash_page_huge() to an helper
function, so it could also be used by others.
Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 35 | ||||
-rw-r--r-- | arch/powerpc/mm/hugetlbpage-hash64.c | 31 |
2 files changed, 41 insertions, 25 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index f410c3e12c1e..ead9fa84ffd9 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -1230,6 +1230,41 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) | |||
1230 | bad_page_fault(regs, address, SIGBUS); | 1230 | bad_page_fault(regs, address, SIGBUS); |
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | long hpte_insert_repeating(unsigned long hash, unsigned long vpn, | ||
1234 | unsigned long pa, unsigned long rflags, | ||
1235 | unsigned long vflags, int psize, int ssize) | ||
1236 | { | ||
1237 | unsigned long hpte_group; | ||
1238 | long slot; | ||
1239 | |||
1240 | repeat: | ||
1241 | hpte_group = ((hash & htab_hash_mask) * | ||
1242 | HPTES_PER_GROUP) & ~0x7UL; | ||
1243 | |||
1244 | /* Insert into the hash table, primary slot */ | ||
1245 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, vflags, | ||
1246 | psize, ssize); | ||
1247 | |||
1248 | /* Primary is full, try the secondary */ | ||
1249 | if (unlikely(slot == -1)) { | ||
1250 | hpte_group = ((~hash & htab_hash_mask) * | ||
1251 | HPTES_PER_GROUP) & ~0x7UL; | ||
1252 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, | ||
1253 | vflags | HPTE_V_SECONDARY, | ||
1254 | psize, ssize); | ||
1255 | if (slot == -1) { | ||
1256 | if (mftb() & 0x1) | ||
1257 | hpte_group = ((hash & htab_hash_mask) * | ||
1258 | HPTES_PER_GROUP)&~0x7UL; | ||
1259 | |||
1260 | ppc_md.hpte_remove(hpte_group); | ||
1261 | goto repeat; | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | return slot; | ||
1266 | } | ||
1267 | |||
1233 | #ifdef CONFIG_DEBUG_PAGEALLOC | 1268 | #ifdef CONFIG_DEBUG_PAGEALLOC |
1234 | static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) | 1269 | static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) |
1235 | { | 1270 | { |
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index edb4129b182a..b913f416d97a 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c | |||
@@ -14,6 +14,10 @@ | |||
14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
15 | #include <asm/machdep.h> | 15 | #include <asm/machdep.h> |
16 | 16 | ||
17 | extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn, | ||
18 | unsigned long pa, unsigned long rlags, | ||
19 | unsigned long vflags, int psize, int ssize); | ||
20 | |||
17 | int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | 21 | int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, |
18 | pte_t *ptep, unsigned long trap, int local, int ssize, | 22 | pte_t *ptep, unsigned long trap, int local, int ssize, |
19 | unsigned int shift, unsigned int mmu_psize) | 23 | unsigned int shift, unsigned int mmu_psize) |
@@ -83,7 +87,6 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | |||
83 | 87 | ||
84 | if (likely(!(old_pte & _PAGE_HASHPTE))) { | 88 | if (likely(!(old_pte & _PAGE_HASHPTE))) { |
85 | unsigned long hash = hpt_hash(vpn, shift, ssize); | 89 | unsigned long hash = hpt_hash(vpn, shift, ssize); |
86 | unsigned long hpte_group; | ||
87 | 90 | ||
88 | pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; | 91 | pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; |
89 | 92 | ||
@@ -97,30 +100,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | |||
97 | rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | | 100 | rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | |
98 | _PAGE_COHERENT | _PAGE_GUARDED)); | 101 | _PAGE_COHERENT | _PAGE_GUARDED)); |
99 | 102 | ||
100 | repeat: | 103 | slot = hpte_insert_repeating(hash, vpn, pa, rflags, 0, |
101 | hpte_group = ((hash & htab_hash_mask) * | 104 | mmu_psize, ssize); |
102 | HPTES_PER_GROUP) & ~0x7UL; | ||
103 | |||
104 | /* Insert into the hash table, primary slot */ | ||
105 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0, | ||
106 | mmu_psize, ssize); | ||
107 | |||
108 | /* Primary is full, try the secondary */ | ||
109 | if (unlikely(slot == -1)) { | ||
110 | hpte_group = ((~hash & htab_hash_mask) * | ||
111 | HPTES_PER_GROUP) & ~0x7UL; | ||
112 | slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, | ||
113 | HPTE_V_SECONDARY, | ||
114 | mmu_psize, ssize); | ||
115 | if (slot == -1) { | ||
116 | if (mftb() & 0x1) | ||
117 | hpte_group = ((hash & htab_hash_mask) * | ||
118 | HPTES_PER_GROUP)&~0x7UL; | ||
119 | |||
120 | ppc_md.hpte_remove(hpte_group); | ||
121 | goto repeat; | ||
122 | } | ||
123 | } | ||
124 | 105 | ||
125 | /* | 106 | /* |
126 | * Hypervisor failure. Restore old pte and return -1 | 107 | * Hypervisor failure. Restore old pte and return -1 |