aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2014-08-13 03:01:58 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-13 04:20:38 -0400
commitfa1f8ae80f8bb996594167ff4750a0b0a5a5bb5d (patch)
treef2ca5e2cde1b9d9d9fbe03316231db8eda125de2
parentb0aa44a3dfae3d8f45bd1264349aa87f87b7774f (diff)
powerpc/thp: Don't recompute vsid and ssize in loop on invalidate
The segment identifier and segment size will remain the same in the loop, So we can compute it outside. We also change the hugepage_invalidate interface so that we can use it the later patch CC: <stable@vger.kernel.org> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/machdep.h6
-rw-r--r--arch/powerpc/mm/hash_native_64.c19
-rw-r--r--arch/powerpc/mm/pgtable_64.c24
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c20
4 files changed, 26 insertions, 43 deletions
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 44e90516519b..b125ceab149c 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -57,10 +57,10 @@ struct machdep_calls {
57 void (*hpte_removebolted)(unsigned long ea, 57 void (*hpte_removebolted)(unsigned long ea,
58 int psize, int ssize); 58 int psize, int ssize);
59 void (*flush_hash_range)(unsigned long number, int local); 59 void (*flush_hash_range)(unsigned long number, int local);
60 void (*hugepage_invalidate)(struct mm_struct *mm, 60 void (*hugepage_invalidate)(unsigned long vsid,
61 unsigned long addr,
61 unsigned char *hpte_slot_array, 62 unsigned char *hpte_slot_array,
62 unsigned long addr, int psize); 63 int psize, int ssize);
63
64 /* special for kexec, to be called in real mode, linear mapping is 64 /* special for kexec, to be called in real mode, linear mapping is
65 * destroyed as well */ 65 * destroyed as well */
66 void (*hpte_clear_all)(void); 66 void (*hpte_clear_all)(void);
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index cf1d325eae8b..fb89d7695a9a 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -412,18 +412,18 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
412 local_irq_restore(flags); 412 local_irq_restore(flags);
413} 413}
414 414
415static void native_hugepage_invalidate(struct mm_struct *mm, 415static void native_hugepage_invalidate(unsigned long vsid,
416 unsigned long addr,
416 unsigned char *hpte_slot_array, 417 unsigned char *hpte_slot_array,
417 unsigned long addr, int psize) 418 int psize, int ssize)
418{ 419{
419 int ssize = 0, i; 420 int i, lock_tlbie;
420 int lock_tlbie;
421 struct hash_pte *hptep; 421 struct hash_pte *hptep;
422 int actual_psize = MMU_PAGE_16M; 422 int actual_psize = MMU_PAGE_16M;
423 unsigned int max_hpte_count, valid; 423 unsigned int max_hpte_count, valid;
424 unsigned long flags, s_addr = addr; 424 unsigned long flags, s_addr = addr;
425 unsigned long hpte_v, want_v, shift; 425 unsigned long hpte_v, want_v, shift;
426 unsigned long hidx, vpn = 0, vsid, hash, slot; 426 unsigned long hidx, vpn = 0, hash, slot;
427 427
428 shift = mmu_psize_defs[psize].shift; 428 shift = mmu_psize_defs[psize].shift;
429 max_hpte_count = 1U << (PMD_SHIFT - shift); 429 max_hpte_count = 1U << (PMD_SHIFT - shift);
@@ -437,15 +437,6 @@ static void native_hugepage_invalidate(struct mm_struct *mm,
437 437
438 /* get the vpn */ 438 /* get the vpn */
439 addr = s_addr + (i * (1ul << shift)); 439 addr = s_addr + (i * (1ul << shift));
440 if (!is_kernel_addr(addr)) {
441 ssize = user_segment_size(addr);
442 vsid = get_vsid(mm->context.id, addr, ssize);
443 WARN_ON(vsid == 0);
444 } else {
445 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
446 ssize = mmu_kernel_ssize;
447 }
448
449 vpn = hpt_vpn(addr, vsid, ssize); 440 vpn = hpt_vpn(addr, vsid, ssize);
450 hash = hpt_hash(vpn, shift, ssize); 441 hash = hpt_hash(vpn, shift, ssize);
451 if (hidx & _PTEIDX_SECONDARY) 442 if (hidx & _PTEIDX_SECONDARY)
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 3b3c4d34c7a0..5039f3b04d6e 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -745,12 +745,21 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
745 if (!hpte_slot_array) 745 if (!hpte_slot_array)
746 return; 746 return;
747 747
748 /* get the base page size */ 748 /* get the base page size,vsid and segment size */
749 psize = get_slice_psize(mm, s_addr); 749 psize = get_slice_psize(mm, s_addr);
750 if (!is_kernel_addr(s_addr)) {
751 ssize = user_segment_size(s_addr);
752 vsid = get_vsid(mm->context.id, s_addr, ssize);
753 WARN_ON(vsid == 0);
754 } else {
755 vsid = get_kernel_vsid(s_addr, mmu_kernel_ssize);
756 ssize = mmu_kernel_ssize;
757 }
750 758
751 if (ppc_md.hugepage_invalidate) 759 if (ppc_md.hugepage_invalidate)
752 return ppc_md.hugepage_invalidate(mm, hpte_slot_array, 760 return ppc_md.hugepage_invalidate(vsid, s_addr,
753 s_addr, psize); 761 hpte_slot_array,
762 psize, ssize);
754 /* 763 /*
755 * No bluk hpte removal support, invalidate each entry 764 * No bluk hpte removal support, invalidate each entry
756 */ 765 */
@@ -768,15 +777,6 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
768 777
769 /* get the vpn */ 778 /* get the vpn */
770 addr = s_addr + (i * (1ul << shift)); 779 addr = s_addr + (i * (1ul << shift));
771 if (!is_kernel_addr(addr)) {
772 ssize = user_segment_size(addr);
773 vsid = get_vsid(mm->context.id, addr, ssize);
774 WARN_ON(vsid == 0);
775 } else {
776 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
777 ssize = mmu_kernel_ssize;
778 }
779
780 vpn = hpt_vpn(addr, vsid, ssize); 780 vpn = hpt_vpn(addr, vsid, ssize);
781 hash = hpt_hash(vpn, shift, ssize); 781 hash = hpt_hash(vpn, shift, ssize);
782 if (hidx & _PTEIDX_SECONDARY) 782 if (hidx & _PTEIDX_SECONDARY)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index fbfcef514aa7..34e64237fff9 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -431,16 +431,17 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
431 spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); 431 spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
432} 432}
433 433
434static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm, 434static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
435 unsigned char *hpte_slot_array, 435 unsigned long addr,
436 unsigned long addr, int psize) 436 unsigned char *hpte_slot_array,
437 int psize, int ssize)
437{ 438{
438 int ssize = 0, i, index = 0; 439 int i, index = 0;
439 unsigned long s_addr = addr; 440 unsigned long s_addr = addr;
440 unsigned int max_hpte_count, valid; 441 unsigned int max_hpte_count, valid;
441 unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH]; 442 unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH];
442 unsigned long slot_array[PPC64_HUGE_HPTE_BATCH]; 443 unsigned long slot_array[PPC64_HUGE_HPTE_BATCH];
443 unsigned long shift, hidx, vpn = 0, vsid, hash, slot; 444 unsigned long shift, hidx, vpn = 0, hash, slot;
444 445
445 shift = mmu_psize_defs[psize].shift; 446 shift = mmu_psize_defs[psize].shift;
446 max_hpte_count = 1U << (PMD_SHIFT - shift); 447 max_hpte_count = 1U << (PMD_SHIFT - shift);
@@ -453,15 +454,6 @@ static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm,
453 454
454 /* get the vpn */ 455 /* get the vpn */
455 addr = s_addr + (i * (1ul << shift)); 456 addr = s_addr + (i * (1ul << shift));
456 if (!is_kernel_addr(addr)) {
457 ssize = user_segment_size(addr);
458 vsid = get_vsid(mm->context.id, addr, ssize);
459 WARN_ON(vsid == 0);
460 } else {
461 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
462 ssize = mmu_kernel_ssize;
463 }
464
465 vpn = hpt_vpn(addr, vsid, ssize); 457 vpn = hpt_vpn(addr, vsid, ssize);
466 hash = hpt_hash(vpn, shift, ssize); 458 hash = hpt_hash(vpn, shift, ssize);
467 if (hidx & _PTEIDX_SECONDARY) 459 if (hidx & _PTEIDX_SECONDARY)