Skip to content

Commit

Permalink
powerpc/mm/radix: Use ptep_get_and_clear_full when clearing pte for f…
Browse files Browse the repository at this point in the history
…ull mm

This helps us to do some optimization for application exit case, where we can
skip the DD1 style pte update sequence.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Tested-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Aneesh Kumar K.V authored and Michael Ellerman committed Feb 15, 2017
1 parent ca94573 commit f4894b8
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
17 changes: 17 additions & 0 deletions arch/powerpc/include/asm/book3s/64/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,23 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
return __pte(old);
}

#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
unsigned long addr,
pte_t *ptep, int full)
{
if (full && radix_enabled()) {
/*
* Let's skip the DD1 style pte update here. We know that
* this is a full mm pte clear and hence can be sure there is
* no parallel set_pte.
*/
return radix__ptep_get_and_clear_full(mm, addr, ptep, full);
}
return ptep_get_and_clear(mm, addr, ptep);
}


static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t * ptep)
{
Expand Down
23 changes: 22 additions & 1 deletion arch/powerpc/include/asm/book3s/64/radix.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,

unsigned long new_pte;

old_pte = __radix_pte_update(ptep, ~0, 0);
old_pte = __radix_pte_update(ptep, ~0ul, 0);
/*
* new value of pte
*/
Expand All @@ -157,6 +157,27 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,
return old_pte;
}

static inline pte_t radix__ptep_get_and_clear_full(struct mm_struct *mm,
unsigned long addr,
pte_t *ptep, int full)
{
unsigned long old_pte;

if (full) {
/*
* If we are trying to clear the pte, we can skip
* the DD1 pte update sequence and batch the tlb flush. The
* tlb flush batching is done by mmu gather code. We
* still keep the cmp_xchg update to make sure we get
* correct R/C bit which might be updated via Nest MMU.
*/
old_pte = __radix_pte_update(ptep, ~0ul, 0);
} else
old_pte = radix__pte_update(mm, addr, ptep, ~0ul, 0, 0);

return __pte(old_pte);
}

/*
* Set the dirty and/or accessed bits atomically in a linux PTE, this
* function doesn't need to invalidate tlb.
Expand Down

0 comments on commit f4894b8

Please sign in to comment.