Commit d504bed6 authored by Michael Neuling's avatar Michael Neuling Committed by Benjamin Herrenschmidt

powerpc/kexec: Speedup kexec hash PTE tear down

Currently for kexec the PTE tear down on 1TB segment systems normally
requires 3 hcalls for each PTE removal. On a machine with 32GB of
memory it can take around a minute to remove all the PTEs.

This optimises the path so that we only remove PTEs that are valid.
It also uses the read 4 PTEs at once HCALL.  For the common case where
a PTEs is invalid in a 1TB segment, this turns the 3 HCALLs per PTE
down to 1 HCALL per 4 PTEs.

This gives an > 10x speedup in kexec times on PHYP, taking a 32GB
machine from around 1 minute down to a few seconds.
Signed-off-by: default avatarMichael Neuling <mikey@neuling.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent f90ece28
...@@ -367,21 +367,28 @@ static void pSeries_lpar_hptab_clear(void) ...@@ -367,21 +367,28 @@ static void pSeries_lpar_hptab_clear(void)
{ {
unsigned long size_bytes = 1UL << ppc64_pft_size; unsigned long size_bytes = 1UL << ppc64_pft_size;
unsigned long hpte_count = size_bytes >> 4; unsigned long hpte_count = size_bytes >> 4;
unsigned long dummy1, dummy2, dword0; struct {
unsigned long pteh;
unsigned long ptel;
} ptes[4];
long lpar_rc; long lpar_rc;
int i; int i, j;
/* TODO: Use bulk call */ /* Read in batches of 4,
for (i = 0; i < hpte_count; i++) { * invalidate only valid entries not in the VRMA
/* dont remove HPTEs with VRMA mappings */ * hpte_count will be a multiple of 4
lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG, */
&dummy1, &dummy2); for (i = 0; i < hpte_count; i += 4) {
if (lpar_rc == H_NOT_FOUND) { lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes);
lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1); if (lpar_rc != H_SUCCESS)
if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK) continue;
!= HPTE_V_VRMA_MASK)) for (j = 0; j < 4; j++){
/* Can be hpte for 1TB Seg. So remove it */ if ((ptes[j].pteh & HPTE_V_VRMA_MASK) ==
plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); HPTE_V_VRMA_MASK)
continue;
if (ptes[j].pteh & HPTE_V_VALID)
plpar_pte_remove_raw(0, i + j, 0,
&(ptes[j].pteh), &(ptes[j].ptel));
} }
} }
} }
......
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