All of lore.kernel.org
 help / color / mirror / Atom feed
From: Emil Tsalapatis <emil@etsalapatis.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, eddyz87@gmail.com,
	memxor@gmail.com, daniel@iogearbox.net,
	Emil Tsalapatis <emil@etsalapatis.com>
Subject: [PATCH bpf-next v5 4/5] bpf: Retry arena faults when the arena lock times out
Date: Fri, 16 Oct 2026 19:37:02 +0000	[thread overview]
Message-ID: <20261016193703.9203-5-emil@etsalapatis.com> (raw)
In-Reply-To: <20261016193703.9203-1-emil@etsalapatis.com>

arena_vm_fault() and arena_fault_page() raise SIGBUS whenever they
fail to take the arena spinlock. The resilient spinlock fails with
-EDEADLK when it detects a deadlock involving locks the caller holds,
which retrying cannot resolve, and with -ETIMEDOUT otherwise. A
timeout means either contention or a deadlock among other CPUs that
the lock broke by timing out. The faulting task holds no other
resilient spinlock, so it is not part of such a cycle, and a retry
can succeed. A timeout should not kill the faulting process.

Commit 0b10b945479c ("bpf: Fix mmap_lock deadlock on arena lock
failure") raised SIGBUS because a retry would have to drop the fault
lock and bound its retries. Keep SIGBUS for -EDEADLK and retry the
fault on a timeout. Faults that allow retry drop the fault lock and
return VM_FAULT_RETRY, as __folio_lock_or_retry() does, unless
FAULT_FLAG_RETRY_NOWAIT asks to keep it. Each attempt spins until it
takes the lock or times out, and the fault handlers stop retrying on
fatal signals, so no explicit bound is needed. Faults that cannot
retry, such as some get_user_pages() callers, return VM_FAULT_NOPAGE
so that the caller faults again, as they already do for pages whose
free is in progress.

Fixes: 0b10b945479c ("bpf: Fix mmap_lock deadlock on arena lock failure")
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
---
 kernel/bpf/arena.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c
index dd9f322ad57f..034495e014fe 100644
--- a/kernel/bpf/arena.c
+++ b/kernel/bpf/arena.c
@@ -589,7 +589,7 @@ static bool arena_fault_page(struct bpf_arena *arena, struct vm_fault *vmf,
 
 	folio_unlock(folio);
 	put_page(page);
-	if (err) {
+	if (err == -EDEADLK) {
 		*retp = VM_FAULT_SIGBUS;
 		return true;
 	}
@@ -672,8 +672,13 @@ static vm_fault_t arena_vm_fault(struct vm_fault *vmf)
 
 	ret = raw_res_spin_lock_irqsave(&arena->spinlock, flags);
 	if (ret) {
-		fault_ret = VM_FAULT_SIGBUS;
-		goto out_err;
+		/* If we are deadlocking somehow, no way to ensure forward progress. */
+		if (ret == -EDEADLK) {
+			fault_ret = VM_FAULT_SIGBUS;
+			goto out_err;
+		}
+
+		goto retry_free;
 	}
 
 	page = vmalloc_to_page((void *)kaddr);
@@ -776,6 +781,9 @@ static vm_fault_t arena_vm_fault(struct vm_fault *vmf)
 		free_pages_nolock(new_page, 0);
 	return fault_ret;
 
+retry_free:
+	if (new_page)
+		free_pages_nolock(new_page, 0);
 retry:
 	/* Non-retryable GUP callers recheck the PTE on NOPAGE. */
 	if (!(vmf->flags & FAULT_FLAG_ALLOW_RETRY))
-- 
2.52.0


  parent reply	other threads:[~2026-10-16 19:37 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 19:36 [PATCH bpf-next v5 0/5] bpf: Fix arena memory incoherence Emil Tsalapatis
2026-10-16 19:36 ` [PATCH bpf-next v5 1/5] bpf: Stop deferred arena frees before map teardown Emil Tsalapatis
2026-10-16 19:37 ` [PATCH bpf-next v5 2/5] bpf: Revalidate faulted arena pages before installing user mappings Emil Tsalapatis
2026-10-16 19:37 ` [PATCH bpf-next v5 3/5] bpf: Fix arena race between page free and alloc leading to incoherency Emil Tsalapatis
2026-10-16 20:15   ` bot+bpf-ci
2026-10-16 19:37 ` Emil Tsalapatis [this message]
2026-10-16 23:44   ` [PATCH bpf-next v5 4/5] bpf: Retry arena faults when the arena lock times out Alexei Starovoitov
2026-10-16 19:37 ` [PATCH bpf-next v5 5/5] selftests/bpf: Add arena allocation race tests Emil Tsalapatis
2026-10-16 23:44 ` [PATCH bpf-next v5 0/5] bpf: Fix arena memory incoherence Alexei Starovoitov

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=20261016193703.9203-5-emil@etsalapatis.com \
    --to=emil@etsalapatis.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=memxor@gmail.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.