Skip to content

Commit fb5b480

Browse files
Martin KaFai LauAlexei Starovoitov
authored andcommitted
bpf: Add bpf_list_{front,back} kfunc
In the kernel fq qdisc implementation, it only needs to look at the fields of the first node in a list but does not always need to remove it from the list. It is more convenient to have a peek kfunc for the list. It works similar to the bpf_rbtree_first(). This patch adds bpf_list_{front,back} kfunc. The verifier is changed such that the kfunc returning "struct bpf_list_node *" will be marked as non-owning. The exception is the KF_ACQUIRE kfunc. The net effect is only the new bpf_list_{front,back} kfuncs will have its return pointer marked as non-owning. Acked-by: Kumar Kartikeya Dwivedi <[email protected]> Signed-off-by: Martin KaFai Lau <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 3fab84f commit fb5b480

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

kernel/bpf/helpers.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,26 @@ __bpf_kfunc struct bpf_list_node *bpf_list_pop_back(struct bpf_list_head *head)
22932293
return __bpf_list_del(head, true);
22942294
}
22952295

2296+
__bpf_kfunc struct bpf_list_node *bpf_list_front(struct bpf_list_head *head)
2297+
{
2298+
struct list_head *h = (struct list_head *)head;
2299+
2300+
if (list_empty(h) || unlikely(!h->next))
2301+
return NULL;
2302+
2303+
return (struct bpf_list_node *)h->next;
2304+
}
2305+
2306+
__bpf_kfunc struct bpf_list_node *bpf_list_back(struct bpf_list_head *head)
2307+
{
2308+
struct list_head *h = (struct list_head *)head;
2309+
2310+
if (list_empty(h) || unlikely(!h->next))
2311+
return NULL;
2312+
2313+
return (struct bpf_list_node *)h->prev;
2314+
}
2315+
22962316
__bpf_kfunc struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root,
22972317
struct bpf_rb_node *node)
22982318
{
@@ -3236,6 +3256,8 @@ BTF_ID_FLAGS(func, bpf_list_push_front_impl)
32363256
BTF_ID_FLAGS(func, bpf_list_push_back_impl)
32373257
BTF_ID_FLAGS(func, bpf_list_pop_front, KF_ACQUIRE | KF_RET_NULL)
32383258
BTF_ID_FLAGS(func, bpf_list_pop_back, KF_ACQUIRE | KF_RET_NULL)
3259+
BTF_ID_FLAGS(func, bpf_list_front, KF_RET_NULL)
3260+
BTF_ID_FLAGS(func, bpf_list_back, KF_RET_NULL)
32393261
BTF_ID_FLAGS(func, bpf_task_acquire, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
32403262
BTF_ID_FLAGS(func, bpf_task_release, KF_RELEASE)
32413263
BTF_ID_FLAGS(func, bpf_rbtree_remove, KF_ACQUIRE | KF_RET_NULL)

kernel/bpf/verifier.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12079,6 +12079,8 @@ enum special_kfunc_type {
1207912079
KF_bpf_list_push_back_impl,
1208012080
KF_bpf_list_pop_front,
1208112081
KF_bpf_list_pop_back,
12082+
KF_bpf_list_front,
12083+
KF_bpf_list_back,
1208212084
KF_bpf_cast_to_kern_ctx,
1208312085
KF_bpf_rdonly_cast,
1208412086
KF_bpf_rcu_read_lock,
@@ -12124,6 +12126,8 @@ BTF_ID(func, bpf_list_push_front_impl)
1212412126
BTF_ID(func, bpf_list_push_back_impl)
1212512127
BTF_ID(func, bpf_list_pop_front)
1212612128
BTF_ID(func, bpf_list_pop_back)
12129+
BTF_ID(func, bpf_list_front)
12130+
BTF_ID(func, bpf_list_back)
1212712131
BTF_ID(func, bpf_cast_to_kern_ctx)
1212812132
BTF_ID(func, bpf_rdonly_cast)
1212912133
BTF_ID(func, bpf_rbtree_remove)
@@ -12160,6 +12164,8 @@ BTF_ID(func, bpf_list_push_front_impl)
1216012164
BTF_ID(func, bpf_list_push_back_impl)
1216112165
BTF_ID(func, bpf_list_pop_front)
1216212166
BTF_ID(func, bpf_list_pop_back)
12167+
BTF_ID(func, bpf_list_front)
12168+
BTF_ID(func, bpf_list_back)
1216312169
BTF_ID(func, bpf_cast_to_kern_ctx)
1216412170
BTF_ID(func, bpf_rdonly_cast)
1216512171
BTF_ID(func, bpf_rcu_read_lock)
@@ -12598,7 +12604,9 @@ static bool is_bpf_list_api_kfunc(u32 btf_id)
1259812604
return btf_id == special_kfunc_list[KF_bpf_list_push_front_impl] ||
1259912605
btf_id == special_kfunc_list[KF_bpf_list_push_back_impl] ||
1260012606
btf_id == special_kfunc_list[KF_bpf_list_pop_front] ||
12601-
btf_id == special_kfunc_list[KF_bpf_list_pop_back];
12607+
btf_id == special_kfunc_list[KF_bpf_list_pop_back] ||
12608+
btf_id == special_kfunc_list[KF_bpf_list_front] ||
12609+
btf_id == special_kfunc_list[KF_bpf_list_back];
1260212610
}
1260312611

1260412612
static bool is_bpf_rbtree_api_kfunc(u32 btf_id)
@@ -13903,7 +13911,7 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
1390313911
if (is_kfunc_ret_null(&meta))
1390413912
regs[BPF_REG_0].id = id;
1390513913
regs[BPF_REG_0].ref_obj_id = id;
13906-
} else if (is_rbtree_node_type(ptr_type)) {
13914+
} else if (is_rbtree_node_type(ptr_type) || is_list_node_type(ptr_type)) {
1390713915
ref_set_non_owning(env, &regs[BPF_REG_0]);
1390813916
}
1390913917

0 commit comments

Comments
 (0)