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

Commit c2c1accd authored by Zachary Amsden's avatar Zachary Amsden Committed by Andi Kleen
Browse files

[PATCH] i386: pte clear optimization



When exiting from an address space, no special hypervisor notification of page
table updates needs to occur; direct page table hypervisors, such as Xen,
switch to another address space first (init_mm) and unprotects the page tables
to avoid the cost of trapping to the hypervisor for each pte_clear.  Shadow
mode hypervisors, such as VMI and lhype don't need to do the extra work of
calling through paravirt-ops, and can just directly clear the page table
entries without notifiying the hypervisor, since all the page tables are about
to be freed.

So introduce native_pte_clear functions which bypass any paravirt-ops
notification.  This results in a significant performance win for VMI and
removes some indirect calls from zap_pte_range.

Note the 3-level paging already had a native_pte_clear function, thus
demanding argument conformance and extra args for the 2-level definition.

Signed-off-by: default avatarZachary Amsden <zach@vmware.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent df3624aa
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
#define pte_clear(mm,addr,xp)	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)

static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *xp)
{
	*xp = __pte(0);
}

static inline pte_t native_ptep_get_and_clear(pte_t *xp)
{
	return __pte(xchg(&xp->pte_low, 0));
+1 −1
Original line number Diff line number Diff line
@@ -344,7 +344,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long
	pte_t pte;
	if (full) {
		pte = *ptep;
		pte_clear(mm, addr, ptep);
		native_pte_clear(mm, addr, ptep);
	} else {
		pte = ptep_get_and_clear(mm, addr, ptep);
	}