aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2015-11-30 22:36:59 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2015-12-13 23:19:17 -0500
commit4ad90c864989337e7946f456478b6417325689d0 (patch)
tree468b25b8e496092ad8f32db383455f8f9261fbca /arch
parent45949ebe6c748cba93c1dd6ab9d03190f862ecf7 (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.h17
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c54
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 */
207static 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
318static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot) 318static 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
337static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize) 343static 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
361static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, 361static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
362 unsigned long ea, 362 unsigned long ea,