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

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.com


Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent b7d1af37
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ struct btf_struct_metas {

extern const struct file_operations btf_fops;

const char *btf_get_name(const struct btf *btf);
void btf_get(struct btf *btf);
void btf_put(struct btf *btf);
int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz);
+83 −74
Original line number Diff line number Diff line
@@ -110,62 +110,48 @@ const struct bpf_prog_ops bpf_struct_ops_prog_ops = {

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;
	struct bpf_struct_ops *st_ops;
	const struct btf_type *t;
	s32 type_id, value_id;
	char value_name[128];
	const char *mname;
	u32 i, j;

	/* Ensure BTF type is emitted for "struct bpf_struct_ops_##_name" */
#define BPF_STRUCT_OPS_TYPE(_name) BTF_TYPE_EMIT(struct bpf_struct_ops_##_name);
#include "bpf_struct_ops_types.h"
#undef BPF_STRUCT_OPS_TYPE

	module_id = btf_find_by_name_kind(btf, "module", BTF_KIND_STRUCT);
	if (module_id < 0) {
		pr_warn("Cannot find struct module in btf_vmlinux\n");
		return;
	}
	module_type = btf_type_by_id(btf, module_id);

	for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
		st_ops = bpf_struct_ops[i];
	int i;

	if (strlen(st_ops->name) + VALUE_PREFIX_LEN >=
	    sizeof(value_name)) {
		pr_warn("struct_ops name %s is too long\n",
			st_ops->name);
			continue;
		return;
	}
	sprintf(value_name, "%s%s", VALUE_PREFIX, st_ops->name);

	value_id = btf_find_by_name_kind(btf, value_name,
					 BTF_KIND_STRUCT);
	if (value_id < 0) {
			pr_warn("Cannot find struct %s in btf_vmlinux\n",
				value_name);
			continue;
		pr_warn("Cannot find struct %s in %s\n",
			value_name, btf_get_name(btf));
		return;
	}

	type_id = btf_find_by_name_kind(btf, st_ops->name,
					BTF_KIND_STRUCT);
	if (type_id < 0) {
			pr_warn("Cannot find struct %s in btf_vmlinux\n",
				st_ops->name);
			continue;
		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);
			continue;
		return;
	}

		for_each_member(j, t, member) {
	for_each_member(i, t, member) {
		const struct btf_type *func_proto;

		mname = btf_name_by_offset(btf, member->name_off);
@@ -187,14 +173,14 @@ void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
		if (func_proto &&
		    btf_distill_func_proto(log, btf,
					   func_proto, mname,
						   &st_ops->func_models[j])) {
					   &st_ops->func_models[i])) {
			pr_warn("Error in parsing func ptr %s in struct %s\n",
				mname, st_ops->name);
			break;
		}
	}

		if (j == btf_type_vlen(t)) {
	if (i == btf_type_vlen(t)) {
		if (st_ops->init(btf)) {
			pr_warn("Error in init bpf_struct_ops %s\n",
				st_ops->name);
@@ -207,6 +193,29 @@ void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
		}
	}
}

void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
{
	struct bpf_struct_ops *st_ops;
	s32 module_id;
	u32 i;

	/* Ensure BTF type is emitted for "struct bpf_struct_ops_##_name" */
#define BPF_STRUCT_OPS_TYPE(_name) BTF_TYPE_EMIT(struct bpf_struct_ops_##_name);
#include "bpf_struct_ops_types.h"
#undef BPF_STRUCT_OPS_TYPE

	module_id = btf_find_by_name_kind(btf, "module", BTF_KIND_STRUCT);
	if (module_id < 0) {
		pr_warn("Cannot find struct module in %s\n", btf_get_name(btf));
		return;
	}
	module_type = btf_type_by_id(btf, module_id);

	for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
		st_ops = bpf_struct_ops[i];
		bpf_struct_ops_init_one(st_ops, btf, log);
	}
}

extern struct btf *btf_vmlinux;
+5 −0
Original line number Diff line number Diff line
@@ -1707,6 +1707,11 @@ static void btf_free_rcu(struct rcu_head *rcu)
	btf_free(btf);
}

const char *btf_get_name(const struct btf *btf)
{
	return btf->name;
}

void btf_get(struct btf *btf)
{
	refcount_inc(&btf->refcnt);