Skip to content

Commit

Permalink
tlb: mmu_gather: Introduce tlb_gather_mmu_fullmm()
Browse files Browse the repository at this point in the history
Passing the range '0, -1' to tlb_gather_mmu() sets the 'fullmm' flag,
which indicates that the mm_struct being operated on is going away. In
this case, some architectures (such as arm64) can elide TLB invalidation
by ensuring that the TLB tag (ASID) associated with this mm is not
immediately reclaimed. Although this behaviour is documented in
asm-generic/tlb.h, it's subtle and easily missed.

Introduce tlb_gather_mmu_fullmm() to make it clearer that this is for the
entire mm and WARN() if tlb_gather_mmu() is called with the 'fullmm'
address range.

Signed-off-by: Will Deacon <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Yu Zhao <[email protected]>
Acked-by: Peter Zijlstra (Intel) <[email protected]>
Acked-by: Linus Torvalds <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
  • Loading branch information
willdeacon authored and Peter Zijlstra committed Jan 29, 2021
1 parent ae8eba8 commit d8b4505
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
6 changes: 4 additions & 2 deletions include/asm-generic/tlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
*
* The mmu_gather API consists of:
*
* - tlb_gather_mmu() / tlb_finish_mmu(); start and finish a mmu_gather
* - tlb_gather_mmu() / tlb_gather_mmu_fullmm() / tlb_finish_mmu()
*
* start and finish a mmu_gather
*
* Finish in particular will issue a (final) TLB invalidate and free
* all (remaining) queued pages.
Expand Down Expand Up @@ -91,7 +93,7 @@
*
* - mmu_gather::fullmm
*
* A flag set by tlb_gather_mmu() to indicate we're going to free
* A flag set by tlb_gather_mmu_fullmm() to indicate we're going to free
* the entire mm; this allows a number of optimizations.
*
* - We can ignore tlb_{start,end}_vma(); because we don't
Expand Down
1 change: 1 addition & 0 deletions include/linux/mm_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm)
struct mmu_gather;
extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
unsigned long start, unsigned long end);
extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm);
extern void tlb_finish_mmu(struct mmu_gather *tlb);

static inline void init_tlb_flush_pending(struct mm_struct *mm)
Expand Down
2 changes: 1 addition & 1 deletion mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -3214,7 +3214,7 @@ void exit_mmap(struct mm_struct *mm)

lru_add_drain();
flush_cache_mm(mm);
tlb_gather_mmu(&tlb, mm, 0, -1);
tlb_gather_mmu_fullmm(&tlb, mm);
/* update_hiwater_rss(mm) here? but nobody should be looking */
/* Use -1 here to ensure all VMAs in the mm are unmapped */
unmap_vmas(&tlb, vma, 0, -1);
Expand Down
16 changes: 14 additions & 2 deletions mm/mmu_gather.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ void tlb_flush_mmu(struct mmu_gather *tlb)
* respectively when @mm is without users and we're going to destroy
* the full address space (exit/execve).
*/
void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
unsigned long start, unsigned long end)
static void __tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
unsigned long start, unsigned long end)
{
tlb->mm = mm;

Expand All @@ -287,6 +287,18 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
inc_tlb_flush_pending(tlb->mm);
}

void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
unsigned long start, unsigned long end)
{
WARN_ON(!(start | (end + 1))); /* Use _fullmm() instead */
__tlb_gather_mmu(tlb, mm, start, end);
}

void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm)
{
__tlb_gather_mmu(tlb, mm, 0, -1);
}

/**
* tlb_finish_mmu - finish an mmu_gather structure
* @tlb: the mmu_gather structure to finish
Expand Down

0 comments on commit d8b4505

Please sign in to comment.