From: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>
To: "Kumar Kartikeya Dwivedi" <memxor@gmail.com>, <bpf@vger.kernel.org>
Cc: "Andrii Nakryiko" <andrii@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Emil Tsalapatis" <emil@etsalapatis.com>,
"Ihor Solodrai" <ihor.solodrai@linux.dev>, <kkd@meta.com>,
<kernel-team@meta.com>
Subject: Re: [PATCH bpf-next v1 00/29] Exceptions - Resource Cleanup - Redux
Date: Wed, 11 Nov 2026 20:33:26 +0000 [thread overview]
Message-ID: <DMSO2CZRMEUE.LE9RG32M5QBN@gmail.com> (raw)
In-Reply-To: <cover.1794399387.git.memxor@gmail.com>
On Wed, Nov 11, 2026 at 04:56 AM Kumar Kartikeya Dwivedi <memxor@gmail.com> wrote:
> This series allows the main program and its subprogs, static and global,
> to throw while holding resources. The unwinder releases the resources of
> every frame it discards.
Agree that we need bpf_throw() from everywhere.
Below is an idea for brainstorming. No code yet.
Drop elaboration in the verifier. Pads instead of descriptors.
Keep the analysis of what a frame holds at a site.
Change what comes out of it: not tables for a C unwinder, but landing pads.
A pad is BPF insns that the verifier adds after the main pass, like guards.
Then throw, cancel and rust panic are one mechanism:
unwind_goto / unwind_exit.
1. One unwinder
site the verifier emits
----------------------------------- ---------------------------------
call bpf_throw r0 = cookie; goto pad
loop guard, recursion check may_goto pad
call / callx of a subprog that may unwind_goto pad, behind the call
unwind, no unwind_goto behind it
helper that runs a callback unwind_goto pad, behind the call
(your 'helpers have pads')
arena load / store / atomic unwind_goto pad, behind the access.
JIT points the extable entry at it
pad: release calls
r0 = 0
unwind_exit main prog: call exception_cb; exit
Every frame leaves through its epilogue. The frame at the site has R0-R9.
A frame that waits in a call has R6-R9 and its stack.
No stack walk, no asm entries, no saved register offsets, no site tables.
No void (*)(void *) wrappers: a pad calls the release kfunc with its type.
A frame of rust keeps its own pads. Nothing is skipped by construction.
Sites that need the same pad share it. Most sites hold nothing.
2. Three questions, answered apart
WHO The frame that acquired it since its entry.
releases What a callee returns with is the caller's.
Or the callee that it was MOVED into: the caller keeps no
live copy behind the call (R6-R9, stack).
Decided at the call from the state and liveness.
Nothing provisional. Nothing to settle after the pass.
WHERE is The prog's own live place, like your lattice: register,
the handle spill, stack object, pointer to what the lock is in + delta,
fixed address, load through a live pointer.
The prog has to release it later, so the handle is live.
WHETHER The pc, when all states at the site agree.
it is held Otherwise a DROP FLAG, as rustc and clang do it.
3. The drop flag
One hidden byte in the frame. The entry of the subprog zeroes the word.
flag = 1 behind the insn of THIS frame that brought the resource:
the acquiring call, the call of a subprog that returns
with it, or the entry when it was moved in
flag = 0 at the insn of THIS frame that takes it away:
the releasing call, or the call that moves it out
*(u8 *)(r10 - H) = 0
if r7 == 0 goto skip
call bpf_task_from_pid
r6 = r0
*(u8 *)(r10 - H) = 1
skip: ... arena access, loop, call foo ... -> pad
if r7 == 0 goto out
*(u8 *)(r10 - H) = 0
r1 = r6
call bpf_task_release
pad: r1 = *(u8 *)(r10 - H)
if r1 == 0 goto done
r1 = r6
if r1 == 0 goto done
call bpf_task_release
done: r0 = 0
unwind_exit
The stores are unconditional. bpf_res_spin_lock() needs a test of r0 first.
The flag has no handle in it. So there is no register to find at the
acquire, no compare chain at the release, no refresh after a call.
A flag is emitted only where the states at some site disagree.
Identity: a reference carries its origin, as in your set.
A join or a subsumption can pair two references with different origins.
Then the origins go into one set (union-find) and share a flag.
States are joined as today.
Sections become entries of refs[], so they have an origin too.
4. What I hope goes away, in your terms
tables, unwinder, phases, asm entries, pads
registers recovered from prologues
mirror flag + the prog's own place
NULL in the lattice flag. A pad tests for NULL too
entry guarded by a scalar flag
descriptor per chain of calls flag in the callee's frame:
'differs by chain' is 'held
on some paths' there
provisional listings, transfer move at the call
other origins are not joined union-find
What stays: classes, type -> release kfunc, the places, helpers have pads,
the return value of a cancelled prog, the struct_ops hook, the stack in
arena, bpf_throw() reads all registers and slots for liveness.
5. Where I'm looking for ideas.
a. Several resources of one origin at once. rbtree_search pops nodes
into an array in a loop that is walked. A flag per origin cannot say
which.
b. A callee releases what the caller keeps live, on some paths only.
try_consume(obj). During the call the pc of the callee tells.
Behind the call only the callee knows. Maybe: the callee has its own
flag and returns it in a scratch register at exit and unwind_exit.
R2 survives exit already for 16 byte returns.
I think you're doing something like that in your followup patches.
prev parent reply other threads:[~2026-11-11 20:33 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 12:56 [PATCH bpf-next v1 00/29] Exceptions - Resource Cleanup - Redux Kumar Kartikeya Dwivedi
2026-11-11 12:56 ` [PATCH bpf-next v1 01/29] bpf: Record where JITs save callee-saved registers Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 02/29] bpf: Add bpf_throw_unwind() and an arch entry hook Kumar Kartikeya Dwivedi
2026-11-11 14:45 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 03/29] bpf, x86: Capture registers in a native bpf_throw() entry Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 04/29] bpf, arm64: " Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 05/29] bpf: Restore callee-saved registers from unwound frames Kumar Kartikeya Dwivedi
2026-11-11 14:41 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 06/29] bpf: Keep last insn's aux data in add_hidden_subprog() Kumar Kartikeya Dwivedi
2026-11-11 14:38 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 07/29] bpf: Add one allocator for hidden stack slots Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 15:15 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 08/29] bpf: Add flags and release kfuncs to the dtor registry Kumar Kartikeya Dwivedi
2026-11-11 13:33 ` bot+bpf-ci
2026-11-11 15:36 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 09/29] bpf: Register cleanup destructors for more types Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 15:00 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 10/29] bpf: Record where JITed frames keep the BPF stack Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 11/29] bpf: Give every reference an owner frame Kumar Kartikeya Dwivedi
2026-11-11 13:33 ` bot+bpf-ci
2026-11-11 12:57 ` [PATCH bpf-next v1 12/29] bpf: Release resources in hidden slots on bpf_throw() Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 15:30 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 13/29] bpf: Track held resources in hidden stack slots Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 16:12 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 14/29] bpf: Describe held resources at throw sites Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 12:57 ` [PATCH bpf-next v1 15/29] bpf: Describe handles in registers " Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 16:11 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 16/29] bpf: Describe locks " Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 16:04 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 17/29] bpf: Apply hidden slot limits only when a slot is needed Kumar Kartikeya Dwivedi
2026-11-11 16:31 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 18/29] bpf: Allow a callee to leave resources with its caller Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 16:41 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 19/29] bpf: Allow a callee to release its caller's resources Kumar Kartikeya Dwivedi
2026-11-11 17:02 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 20/29] bpf: Transfer a reference to the callee that releases it Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 16:57 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 21/29] bpf: Support callx when a callee releases resources Kumar Kartikeya Dwivedi
2026-11-11 14:04 ` bot+bpf-ci
2026-11-11 17:13 ` sashiko-bot
2026-11-11 12:57 ` [PATCH bpf-next v1 22/29] selftests/bpf: Test rejected throws that hold resources Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 23/29] selftests/bpf: Test resource cleanup on bpf_throw() Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 24/29] selftests/bpf: Test cleanup of handles on the stack Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 25/29] selftests/bpf: Test cleanup of handles in registers Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 26/29] selftests/bpf: Test callees releasing caller resources Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 27/29] selftests/bpf: Test resources a callee leaves with its caller Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 28/29] selftests/bpf: Test cleanup of locks described at sites Kumar Kartikeya Dwivedi
2026-11-11 12:57 ` [PATCH bpf-next v1 29/29] selftests/bpf: Test callee releases through callx Kumar Kartikeya Dwivedi
2026-11-11 20:33 ` Alexei Starovoitov [this message]
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=DMSO2CZRMEUE.LE9RG32M5QBN@gmail.com \
--to=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=kernel-team@meta.com \
--cc=kkd@meta.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox