Re: [PATCH 4/6] alpha: only use a targeted tbi() when the target mm is really current (UP)
Matt Turner <[email protected]>
| Newsgroups | gmane.linux.ports.alpha,gmane.linux.kernel |
|---|---|
| Message-ID | <CAEdQ38HYF0KWE0pxRBdWYfr9e0q8HqJ_BQu=_Zaredb3Xp+euQ@mail.gmail.com> |
On Sun, Aug 9, 2026 at 4:55 AM Magnus Lindholm <[email protected]> wrote: > > The uniprocessor flush_tlb_page() has the same defect the previous patch > fixed for SMP: > > if (mm == current->active_mm) > flush_tlb_current_page(mm, vma, addr); > else > flush_tlb_other(mm); > > For a non-executable vma flush_tlb_current_page() issues tbi(2, addr), > which acts on the address space context currently loaded, so it reaches > the mm's translations only when that context belongs to it. Under lazy > TLB an idle or kernel task keeps the mm as its active_mm while a different > ASN is loaded, so the tbi() invalidates the wrong context and the stale > translation survives. > > Use current->mm instead, as for SMP. > > This is not theoretical on a uniprocessor. folio_mkclean() runs in the > writeback flusher kworker, which borrows the mm, and with one CPU that > kworker necessarily shares it with the thread holding the translation. A > test that writes a small MAP_SHARED file while background writeback cleans > it loses data on every round: the mapping holds one value and the file > another. > > flush_tlb_mm() and flush_icache_user_page() need no equivalent change > here. Both use __load_new_mm_context(), which allocates and loads a fresh > context rather than relying on a targeted tbi() against whatever ASN > happened to be loaded. > > Signed-off-by: Magnus Lindholm <[email protected]> > --- > arch/alpha/include/asm/tlbflush.h | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/arch/alpha/include/asm/tlbflush.h b/arch/alpha/include/asm/tlbflush.h > index 0c8529997f54..6593a64090f1 100644 > --- a/arch/alpha/include/asm/tlbflush.h > +++ b/arch/alpha/include/asm/tlbflush.h > @@ -87,7 +87,14 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) > { > struct mm_struct *mm = vma->vm_mm; > > - if (mm == current->active_mm) > + /* > + * tbi() acts on the address space context currently loaded, so it > + * reaches MM's translations only when a thread of MM is current. > + * Under lazy TLB an idle or kernel task keeps MM as its active_mm > + * with a different ASN loaded, and a targeted tbi() would then > + * invalidate the wrong context. > + */ > + if (mm == current->mm) > flush_tlb_current_page(mm, vma, addr); > else > flush_tlb_other(mm); > -- > 2.53.0 > Maybe rename this patch to > alpha: fix the local TLB invalidate in the UP flush_tlb_page().