From: chenyuan <chenyuan_fl@163.com>
To: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>
Cc: bpf <bpf@vger.kernel.org>, LKML <linux-kernel@vger.kernel.org>,
"Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Song Liu" <song@kernel.org>,
"Yonghong Song" <yonghong.song@linux.dev>,
"Jiri Olsa" <jolsa@kernel.org>,
"Emil Tsalapatis" <emil@etsalapatis.com>,
"Ihor Solodrai" <ihor.solodrai@linux.dev>,
"Yuan Chen" <chenyuan@kylinos.cn>
Subject: Re:Re: [PATCH bpf-next v4 2/3] bpf, arena: fix range_tree_set inconsistency on kmalloc_nolock failure
Date: Tue, 1 Sep 2026 15:01:39 +0800 (CST) [thread overview]
Message-ID: <704850b0.58d3.1a05bc6055a.Coremail.chenyuan_fl@163.com> (raw)
In-Reply-To: <CAADnVQKPSWBzaEc7QBT39C_N_32Gu5_P5Cob9G0rxcDgiSQg6g@mail.gmail.com>
The two lookups answer different questions, so the second one is
not redundant:
- The pre-clear lookup only consumes the boolean result. Nodes are
disjoint, and a node covering both start - 1 and last + 1 would
fully cover [start, last], which is rejected by the early return
above. Hence range_tree_clear() can only remove or truncate nodes
overlapping [start, last]: a node covering start - 1 either ends
there (untouched) or straddles start and is truncated to
[rn_start, start - 1]. Adjacency on either side is therefore
invariant across the clear, and "no adjacent node on either side"
before the clear is exactly the condition for the else-branch --
the only case needing a fresh node. It must be evaluated before
any tree modification to keep the -ENOMEM path side-effect free.
- The post-clear lookup fetches the node handles used by the
merge/extend branches. The pre-clear handles cannot be reused:
an adjacent node may straddle the range and get truncated (e.g.
[start - 1, start + 3] becomes [start - 1, start - 1]), so both
its bounds and its position in the tree change. Re-looking it up
keeps range_tree_set() independent of how range_tree_clear()
implements truncation, and leaves the -EFAULT checks below as a
sanity check of the clear itself.
The comment indeed fails to spell this out (and "adjacent free
range" is backwards); I'll reword it in v5.
At 2026-08-27 10:56:04, "Alexei Starovoitov" <alexei.starovoitov@gmail.com> wrote:
>On Mon, Aug 24, 2026 at 6:40 AM <chenyuan_fl@163.com> wrote:
>>
>> From: Yuan Chen <chenyuan@kylinos.cn>
>>
>> range_tree_set() pre-allocates the node needed for a brand-new range
>> before calling range_tree_clear(), so an allocation failure returns
>> -ENOMEM without having modified the tree (previously the overlapping
>> nodes were already removed by range_tree_clear() before the allocation
>> was attempted, permanently losing the cleared sub-ranges).
>>
>> Signed-off-by: Yuan Chen <chenyuan@kylinos.cn>
>> ---
>> kernel/bpf/range_tree.c | 45 +++++++++++++++++++++++++++++++----------
>> 1 file changed, 34 insertions(+), 11 deletions(-)
>>
>> diff --git a/kernel/bpf/range_tree.c b/kernel/bpf/range_tree.c
>> index 15b588377a76..54055b1fe541 100644
>> --- a/kernel/bpf/range_tree.c
>> +++ b/kernel/bpf/range_tree.c
>> @@ -199,6 +199,7 @@ int is_range_tree_set(struct range_tree *rt, u32 start, u32 len)
>> int range_tree_set(struct range_tree *rt, u32 start, u32 len)
>> {
>> u32 last = start + len - 1;
>> + struct range_node *new_rn = NULL;
>> struct range_node *right;
>> struct range_node *left;
>> int err;
>> @@ -208,20 +209,40 @@ int range_tree_set(struct range_tree *rt, u32 start, u32 len)
>> if (left && left->rn_start <= start && left->rn_last >= last)
>> return 0;
>>
>> + /*
>> + * A new node is needed only when the range has no adjacent free
>> + * range on either side. This is known before clearing: any range
>> + * covering start - 1 or last + 1 survives the clear as an adjacent
>> + * piece.
>
>If this is true, why do a 2nd call to left = range_it_iter_first() ?
>
>
>> Allocate only in that case, before modifying the tree, so
>> + * a failure leaves the range tree unmodified
>> + */
>> + left = range_it_iter_first(rt, start - 1, start - 1);
>> + right = range_it_iter_first(rt, last + 1, last + 1);
>> + if (!left && !right) {
>> + new_rn = kmalloc_nolock(sizeof(struct range_node),
>> + __GFP_ACCOUNT, NUMA_NO_NODE);
>> + if (!new_rn)
>> + return -ENOMEM;
>> + }
>> +
>> /* Clear out everything in the range we want to set. */
>> err = range_tree_clear(rt, start, len);
>> if (err)
>> - return err;
>> + goto out_free_new;
>>
>> /* Do we have a left-adjacent range ? */
>> left = range_it_iter_first(rt, start - 1, start - 1);
>
>pw-bot: cr
next prev parent reply other threads:[~2026-09-01 7:02 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 13:40 [PATCH bpf-next v4 0/3] bpf, arena: fix range_tree consistency on allocation failure chenyuan_fl
2026-08-24 13:40 ` [PATCH bpf-next v4 1/3] bpf, arena: fix range_tree_clear inconsistency on kmalloc_nolock failure chenyuan_fl
2026-08-24 14:35 ` bot+bpf-ci
2026-08-24 13:40 ` [PATCH bpf-next v4 2/3] bpf, arena: fix range_tree_set " chenyuan_fl
2026-08-24 14:35 ` bot+bpf-ci
2026-08-27 2:56 ` Alexei Starovoitov
2026-09-01 7:01 ` chenyuan [this message]
2026-09-02 9:37 ` [PATCH bpf-next v5 0/3] bpf, arena: fix range_tree consistency on allocation failure chenyuan_fl
2026-09-02 9:37 ` [PATCH bpf-next v5 1/3] bpf, arena: fix range_tree_clear inconsistency on kmalloc_nolock failure chenyuan_fl
2026-09-02 9:37 ` [PATCH bpf-next v5 2/3] bpf, arena: fix range_tree_set " chenyuan_fl
2026-09-02 9:37 ` [PATCH bpf-next v5 3/3] bpf, arena: handle range_tree_set failures in alloc/free paths chenyuan_fl
2026-09-02 9:53 ` sashiko-bot
2026-09-08 15:53 ` Emil Tsalapatis
2026-08-24 13:40 ` [PATCH bpf-next v4 3/3] bpf, arena: check range_tree_set return in arena_free_pages and arena_free_worker chenyuan_fl
2026-08-24 13:54 ` sashiko-bot
2026-08-24 14:35 ` bot+bpf-ci
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=704850b0.58d3.1a05bc6055a.Coremail.chenyuan_fl@163.com \
--to=chenyuan_fl@163.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chenyuan@kylinos.cn \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/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.