diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2015-11-30 22:36:59 -0500 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-12-13 23:19:17 -0500 |
commit | 4ad90c864989337e7946f456478b6417325689d0 (patch) | |
tree | 468b25b8e496092ad8f32db383455f8f9261fbca /arch | |
parent | 45949ebe6c748cba93c1dd6ab9d03190f862ecf7 (diff) |
powerpc/mm: Use H_READ with H_READ_4
This will bulk read 4 hash pte slot entries and should reduce the loop
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/plpar_wrappers.h | 17 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 54 |
2 files changed, 44 insertions, 27 deletions
diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h index 67859edbf8fd..1b394247afc2 100644 --- a/arch/powerpc/include/asm/plpar_wrappers.h +++ b/arch/powerpc/include/asm/plpar_wrappers.h | |||
@@ -202,6 +202,23 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex, | |||
202 | } | 202 | } |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * ptes must be 8*sizeof(unsigned long) | ||
206 | */ | ||
207 | static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex, | ||
208 | unsigned long *ptes) | ||
209 | |||
210 | { | ||
211 | long rc; | ||
212 | unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; | ||
213 | |||
214 | rc = plpar_hcall9(H_READ, retbuf, flags | H_READ_4, ptex); | ||
215 | |||
216 | memcpy(ptes, retbuf, 8*sizeof(unsigned long)); | ||
217 | |||
218 | return rc; | ||
219 | } | ||
220 | |||
221 | /* | ||
205 | * plpar_pte_read_4_raw can be called in real mode. | 222 | * plpar_pte_read_4_raw can be called in real mode. |
206 | * ptes must be 8*sizeof(unsigned long) | 223 | * ptes must be 8*sizeof(unsigned long) |
207 | */ | 224 | */ |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 6d46547871aa..477290ad855e 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -315,48 +315,48 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot, | |||
315 | return 0; | 315 | return 0; |
316 | } | 316 | } |
317 | 317 | ||
318 | static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot) | 318 | static long __pSeries_lpar_hpte_find(unsigned long want_v, unsigned long hpte_group) |
319 | { | 319 | { |
320 | unsigned long dword0; | 320 | long lpar_rc; |
321 | unsigned long lpar_rc; | 321 | unsigned long i, j; |
322 | unsigned long dummy_word1; | 322 | struct { |
323 | unsigned long flags; | 323 | unsigned long pteh; |
324 | unsigned long ptel; | ||
325 | } ptes[4]; | ||
324 | 326 | ||
325 | /* Read 1 pte at a time */ | 327 | for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) { |
326 | /* Do not need RPN to logical page translation */ | ||
327 | /* No cross CEC PFT access */ | ||
328 | flags = 0; | ||
329 | 328 | ||
330 | lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1); | 329 | lpar_rc = plpar_pte_read_4(0, hpte_group, (void *)ptes); |
330 | if (lpar_rc != H_SUCCESS) | ||
331 | continue; | ||
331 | 332 | ||
332 | BUG_ON(lpar_rc != H_SUCCESS); | 333 | for (j = 0; j < 4; j++) { |
334 | if (HPTE_V_COMPARE(ptes[j].pteh, want_v) && | ||
335 | (ptes[j].pteh & HPTE_V_VALID)) | ||
336 | return i + j; | ||
337 | } | ||
338 | } | ||
333 | 339 | ||
334 | return dword0; | 340 | return -1; |
335 | } | 341 | } |
336 | 342 | ||
337 | static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize) | 343 | static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize) |
338 | { | 344 | { |
339 | unsigned long hash; | ||
340 | unsigned long i; | ||
341 | long slot; | 345 | long slot; |
342 | unsigned long want_v, hpte_v; | 346 | unsigned long hash; |
347 | unsigned long want_v; | ||
348 | unsigned long hpte_group; | ||
343 | 349 | ||
344 | hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize); | 350 | hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize); |
345 | want_v = hpte_encode_avpn(vpn, psize, ssize); | 351 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
346 | 352 | ||
347 | /* Bolted entries are always in the primary group */ | 353 | /* Bolted entries are always in the primary group */ |
348 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | 354 | hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP; |
349 | for (i = 0; i < HPTES_PER_GROUP; i++) { | 355 | slot = __pSeries_lpar_hpte_find(want_v, hpte_group); |
350 | hpte_v = pSeries_lpar_hpte_getword0(slot); | 356 | if (slot < 0) |
351 | 357 | return -1; | |
352 | if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID)) | 358 | return hpte_group + slot; |
353 | /* HPTE matches */ | 359 | } |
354 | return slot; | ||
355 | ++slot; | ||
356 | } | ||
357 | |||
358 | return -1; | ||
359 | } | ||
360 | 360 | ||
361 | static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, | 361 | static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, |
362 | unsigned long ea, | 362 | unsigned long ea, |