mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 16:13:19 +09:00
bpf: Add basic bpf_rb_{root,node} support
This patch adds special BPF_RB_{ROOT,NODE} btf_field_types similar to
BPF_LIST_{HEAD,NODE}, adds the necessary plumbing to detect the new
types, and adds bpf_rb_root_free function for freeing bpf_rb_root in
map_values.
structs bpf_rb_root and bpf_rb_node are opaque types meant to
obscure structs rb_root_cached rb_node, respectively.
btf_struct_access will prevent BPF programs from touching these special
fields automatically now that they're recognized.
btf_check_and_fixup_fields now groups list_head and rb_root together as
"graph root" fields and {list,rb}_node as "graph node", and does same
ownership cycle checking as before. Note that this function does _not_
prevent ownership type mixups (e.g. rb_root owning list_node) - that's
handled by btf_parse_graph_root.
After this patch, a bpf program can have a struct bpf_rb_root in a
map_value, but not add anything to nor do anything useful with it.
Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com>
Link: https://lore.kernel.org/r/20230214004017.2534011-2-davemarchevsky@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
6a3cd3318f
commit
9c395c1b99
@@ -181,7 +181,10 @@ enum btf_field_type {
|
||||
BPF_KPTR = BPF_KPTR_UNREF | BPF_KPTR_REF,
|
||||
BPF_LIST_HEAD = (1 << 4),
|
||||
BPF_LIST_NODE = (1 << 5),
|
||||
BPF_GRAPH_NODE_OR_ROOT = BPF_LIST_NODE | BPF_LIST_HEAD,
|
||||
BPF_RB_ROOT = (1 << 6),
|
||||
BPF_RB_NODE = (1 << 7),
|
||||
BPF_GRAPH_NODE_OR_ROOT = BPF_LIST_NODE | BPF_LIST_HEAD |
|
||||
BPF_RB_NODE | BPF_RB_ROOT,
|
||||
};
|
||||
|
||||
struct btf_field_kptr {
|
||||
@@ -285,6 +288,10 @@ static inline const char *btf_field_type_name(enum btf_field_type type)
|
||||
return "bpf_list_head";
|
||||
case BPF_LIST_NODE:
|
||||
return "bpf_list_node";
|
||||
case BPF_RB_ROOT:
|
||||
return "bpf_rb_root";
|
||||
case BPF_RB_NODE:
|
||||
return "bpf_rb_node";
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return "unknown";
|
||||
@@ -305,6 +312,10 @@ static inline u32 btf_field_type_size(enum btf_field_type type)
|
||||
return sizeof(struct bpf_list_head);
|
||||
case BPF_LIST_NODE:
|
||||
return sizeof(struct bpf_list_node);
|
||||
case BPF_RB_ROOT:
|
||||
return sizeof(struct bpf_rb_root);
|
||||
case BPF_RB_NODE:
|
||||
return sizeof(struct bpf_rb_node);
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
@@ -325,6 +336,10 @@ static inline u32 btf_field_type_align(enum btf_field_type type)
|
||||
return __alignof__(struct bpf_list_head);
|
||||
case BPF_LIST_NODE:
|
||||
return __alignof__(struct bpf_list_node);
|
||||
case BPF_RB_ROOT:
|
||||
return __alignof__(struct bpf_rb_root);
|
||||
case BPF_RB_NODE:
|
||||
return __alignof__(struct bpf_rb_node);
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
@@ -435,6 +450,9 @@ void copy_map_value_locked(struct bpf_map *map, void *dst, void *src,
|
||||
void bpf_timer_cancel_and_free(void *timer);
|
||||
void bpf_list_head_free(const struct btf_field *field, void *list_head,
|
||||
struct bpf_spin_lock *spin_lock);
|
||||
void bpf_rb_root_free(const struct btf_field *field, void *rb_root,
|
||||
struct bpf_spin_lock *spin_lock);
|
||||
|
||||
|
||||
int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user