Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ad90c86 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Michael Ellerman
Browse files

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: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 45949ebe
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -201,6 +201,23 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
	return rc;
	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.
 * plpar_pte_read_4_raw can be called in real mode.
 * ptes must be 8*sizeof(unsigned long)
 * ptes must be 8*sizeof(unsigned long)
+27 −27
Original line number Original line Diff line number Diff line
@@ -315,47 +315,47 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
	return 0;
	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;
	long lpar_rc;
	unsigned long lpar_rc;
	unsigned long i, j;
	unsigned long dummy_word1;
	struct {
	unsigned long flags;
		unsigned long pteh;
		unsigned long ptel;
	} ptes[4];


	/* Read 1 pte at a time                        */
	for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) {
	/* Do not need RPN to logical page translation */
	/* No cross CEC PFT access                     */
	flags = 0;


	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)
static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize)
{
{
	unsigned long hash;
	unsigned long i;
	long slot;
	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);
	hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
	want_v = hpte_encode_avpn(vpn, psize, ssize);
	want_v = hpte_encode_avpn(vpn, psize, ssize);


	/* Bolted entries are always in the primary group */
	/* Bolted entries are always in the primary group */
	slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
	hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
	for (i = 0; i < HPTES_PER_GROUP; i++) {
	slot = __pSeries_lpar_hpte_find(want_v, hpte_group);
		hpte_v = pSeries_lpar_hpte_getword0(slot);
	if (slot < 0)

		if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID))
			/* HPTE matches */
			return slot;
		++slot;
	}

		return -1;
		return -1;
	return hpte_group + slot;
}
}


static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,