From: Leon Hwang <leon.hwang@linux.dev>
To: Chengkaitao <pilgrimtao@gmail.com>,
martin.lau@linux.dev, ast@kernel.org, daniel@iogearbox.net,
andrii@kernel.org, eddyz87@gmail.com, song@kernel.org,
yonghong.song@linux.dev, john.fastabend@gmail.com,
kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com,
jolsa@kernel.org, shuah@kernel.org, chengkaitao@kylinos.cn,
linux-kselftest@vger.kernel.org
Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH bpf-next v7 3/5] bpf: add bpf_list_is_first/last/empty kfuncs
Date: Mon, 9 Mar 2026 14:42:18 +0800 [thread overview]
Message-ID: <489ddc36-d348-48ba-9a1f-52d9f63778cd@linux.dev> (raw)
In-Reply-To: <20260308134614.29711-4-pilgrimtao@gmail.com>
On 8/3/26 21:46, Chengkaitao wrote:
> From: Kaitao Cheng <chengkaitao@kylinos.cn>
>
> Add three kfuncs for BPF linked list queries:
> - bpf_list_is_first(head, node): true if node is the first in the list.
> - bpf_list_is_last(head, node): true if node is the last in the list.
> - bpf_list_empty(head): true if the list has no entries.
>
> In previous versions, to implement the above functionality, it was ^
Currently, ..., it is
"The previous versions" would mislead readers, that you are referring to
the previous versions of this series.
Thanks,
Leon
> necessary to first call bpf_list_pop_front/back to retrieve the first
> or last node before checking whether the passed-in node was the first
> or last one. After the check, the node had to be pushed back into the
> list using bpf_list_push_front/back, which was very inefficient.>
> Now, with the bpf_list_is_first/last/empty kfuncs, we can directly
> check whether a node is the first, last, or whether the list is empty,
> without having to first retrieve the node.
>
> Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
> ---
> kernel/bpf/helpers.c | 38 ++++++++++++++++++++++++++++++++++++++
> kernel/bpf/verifier.c | 15 +++++++++++++--
> 2 files changed, 51 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 407520fde668..476f5ad319e2 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -2515,6 +2515,41 @@ __bpf_kfunc struct bpf_list_node *bpf_list_back(struct bpf_list_head *head)
> return (struct bpf_list_node *)h->prev;
> }
>
> +__bpf_kfunc bool bpf_list_is_first(struct bpf_list_head *head, struct bpf_list_node *node)
> +{
> + struct list_head *h = (struct list_head *)head;
> + struct bpf_list_node_kern *kn = (struct bpf_list_node_kern *)node;
> +
> + if (READ_ONCE(kn->owner) != head)
> + return false;
> +
> + return list_is_first(&kn->list_head, h);
> +}
> +
> +__bpf_kfunc bool bpf_list_is_last(struct bpf_list_head *head, struct bpf_list_node *node)
> +{
> + struct list_head *h = (struct list_head *)head;
> + struct bpf_list_node_kern *kn = (struct bpf_list_node_kern *)node;
> +
> + if (READ_ONCE(kn->owner) != head)
> + return false;
> +
> + return list_is_last(&kn->list_head, h);
> +}
> +
> +__bpf_kfunc bool bpf_list_empty(struct bpf_list_head *head)
> +{
> + struct list_head *h = (struct list_head *)head;
> +
> + /* If list_head was 0-initialized by map, bpf_obj_init_field wasn't
> + * called on its fields, so init here
> + */
> + if (unlikely(!h->next))
> + INIT_LIST_HEAD(h);
> +
> + return list_empty(h);
> +}
> +
> __bpf_kfunc struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root,
> struct bpf_rb_node *node)
> {
> @@ -4585,6 +4620,9 @@ BTF_ID_FLAGS(func, bpf_list_del, KF_ACQUIRE | KF_RET_NULL)
> BTF_ID_FLAGS(func, bpf_list_front, KF_RET_NULL)
> BTF_ID_FLAGS(func, bpf_list_back, KF_RET_NULL)
> BTF_ID_FLAGS(func, bpf_list_add_impl)
> +BTF_ID_FLAGS(func, bpf_list_is_first)
> +BTF_ID_FLAGS(func, bpf_list_is_last)
> +BTF_ID_FLAGS(func, bpf_list_empty)
> BTF_ID_FLAGS(func, bpf_task_acquire, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
> BTF_ID_FLAGS(func, bpf_task_release, KF_RELEASE)
> BTF_ID_FLAGS(func, bpf_rbtree_remove, KF_ACQUIRE | KF_RET_NULL)
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 5f55b68ed935..5e32e02429c4 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -12465,6 +12465,9 @@ enum special_kfunc_type {
> KF_bpf_list_del,
> KF_bpf_list_front,
> KF_bpf_list_back,
> + KF_bpf_list_is_first,
> + KF_bpf_list_is_last,
> + KF_bpf_list_empty,
> KF_bpf_cast_to_kern_ctx,
> KF_bpf_rdonly_cast,
> KF_bpf_rcu_read_lock,
> @@ -12527,6 +12530,9 @@ BTF_ID(func, bpf_list_pop_back)
> BTF_ID(func, bpf_list_del)
> BTF_ID(func, bpf_list_front)
> BTF_ID(func, bpf_list_back)
> +BTF_ID(func, bpf_list_is_first)
> +BTF_ID(func, bpf_list_is_last)
> +BTF_ID(func, bpf_list_empty)
> BTF_ID(func, bpf_cast_to_kern_ctx)
> BTF_ID(func, bpf_rdonly_cast)
> BTF_ID(func, bpf_rcu_read_lock)
> @@ -13003,7 +13009,10 @@ static bool is_bpf_list_api_kfunc(u32 btf_id)
> btf_id == special_kfunc_list[KF_bpf_list_pop_back] ||
> btf_id == special_kfunc_list[KF_bpf_list_del] ||
> btf_id == special_kfunc_list[KF_bpf_list_front] ||
> - btf_id == special_kfunc_list[KF_bpf_list_back];
> + btf_id == special_kfunc_list[KF_bpf_list_back] ||
> + btf_id == special_kfunc_list[KF_bpf_list_is_first] ||
> + btf_id == special_kfunc_list[KF_bpf_list_is_last] ||
> + btf_id == special_kfunc_list[KF_bpf_list_empty];
> }
>
> static bool is_bpf_rbtree_api_kfunc(u32 btf_id)
> @@ -13126,7 +13135,9 @@ static bool check_kfunc_is_graph_node_api(struct bpf_verifier_env *env,
> ret = (kfunc_btf_id == special_kfunc_list[KF_bpf_list_push_front_impl] ||
> kfunc_btf_id == special_kfunc_list[KF_bpf_list_push_back_impl] ||
> kfunc_btf_id == special_kfunc_list[KF_bpf_list_add_impl] ||
> - kfunc_btf_id == special_kfunc_list[KF_bpf_list_del]);
> + kfunc_btf_id == special_kfunc_list[KF_bpf_list_del] ||
> + kfunc_btf_id == special_kfunc_list[KF_bpf_list_is_first] ||
> + kfunc_btf_id == special_kfunc_list[KF_bpf_list_is_last]);
> break;
> case BPF_RB_NODE:
> ret = (kfunc_btf_id == special_kfunc_list[KF_bpf_rbtree_remove] ||
next prev parent reply other threads:[~2026-03-09 6:42 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-08 13:46 [PATCH bpf-next v7 0/5] bpf: Extend the bpf_list family of APIs Chengkaitao
2026-03-08 13:46 ` [PATCH bpf-next v7 1/5] bpf: Introduce the bpf_list_del kfunc Chengkaitao
2026-03-09 6:33 ` Leon Hwang
2026-03-10 20:10 ` Kumar Kartikeya Dwivedi
2026-03-10 20:28 ` Kumar Kartikeya Dwivedi
2026-03-08 13:46 ` [PATCH bpf-next v7 2/5] bpf: Add bpf_list_add_impl to insert node after a given list node Chengkaitao
2026-03-08 14:25 ` bot+bpf-ci
2026-03-09 6:34 ` Leon Hwang
2026-03-10 20:10 ` Kumar Kartikeya Dwivedi
2026-03-08 13:46 ` [PATCH bpf-next v7 3/5] bpf: add bpf_list_is_first/last/empty kfuncs Chengkaitao
2026-03-09 6:42 ` Leon Hwang [this message]
2026-03-08 13:46 ` [PATCH bpf-next v7 4/5] selftests/bpf: Add test cases for bpf_list_del/add/is_first/is_last/empty Chengkaitao
2026-03-08 14:25 ` bot+bpf-ci
2026-03-09 6:43 ` Leon Hwang
2026-03-10 2:05 ` Alexei Starovoitov
2026-03-08 13:46 ` [PATCH bpf-next v7 5/5] bpf: refactor kfunc checks using table-driven approach in verifier Chengkaitao
2026-03-09 6:45 ` Leon Hwang
2026-03-10 20:10 ` Kumar Kartikeya Dwivedi
2026-03-11 5:36 ` Leon Hwang
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=489ddc36-d348-48ba-9a1f-52d9f63778cd@linux.dev \
--to=leon.hwang@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chengkaitao@kylinos.cn \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=pilgrimtao@gmail.com \
--cc=sdf@fomichev.me \
--cc=shuah@kernel.org \
--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.