Re: [RFC 12/20] mm/tlb: save the VMA that is flushed during tlb_start_vma()

From: Peter Zijlstra
Date: Mon Feb 01 2021 - 07:29:40 EST


On Sat, Jan 30, 2021 at 04:11:24PM -0800, Nadav Amit wrote:

> @@ -283,12 +290,6 @@ struct mmu_gather {
> unsigned int cleared_puds : 1;
> unsigned int cleared_p4ds : 1;
>
> - /*
> - * tracks VM_EXEC | VM_HUGETLB in tlb_start_vma
> - */
> - unsigned int vma_exec : 1;
> - unsigned int vma_huge : 1;
> -
> unsigned int batch_count;
>
> #ifndef CONFIG_MMU_GATHER_NO_GATHER

> @@ -372,38 +369,20 @@ static inline void tlb_flush(struct mmu_gather *tlb)
> if (tlb->fullmm || tlb->need_flush_all) {
> flush_tlb_mm(tlb->mm);
> } else if (tlb->end) {
> - struct vm_area_struct vma = {
> - .vm_mm = tlb->mm,
> - .vm_flags = (tlb->vma_exec ? VM_EXEC : 0) |
> - (tlb->vma_huge ? VM_HUGETLB : 0),
> - };
> -
> - flush_tlb_range(&vma, tlb->start, tlb->end);
> + VM_BUG_ON(!tlb->vma);
> + flush_tlb_range(tlb->vma, tlb->start, tlb->end);
> }
> }

I don't much like this, and I think this is a step in the wrong
direction.

The idea is to extend the tlb_{remove,flush}_*() API to provide the
needed information to do TLB flushing. In fact, I think
tlb_remove_huge*() is already sufficient to set the VM_EXEC 'hint'. We
just don't have anything that covers the EXEC thing.

(also, I suspect the page_size crud we have also covers that)

Constructing a fake vma very much ensures arch tlb routines don't go
about and look at anything else either.

> +tlb_update_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
> {
> - /*
> - * flush_tlb_range() implementations that look at VM_HUGETLB (tile,
> - * mips-4k) flush only large pages.
> - *
> - * flush_tlb_range() implementations that flush I-TLB also flush D-TLB
> - * (tile, xtensa, arm), so it's ok to just add VM_EXEC to an existing
> - * range.
> - *
> - * We rely on tlb_end_vma() to issue a flush, such that when we reset
> - * these values the batch is empty.
> - */
> - tlb->vma_huge = is_vm_hugetlb_page(vma);
> - tlb->vma_exec = !!(vma->vm_flags & VM_EXEC);
> + tlb->vma = vma;
> }

And you're also removing the useful information about arch tlb flush
functions.