[PATCH RESEND v7 2/5] bpf: allow using bpf_kptr_xchg even if the NON_OWN_REF flag is set

Chengkaitao posted 5 patches 1 month, 2 weeks ago
[PATCH RESEND v7 2/5] bpf: allow using bpf_kptr_xchg even if the NON_OWN_REF flag is set
Posted by Chengkaitao 1 month, 2 weeks ago
From: Kaitao Cheng <chengkaitao@kylinos.cn>

When traversing an rbtree using bpf_rbtree_left/right, if bpf_kptr_xchg
is used to access the __kptr pointer contained in a node, it currently
requires first removing the node with bpf_rbtree_remove and clearing the
NON_OWN_REF flag, then re-adding the node to the original rbtree with
bpf_rbtree_add after usage. This process significantly degrades rbtree
traversal performance. The patch enables accessing __kptr pointers with
the NON_OWN_REF flag set while holding the lock, eliminating the need
for this remove-read-add sequence.

Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
---
 kernel/bpf/verifier.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2927a4622ff8..3536a91ff8c7 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -9329,7 +9329,8 @@ static const struct bpf_reg_types timer_types = { .types = { PTR_TO_MAP_VALUE }
 static const struct bpf_reg_types kptr_xchg_dest_types = {
 	.types = {
 		PTR_TO_MAP_VALUE,
-		PTR_TO_BTF_ID | MEM_ALLOC
+		PTR_TO_BTF_ID | MEM_ALLOC,
+		PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF,
 	}
 };
 static const struct bpf_reg_types dynptr_types = {
@@ -9489,6 +9490,7 @@ static int check_reg_type(struct bpf_verifier_env *env, u32 regno,
 	}
 	case PTR_TO_BTF_ID | MEM_ALLOC:
 	case PTR_TO_BTF_ID | MEM_PERCPU | MEM_ALLOC:
+	case PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF:
 		if (meta->func_id != BPF_FUNC_spin_lock && meta->func_id != BPF_FUNC_spin_unlock &&
 		    meta->func_id != BPF_FUNC_kptr_xchg) {
 			verifier_bug(env, "unimplemented handling of MEM_ALLOC");
-- 
2.50.1 (Apple Git-155)
Re: [PATCH RESEND v7 2/5] bpf: allow using bpf_kptr_xchg even if the NON_OWN_REF flag is set
Posted by bot+bpf-ci@kernel.org 1 month, 2 weeks ago
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -9309,7 +9309,8 @@
>  static const struct bpf_reg_types kptr_xchg_dest_types = {
>  	.types = {
>  		PTR_TO_MAP_VALUE,
> -		PTR_TO_BTF_ID | MEM_ALLOC
> +		PTR_TO_BTF_ID | MEM_ALLOC,
> +		PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF,
>  	}
>  };

ref_set_non_owning() adds MEM_RCU to non-owning references when
the btf_record has a refcount field (refcount_off >= 0):

    ref_set_non_owning() {
        reg->type |= NON_OWN_REF;
        if (rec->refcount_off >= 0)
            reg->type |= MEM_RCU;
    }

For such objects, the register type would be
PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF | MEM_RCU, which has no
matching entry in kptr_xchg_dest_types and would be rejected by
the verifier.

Should PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF | MEM_RCU also be
added here? check_func_arg_reg_off() already handles this type
combination, and Alexei Starovoitov requested this addition during
v6 review:

https://lore.kernel.org/bpf/CAADnVQJdwqeoqi+mPjQjmNbUqz2RxAjq-dVsGb7c_MCqpqmwhA@mail.gmail.com/

> @@ -9473,6 +9474,7 @@
>  	}
>  	case PTR_TO_BTF_ID | MEM_ALLOC:
>  	case PTR_TO_BTF_ID | MEM_PERCPU | MEM_ALLOC:
> +	case PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF:
>  		if (meta->func_id != BPF_FUNC_spin_lock && meta->func_id != BPF_FUNC_spin_unlock &&
>  		    meta->func_id != BPF_FUNC_kptr_xchg) {

Similarly, this switch would also need a case for
PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF | MEM_RCU to handle the
refcounted path.


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/22017669804

AI-authorship-score: low
AI-authorship-explanation: The patch went through 7 revisions with genuine maintainer interaction, uses natural technical language, and shows iterative human development.
issues-found: 1
issue-severity-score: medium
issue-severity-explanation: Missing MEM_RCU type variant causes the verifier to reject valid programs using bpf_kptr_xchg on non-owning references to objects with refcount fields, making the feature incomplete for a subset of BPF object types.