[POWERPC] Make pSeries use the H_BULK_REMOVE hypervisor call
H_BULK_REMOVE lets us remove 4 entries from the MMU hash table with one hypervisor call. This uses it in pSeries_lpar_hpte_invalidate so we can tear down mappings with fewer hypervisor calls. Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
e56a6e20f3
commit
f03e64f2ca
@ -502,23 +502,64 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
|
||||
BUG_ON(lpar_rc != H_SUCCESS);
|
||||
}
|
||||
|
||||
/* Flag bits for H_BULK_REMOVE */
|
||||
#define HBR_REQUEST 0x4000000000000000UL
|
||||
#define HBR_RESPONSE 0x8000000000000000UL
|
||||
#define HBR_END 0xc000000000000000UL
|
||||
#define HBR_AVPN 0x0200000000000000UL
|
||||
#define HBR_ANDCOND 0x0100000000000000UL
|
||||
|
||||
/*
|
||||
* Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
|
||||
* lock.
|
||||
*/
|
||||
static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags = 0;
|
||||
unsigned long i, pix, rc;
|
||||
unsigned long flags;
|
||||
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
|
||||
int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
|
||||
unsigned long param[9];
|
||||
unsigned long va;
|
||||
unsigned long hash, index, shift, hidx, slot;
|
||||
real_pte_t pte;
|
||||
int psize;
|
||||
|
||||
if (lock_tlbie)
|
||||
spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
|
||||
|
||||
for (i = 0; i < number; i++)
|
||||
flush_hash_page(batch->vaddr[i], batch->pte[i],
|
||||
batch->psize, local);
|
||||
psize = batch->psize;
|
||||
pix = 0;
|
||||
for (i = 0; i < number; i++) {
|
||||
va = batch->vaddr[i];
|
||||
pte = batch->pte[i];
|
||||
pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
|
||||
hash = hpt_hash(va, shift);
|
||||
hidx = __rpte_to_hidx(pte, index);
|
||||
if (hidx & _PTEIDX_SECONDARY)
|
||||
hash = ~hash;
|
||||
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
|
||||
slot += hidx & _PTEIDX_GROUP_IX;
|
||||
param[pix] = HBR_REQUEST | HBR_AVPN | slot;
|
||||
param[pix+1] = hpte_encode_v(va, psize) & HPTE_V_AVPN;
|
||||
pix += 2;
|
||||
if (pix == 8) {
|
||||
rc = plpar_hcall9(H_BULK_REMOVE, param,
|
||||
param[0], param[1], param[2],
|
||||
param[3], param[4], param[5],
|
||||
param[6], param[7]);
|
||||
BUG_ON(rc != H_SUCCESS);
|
||||
pix = 0;
|
||||
}
|
||||
} pte_iterate_hashed_end();
|
||||
}
|
||||
if (pix) {
|
||||
param[pix] = HBR_END;
|
||||
rc = plpar_hcall9(H_BULK_REMOVE, param, param[0], param[1],
|
||||
param[2], param[3], param[4], param[5],
|
||||
param[6], param[7]);
|
||||
BUG_ON(rc != H_SUCCESS);
|
||||
}
|
||||
|
||||
if (lock_tlbie)
|
||||
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
|
||||
|
@ -168,6 +168,7 @@
|
||||
#define H_FREE_LOGICAL_LAN 0x118
|
||||
#define H_ADD_LOGICAL_LAN_BUFFER 0x11C
|
||||
#define H_SEND_LOGICAL_LAN 0x120
|
||||
#define H_BULK_REMOVE 0x124
|
||||
#define H_MULTICAST_CTRL 0x130
|
||||
#define H_SET_XDABR 0x134
|
||||
#define H_STUFF_TCE 0x138
|
||||
|
Loading…
Reference in New Issue
Block a user