Commit 8fca4f98 authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

Merge branch 'bpf_iter-BTF_ID-at-build-time'

Yonghong Song says:

====================
Commit 5a2798ab
("bpf: Add BTF_ID_LIST/BTF_ID/BTF_ID_UNUSED macros")
implemented a mechanism to compute btf_ids at kernel build
time which can simplify kernel implementation and reduce
runtime overhead by removing in-kernel btf_id calculation.

This patch set tried to use this mechanism to compute
btf_ids for bpf_skc_to_*() helpers and for btf_id_or_null ctx
arguments specified during bpf iterator registration.
Please see individual patch for details.

Changelogs:
  v1 -> v2:
    - v1 ([1]) is only for bpf_skc_to_*() helpers. This version
      expanded it to cover ctx btf_id_or_null arguments
    - abandoned the change of "extern u32 name[]" to
      "static u32 name[]" for BPF_ID_LIST local "name" definition.
      gcc 9 incurred a compilation error.

 [1]: https://lore.kernel.org/bpf/20200717184706.3476992-1-yhs@fb.com/T


====================

Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents e4d9c232 951cf368
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -668,6 +668,7 @@ struct bpf_jit_poke_descriptor {
struct bpf_ctx_arg_aux {
	u32 offset;
	enum bpf_reg_type reg_type;
	u32 btf_id;
};

struct bpf_prog_aux {
@@ -1541,7 +1542,6 @@ static inline bool bpf_map_is_dev_bound(struct bpf_map *map)

struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr);
void bpf_map_offload_map_free(struct bpf_map *map);
void init_btf_sock_ids(struct btf *btf);
#else
static inline int bpf_prog_offload_init(struct bpf_prog *prog,
					union bpf_attr *attr)
@@ -1567,9 +1567,6 @@ static inline struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr)
static inline void bpf_map_offload_map_free(struct bpf_map *map)
{
}
static inline void init_btf_sock_ids(struct btf *btf)
{
}
#endif /* CONFIG_NET && CONFIG_BPF_SYSCALL */

#if defined(CONFIG_BPF_STREAM_PARSER)
+37 −3
Original line number Diff line number Diff line
@@ -57,17 +57,20 @@ asm( \
 * .zero 4
 *
 */
#define __BTF_ID_LIST(name)				\
#define __BTF_ID_LIST(name, scope)			\
asm(							\
".pushsection " BTF_IDS_SECTION ",\"a\";       \n"	\
".local " #name ";                             \n"	\
"." #scope " " #name ";                        \n"	\
#name ":;                                      \n"	\
".popsection;                                  \n");	\

#define BTF_ID_LIST(name)				\
__BTF_ID_LIST(name)					\
__BTF_ID_LIST(name, local)				\
extern u32 name[];

#define BTF_ID_LIST_GLOBAL(name)			\
__BTF_ID_LIST(name, globl)

/*
 * The BTF_ID_UNUSED macro defines 4 zero bytes.
 * It's used when we want to define 'unused' entry
@@ -90,7 +93,38 @@ asm( \
#define BTF_ID_LIST(name) static u32 name[5];
#define BTF_ID(prefix, name)
#define BTF_ID_UNUSED
#define BTF_ID_LIST_GLOBAL(name) u32 name[1];

#endif /* CONFIG_DEBUG_INFO_BTF */

#ifdef CONFIG_NET
/* Define a list of socket types which can be the argument for
 * skc_to_*_sock() helpers. All these sockets should have
 * sock_common as the first argument in its memory layout.
 */
#define BTF_SOCK_TYPE_xxx \
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_INET, inet_sock)			\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_INET_CONN, inet_connection_sock)	\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_INET_REQ, inet_request_sock)	\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_INET_TW, inet_timewait_sock)	\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_REQ, request_sock)			\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_SOCK, sock)				\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_SOCK_COMMON, sock_common)		\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_TCP, tcp_sock)			\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_TCP_REQ, tcp_request_sock)		\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_TCP_TW, tcp_timewait_sock)		\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_TCP6, tcp6_sock)			\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP, udp_sock)			\
	BTF_SOCK_TYPE(BTF_SOCK_TYPE_UDP6, udp6_sock)

enum {
#define BTF_SOCK_TYPE(name, str) name,
BTF_SOCK_TYPE_xxx
#undef BTF_SOCK_TYPE
MAX_BTF_SOCK_TYPE,
};

extern u32 btf_sock_ids[];
#endif

#endif
+3 −3
Original line number Diff line number Diff line
@@ -3672,7 +3672,6 @@ struct btf *btf_parse_vmlinux(void)
		goto errout;

	bpf_struct_ops_init(btf, log);
	init_btf_sock_ids(btf);

	btf_verifier_env_free(env);
	refcount_set(&btf->refcnt, 1);
@@ -3818,16 +3817,17 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
		return true;

	/* this is a pointer to another type */
	info->reg_type = PTR_TO_BTF_ID;
	for (i = 0; i < prog->aux->ctx_arg_info_size; i++) {
		const struct bpf_ctx_arg_aux *ctx_arg_info = &prog->aux->ctx_arg_info[i];

		if (ctx_arg_info->offset == off) {
			info->reg_type = ctx_arg_info->reg_type;
			break;
			info->btf_id = ctx_arg_info->btf_id;
			return true;
		}
	}

	info->reg_type = PTR_TO_BTF_ID;
	if (tgt_prog) {
		ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg);
		if (ret > 0) {
+6 −1
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
#include <linux/fs.h>
#include <linux/filter.h>
#include <linux/kernel.h>
#include <linux/btf_ids.h>

struct bpf_iter_seq_map_info {
	u32 mid;
@@ -81,7 +82,10 @@ static const struct seq_operations bpf_map_seq_ops = {
	.show	= bpf_map_seq_show,
};

static const struct bpf_iter_reg bpf_map_reg_info = {
BTF_ID_LIST(btf_bpf_map_id)
BTF_ID(struct, bpf_map)

static struct bpf_iter_reg bpf_map_reg_info = {
	.target			= "bpf_map",
	.seq_ops		= &bpf_map_seq_ops,
	.init_seq_private	= NULL,
@@ -96,6 +100,7 @@ static const struct bpf_iter_reg bpf_map_reg_info = {

static int __init bpf_map_iter_init(void)
{
	bpf_map_reg_info.ctx_arg_info[0].btf_id = *btf_bpf_map_id;
	return bpf_iter_reg_target(&bpf_map_reg_info);
}

+10 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <linux/fs.h>
#include <linux/fdtable.h>
#include <linux/filter.h>
#include <linux/btf_ids.h>

struct bpf_iter_seq_task_common {
	struct pid_namespace *ns;
@@ -312,7 +313,11 @@ static const struct seq_operations task_file_seq_ops = {
	.show	= task_file_seq_show,
};

static const struct bpf_iter_reg task_reg_info = {
BTF_ID_LIST(btf_task_file_ids)
BTF_ID(struct, task_struct)
BTF_ID(struct, file)

static struct bpf_iter_reg task_reg_info = {
	.target			= "task",
	.seq_ops		= &task_seq_ops,
	.init_seq_private	= init_seq_pidns,
@@ -325,7 +330,7 @@ static const struct bpf_iter_reg task_reg_info = {
	},
};

static const struct bpf_iter_reg task_file_reg_info = {
static struct bpf_iter_reg task_file_reg_info = {
	.target			= "task_file",
	.seq_ops		= &task_file_seq_ops,
	.init_seq_private	= init_seq_pidns,
@@ -344,10 +349,13 @@ static int __init task_iter_init(void)
{
	int ret;

	task_reg_info.ctx_arg_info[0].btf_id = btf_task_file_ids[0];
	ret = bpf_iter_reg_target(&task_reg_info);
	if (ret)
		return ret;

	task_file_reg_info.ctx_arg_info[0].btf_id = btf_task_file_ids[0];
	task_file_reg_info.ctx_arg_info[1].btf_id = btf_task_file_ids[1];
	return bpf_iter_reg_target(&task_file_reg_info);
}
late_initcall(task_iter_init);
Loading