All of lore.kernel.org
 help / color / mirror / Atom feed
From: Catalin Marinas <catalin.marinas@arm.com>
To: "Oscar Salvador (SUSE)" <osalvador@kernel.org>
Cc: Chris Down <chris@chrisdown.name>, Will Deacon <will@kernel.org>,
	linux-kernel@vger.kernel.org, kernel-team@meta.com,
	Mark Rutland <mark.rutland@arm.com>,
	Huang Ying <ying.huang@linux.alibaba.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Muchun Song <muchun.song@linux.dev>,
	Oscar Salvador <osalvador@suse.de>,
	David Hildenbrand <david@kernel.org>,
	Mike Kravetz <mike.kravetz@oracle.com>,
	linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org
Subject: Re: [PATCH] arm64: hugetlb: Prevent write fault livelocks on stale TLB entries
Date: Thu, 12 Nov 2026 14:29:06 +0000	[thread overview]
Message-ID: <avXNMuvCNyLwk7wt@arm.com> (raw)
In-Reply-To: <avQvk0oxEHTLFacU@localhost.localdomain>

On Wed, Nov 11, 2026 at 10:04:19AM +0100, Oscar Salvador (SUSE) wrote:
> On Tue, Nov 10, 2026 at 08:39:02PM -0800, Chris Down wrote:
> > In Meta production, we have had tasks get stuck in a fault loop while
> > using hugetlb on arm64. During my investigations I found that affected
> > tasks share a private hugetlb page.
> > 
> > Looking at the stuck task states, I found the following ordering:
> > 
> >   CPU0                                 CPU1
> >   ----                                 ----
> >   read page
> >   [read only entry cached in TLB]
> >                                        write page
> >                                        hugetlb_fault()
> >                                          hugetlb_wp()
> >                                          [reuse folio]
> >                                          set_huge_ptep_maybe_writable()
> >                                            set_huge_ptep_writable()
> >                                          [flush local TLB only]
> > 
> >   write page using stale entry
> >   hugetlb_fault()
> >     huge_ptep_set_access_flags()
> >     [entry already writable, no flush]
> >   retry write using stale entry
> >   [fault indefinitely. well, that's not ideal!]
> > 
> > The reason is that when a write fault makes a non-contiguous hugetlb
> > entry writable, it only invalidates the local TLB. However, another CPU
> > can keep the old read-only entry, so its write will fault even though
> > the page table already permits it. hugetlb_fault() then finds nothing to
> > change and leaves the stale entry in place, so the same write keeps
> > going round in circles.
> > 
> > This is particularly bad because, if the kernel is copying to user
> > memory, the retry stays inside the kernel and the task can't act on the
> > pending signal.
> > 
> > It can even remain unkillable while holding locks across the copy,
> > resulting in further failures. For example, a read into a hugetlb
> > buffer can hold the pipe mutex and block other users of the pipe until
> > the loop ends, causing cascading lockups across the machine.
> > 
> > To fix this, when a write fault finds nothing to change in a
> > non-contiguous hugetlb entry, let's invalidate the local entry.
> > 
> > Fixes: cb1fa2e99955 ("arm64, tlbflush: don't TLBI broadcast if page reused in write fault")
> > Cc: <stable@vger.kernel.org>
> > Signed-off-by: Chris Down <chris@chrisdown.name>
> 
> This makes sense to me, and I see that commit cb1fa2e99955 ("arm64, tlbflush:
> don't TLBI broadcast if page reused in write fault") only invalidated local tlb
> for cont-hugetlb.
> Reading the changelog, I guess that was an oversight because I could not find
> the reason behind.

I think you mean non-contiguous hugetlb here? cb1fa2e99955 switched
__ptep_set_access_flags() to local invalidation, used on the
non-contiguous hugetlb path. Contiguous hugetlb updates still broadcast
through get_clear_contig_flush().

Ordinary contpte mappings also switched to local invalidation but those
go through the generic fault handler and its fix_spurious_fault()
fallback. That fallback is what the hugetlb path was missing.

-- 
Catalin


  reply	other threads:[~2026-11-12 14:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11  4:39 [PATCH] arm64: hugetlb: Prevent write fault livelocks on stale TLB entries Chris Down
2026-11-11  9:04 ` Oscar Salvador (SUSE)
2026-11-12 14:29   ` Catalin Marinas [this message]
2026-11-12  3:08 ` Huang, Ying
2026-11-12 14:50   ` Catalin Marinas
2026-11-12 19:52 ` Catalin Marinas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=avXNMuvCNyLwk7wt@arm.com \
    --to=catalin.marinas@arm.com \
    --cc=akpm@linux-foundation.org \
    --cc=chris@chrisdown.name \
    --cc=david@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mark.rutland@arm.com \
    --cc=mike.kravetz@oracle.com \
    --cc=muchun.song@linux.dev \
    --cc=osalvador@kernel.org \
    --cc=osalvador@suse.de \
    --cc=will@kernel.org \
    --cc=ying.huang@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.