Commit 3b1f89e7 authored by Kui-Feng Lee's avatar Kui-Feng Lee Committed by Martin KaFai Lau

bpf: refactory struct_ops type initialization to a function.

Move the majority of the code to bpf_struct_ops_init_one(), which can then
be utilized for the initialization of newly registered dynamically
allocated struct_ops types in the following patches.
Signed-off-by: default avatarKui-Feng Lee <thinker.li@gmail.com>
Link: https://lore.kernel.org/r/20240119225005.668602-2-thinker.li@gmail.comSigned-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent b7d1af37
...@@ -137,6 +137,7 @@ struct btf_struct_metas { ...@@ -137,6 +137,7 @@ struct btf_struct_metas {
extern const struct file_operations btf_fops; extern const struct file_operations btf_fops;
const char *btf_get_name(const struct btf *btf);
void btf_get(struct btf *btf); void btf_get(struct btf *btf);
void btf_put(struct btf *btf); void btf_put(struct btf *btf);
int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz); int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz);
......
...@@ -110,102 +110,111 @@ const struct bpf_prog_ops bpf_struct_ops_prog_ops = { ...@@ -110,102 +110,111 @@ const struct bpf_prog_ops bpf_struct_ops_prog_ops = {
static const struct btf_type *module_type; static const struct btf_type *module_type;
void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log) static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
struct btf *btf,
struct bpf_verifier_log *log)
{ {
s32 type_id, value_id, module_id;
const struct btf_member *member; const struct btf_member *member;
struct bpf_struct_ops *st_ops;
const struct btf_type *t; const struct btf_type *t;
s32 type_id, value_id;
char value_name[128]; char value_name[128];
const char *mname; const char *mname;
u32 i, j; int i;
/* Ensure BTF type is emitted for "struct bpf_struct_ops_##_name" */ if (strlen(st_ops->name) + VALUE_PREFIX_LEN >=
#define BPF_STRUCT_OPS_TYPE(_name) BTF_TYPE_EMIT(struct bpf_struct_ops_##_name); sizeof(value_name)) {
#include "bpf_struct_ops_types.h" pr_warn("struct_ops name %s is too long\n",
#undef BPF_STRUCT_OPS_TYPE st_ops->name);
return;
}
sprintf(value_name, "%s%s", VALUE_PREFIX, st_ops->name);
module_id = btf_find_by_name_kind(btf, "module", BTF_KIND_STRUCT); value_id = btf_find_by_name_kind(btf, value_name,
if (module_id < 0) { BTF_KIND_STRUCT);
pr_warn("Cannot find struct module in btf_vmlinux\n"); if (value_id < 0) {
pr_warn("Cannot find struct %s in %s\n",
value_name, btf_get_name(btf));
return; return;
} }
module_type = btf_type_by_id(btf, module_id);
for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) { type_id = btf_find_by_name_kind(btf, st_ops->name,
st_ops = bpf_struct_ops[i]; BTF_KIND_STRUCT);
if (type_id < 0) {
pr_warn("Cannot find struct %s in %s\n",
st_ops->name, btf_get_name(btf));
return;
}
t = btf_type_by_id(btf, type_id);
if (btf_type_vlen(t) > BPF_STRUCT_OPS_MAX_NR_MEMBERS) {
pr_warn("Cannot support #%u members in struct %s\n",
btf_type_vlen(t), st_ops->name);
return;
}
if (strlen(st_ops->name) + VALUE_PREFIX_LEN >= for_each_member(i, t, member) {
sizeof(value_name)) { const struct btf_type *func_proto;
pr_warn("struct_ops name %s is too long\n",
mname = btf_name_by_offset(btf, member->name_off);
if (!*mname) {
pr_warn("anon member in struct %s is not supported\n",
st_ops->name); st_ops->name);
continue; break;
} }
sprintf(value_name, "%s%s", VALUE_PREFIX, st_ops->name);
value_id = btf_find_by_name_kind(btf, value_name, if (__btf_member_bitfield_size(t, member)) {
BTF_KIND_STRUCT); pr_warn("bit field member %s in struct %s is not supported\n",
if (value_id < 0) { mname, st_ops->name);
pr_warn("Cannot find struct %s in btf_vmlinux\n", break;
value_name);
continue;
} }
type_id = btf_find_by_name_kind(btf, st_ops->name, func_proto = btf_type_resolve_func_ptr(btf,
BTF_KIND_STRUCT); member->type,
if (type_id < 0) { NULL);
pr_warn("Cannot find struct %s in btf_vmlinux\n", if (func_proto &&
st_ops->name); btf_distill_func_proto(log, btf,
continue; func_proto, mname,
} &st_ops->func_models[i])) {
t = btf_type_by_id(btf, type_id); pr_warn("Error in parsing func ptr %s in struct %s\n",
if (btf_type_vlen(t) > BPF_STRUCT_OPS_MAX_NR_MEMBERS) { mname, st_ops->name);
pr_warn("Cannot support #%u members in struct %s\n", break;
btf_type_vlen(t), st_ops->name);
continue;
} }
}
for_each_member(j, t, member) { if (i == btf_type_vlen(t)) {
const struct btf_type *func_proto; if (st_ops->init(btf)) {
pr_warn("Error in init bpf_struct_ops %s\n",
st_ops->name);
} else {
st_ops->type_id = type_id;
st_ops->type = t;
st_ops->value_id = value_id;
st_ops->value_type = btf_type_by_id(btf,
value_id);
}
}
}
mname = btf_name_by_offset(btf, member->name_off); void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
if (!*mname) { {
pr_warn("anon member in struct %s is not supported\n", struct bpf_struct_ops *st_ops;
st_ops->name); s32 module_id;
break; u32 i;
}
if (__btf_member_bitfield_size(t, member)) { /* Ensure BTF type is emitted for "struct bpf_struct_ops_##_name" */
pr_warn("bit field member %s in struct %s is not supported\n", #define BPF_STRUCT_OPS_TYPE(_name) BTF_TYPE_EMIT(struct bpf_struct_ops_##_name);
mname, st_ops->name); #include "bpf_struct_ops_types.h"
break; #undef BPF_STRUCT_OPS_TYPE
}
func_proto = btf_type_resolve_func_ptr(btf, module_id = btf_find_by_name_kind(btf, "module", BTF_KIND_STRUCT);
member->type, if (module_id < 0) {
NULL); pr_warn("Cannot find struct module in %s\n", btf_get_name(btf));
if (func_proto && return;
btf_distill_func_proto(log, btf, }
func_proto, mname, module_type = btf_type_by_id(btf, module_id);
&st_ops->func_models[j])) {
pr_warn("Error in parsing func ptr %s in struct %s\n",
mname, st_ops->name);
break;
}
}
if (j == btf_type_vlen(t)) { for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
if (st_ops->init(btf)) { st_ops = bpf_struct_ops[i];
pr_warn("Error in init bpf_struct_ops %s\n", bpf_struct_ops_init_one(st_ops, btf, log);
st_ops->name);
} else {
st_ops->type_id = type_id;
st_ops->type = t;
st_ops->value_id = value_id;
st_ops->value_type = btf_type_by_id(btf,
value_id);
}
}
} }
} }
......
...@@ -1707,6 +1707,11 @@ static void btf_free_rcu(struct rcu_head *rcu) ...@@ -1707,6 +1707,11 @@ static void btf_free_rcu(struct rcu_head *rcu)
btf_free(btf); btf_free(btf);
} }
const char *btf_get_name(const struct btf *btf)
{
return btf->name;
}
void btf_get(struct btf *btf) void btf_get(struct btf *btf)
{ {
refcount_inc(&btf->refcnt); refcount_inc(&btf->refcnt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment