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>
This commit is contained in:
Родитель
45949ebe6c
Коммит
4ad90c8649
|
@ -201,6 +201,23 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* ptes must be 8*sizeof(unsigned long)
|
||||
*/
|
||||
static inline long plpar_pte_read_4(unsigned long flags, unsigned long ptex,
|
||||
unsigned long *ptes)
|
||||
|
||||
{
|
||||
long rc;
|
||||
unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
|
||||
|
||||
rc = plpar_hcall9(H_READ, retbuf, flags | H_READ_4, ptex);
|
||||
|
||||
memcpy(ptes, retbuf, 8*sizeof(unsigned long));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* plpar_pte_read_4_raw can be called in real mode.
|
||||
* ptes must be 8*sizeof(unsigned long)
|
||||
|
|
|
@ -315,48 +315,48 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
|
||||
static long __pSeries_lpar_hpte_find(unsigned long want_v, unsigned long hpte_group)
|
||||
{
|
||||
unsigned long dword0;
|
||||
unsigned long lpar_rc;
|
||||
unsigned long dummy_word1;
|
||||
unsigned long flags;
|
||||
long lpar_rc;
|
||||
unsigned long i, j;
|
||||
struct {
|
||||
unsigned long pteh;
|
||||
unsigned long ptel;
|
||||
} ptes[4];
|
||||
|
||||
/* Read 1 pte at a time */
|
||||
/* Do not need RPN to logical page translation */
|
||||
/* No cross CEC PFT access */
|
||||
flags = 0;
|
||||
for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) {
|
||||
|
||||
lpar_rc = plpar_pte_read(flags, slot, &dword0, &dummy_word1);
|
||||
lpar_rc = plpar_pte_read_4(0, hpte_group, (void *)ptes);
|
||||
if (lpar_rc != H_SUCCESS)
|
||||
continue;
|
||||
|
||||
BUG_ON(lpar_rc != H_SUCCESS);
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (HPTE_V_COMPARE(ptes[j].pteh, want_v) &&
|
||||
(ptes[j].pteh & HPTE_V_VALID))
|
||||
return i + j;
|
||||
}
|
||||
}
|
||||
|
||||
return dword0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize)
|
||||
{
|
||||
unsigned long hash;
|
||||
unsigned long i;
|
||||
long slot;
|
||||
unsigned long want_v, hpte_v;
|
||||
unsigned long hash;
|
||||
unsigned long want_v;
|
||||
unsigned long hpte_group;
|
||||
|
||||
hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
|
||||
want_v = hpte_encode_avpn(vpn, psize, ssize);
|
||||
|
||||
/* Bolted entries are always in the primary group */
|
||||
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
|
||||
for (i = 0; i < HPTES_PER_GROUP; i++) {
|
||||
hpte_v = pSeries_lpar_hpte_getword0(slot);
|
||||
|
||||
if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID))
|
||||
/* HPTE matches */
|
||||
return slot;
|
||||
++slot;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
|
||||
slot = __pSeries_lpar_hpte_find(want_v, hpte_group);
|
||||
if (slot < 0)
|
||||
return -1;
|
||||
return hpte_group + slot;
|
||||
}
|
||||
|
||||
static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
|
||||
unsigned long ea,
|
||||
|
|
Загрузка…
Ссылка в новой задаче