Commit fa1f8ae8 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Benjamin Herrenschmidt

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: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent b0aa44a3
...@@ -57,10 +57,10 @@ struct machdep_calls { ...@@ -57,10 +57,10 @@ struct machdep_calls {
void (*hpte_removebolted)(unsigned long ea, void (*hpte_removebolted)(unsigned long ea,
int psize, int ssize); int psize, int ssize);
void (*flush_hash_range)(unsigned long number, int local); void (*flush_hash_range)(unsigned long number, int local);
void (*hugepage_invalidate)(struct mm_struct *mm, void (*hugepage_invalidate)(unsigned long vsid,
unsigned long addr,
unsigned char *hpte_slot_array, unsigned char *hpte_slot_array,
unsigned long addr, int psize); int psize, int ssize);
/* special for kexec, to be called in real mode, linear mapping is /* special for kexec, to be called in real mode, linear mapping is
* destroyed as well */ * destroyed as well */
void (*hpte_clear_all)(void); void (*hpte_clear_all)(void);
......
...@@ -412,18 +412,18 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, ...@@ -412,18 +412,18 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
local_irq_restore(flags); local_irq_restore(flags);
} }
static void native_hugepage_invalidate(struct mm_struct *mm, static void native_hugepage_invalidate(unsigned long vsid,
unsigned long addr,
unsigned char *hpte_slot_array, unsigned char *hpte_slot_array,
unsigned long addr, int psize) int psize, int ssize)
{ {
int ssize = 0, i; int i, lock_tlbie;
int lock_tlbie;
struct hash_pte *hptep; struct hash_pte *hptep;
int actual_psize = MMU_PAGE_16M; int actual_psize = MMU_PAGE_16M;
unsigned int max_hpte_count, valid; unsigned int max_hpte_count, valid;
unsigned long flags, s_addr = addr; unsigned long flags, s_addr = addr;
unsigned long hpte_v, want_v, shift; unsigned long hpte_v, want_v, shift;
unsigned long hidx, vpn = 0, vsid, hash, slot; unsigned long hidx, vpn = 0, hash, slot;
shift = mmu_psize_defs[psize].shift; shift = mmu_psize_defs[psize].shift;
max_hpte_count = 1U << (PMD_SHIFT - shift); max_hpte_count = 1U << (PMD_SHIFT - shift);
...@@ -437,15 +437,6 @@ static void native_hugepage_invalidate(struct mm_struct *mm, ...@@ -437,15 +437,6 @@ static void native_hugepage_invalidate(struct mm_struct *mm,
/* get the vpn */ /* get the vpn */
addr = s_addr + (i * (1ul << shift)); addr = s_addr + (i * (1ul << shift));
if (!is_kernel_addr(addr)) {
ssize = user_segment_size(addr);
vsid = get_vsid(mm->context.id, addr, ssize);
WARN_ON(vsid == 0);
} else {
vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
ssize = mmu_kernel_ssize;
}
vpn = hpt_vpn(addr, vsid, ssize); vpn = hpt_vpn(addr, vsid, ssize);
hash = hpt_hash(vpn, shift, ssize); hash = hpt_hash(vpn, shift, ssize);
if (hidx & _PTEIDX_SECONDARY) if (hidx & _PTEIDX_SECONDARY)
......
...@@ -745,12 +745,21 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, ...@@ -745,12 +745,21 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
if (!hpte_slot_array) if (!hpte_slot_array)
return; return;
/* get the base page size */ /* get the base page size,vsid and segment size */
psize = get_slice_psize(mm, s_addr); psize = get_slice_psize(mm, s_addr);
if (!is_kernel_addr(s_addr)) {
ssize = user_segment_size(s_addr);
vsid = get_vsid(mm->context.id, s_addr, ssize);
WARN_ON(vsid == 0);
} else {
vsid = get_kernel_vsid(s_addr, mmu_kernel_ssize);
ssize = mmu_kernel_ssize;
}
if (ppc_md.hugepage_invalidate) if (ppc_md.hugepage_invalidate)
return ppc_md.hugepage_invalidate(mm, hpte_slot_array, return ppc_md.hugepage_invalidate(vsid, s_addr,
s_addr, psize); hpte_slot_array,
psize, ssize);
/* /*
* No bluk hpte removal support, invalidate each entry * No bluk hpte removal support, invalidate each entry
*/ */
...@@ -768,15 +777,6 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, ...@@ -768,15 +777,6 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
/* get the vpn */ /* get the vpn */
addr = s_addr + (i * (1ul << shift)); addr = s_addr + (i * (1ul << shift));
if (!is_kernel_addr(addr)) {
ssize = user_segment_size(addr);
vsid = get_vsid(mm->context.id, addr, ssize);
WARN_ON(vsid == 0);
} else {
vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
ssize = mmu_kernel_ssize;
}
vpn = hpt_vpn(addr, vsid, ssize); vpn = hpt_vpn(addr, vsid, ssize);
hash = hpt_hash(vpn, shift, ssize); hash = hpt_hash(vpn, shift, ssize);
if (hidx & _PTEIDX_SECONDARY) if (hidx & _PTEIDX_SECONDARY)
......
...@@ -431,16 +431,17 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot, ...@@ -431,16 +431,17 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
} }
static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm, static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
unsigned long addr,
unsigned char *hpte_slot_array, unsigned char *hpte_slot_array,
unsigned long addr, int psize) int psize, int ssize)
{ {
int ssize = 0, i, index = 0; int i, index = 0;
unsigned long s_addr = addr; unsigned long s_addr = addr;
unsigned int max_hpte_count, valid; unsigned int max_hpte_count, valid;
unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH]; unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH];
unsigned long slot_array[PPC64_HUGE_HPTE_BATCH]; unsigned long slot_array[PPC64_HUGE_HPTE_BATCH];
unsigned long shift, hidx, vpn = 0, vsid, hash, slot; unsigned long shift, hidx, vpn = 0, hash, slot;
shift = mmu_psize_defs[psize].shift; shift = mmu_psize_defs[psize].shift;
max_hpte_count = 1U << (PMD_SHIFT - shift); max_hpte_count = 1U << (PMD_SHIFT - shift);
...@@ -453,15 +454,6 @@ static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm, ...@@ -453,15 +454,6 @@ static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm,
/* get the vpn */ /* get the vpn */
addr = s_addr + (i * (1ul << shift)); addr = s_addr + (i * (1ul << shift));
if (!is_kernel_addr(addr)) {
ssize = user_segment_size(addr);
vsid = get_vsid(mm->context.id, addr, ssize);
WARN_ON(vsid == 0);
} else {
vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
ssize = mmu_kernel_ssize;
}
vpn = hpt_vpn(addr, vsid, ssize); vpn = hpt_vpn(addr, vsid, ssize);
hash = hpt_hash(vpn, shift, ssize); hash = hpt_hash(vpn, shift, ssize);
if (hidx & _PTEIDX_SECONDARY) if (hidx & _PTEIDX_SECONDARY)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment