bpf: net: Use precomputed btf_id for bpf iterators

One additional field btf_id is added to struct
bpf_ctx_arg_aux to store the precomputed btf_ids.
The btf_id is computed at build time with
BTF_ID_LIST or BTF_ID_LIST_GLOBAL macro definitions.
All existing bpf iterators are changed to used
pre-compute btf_ids.

Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200720163403.1393551-1-yhs@fb.com
This commit is contained in:
Yonghong Song 2020-07-20 09:34:03 -07:00 committed by Alexei Starovoitov
parent fce557bcef
commit 951cf368bc
8 changed files with 38 additions and 9 deletions

View File

@ -668,6 +668,7 @@ struct bpf_jit_poke_descriptor {
struct bpf_ctx_arg_aux { struct bpf_ctx_arg_aux {
u32 offset; u32 offset;
enum bpf_reg_type reg_type; enum bpf_reg_type reg_type;
u32 btf_id;
}; };
struct bpf_prog_aux { struct bpf_prog_aux {

View File

@ -3817,16 +3817,17 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
return true; return true;
/* this is a pointer to another type */ /* 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++) { 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]; const struct bpf_ctx_arg_aux *ctx_arg_info = &prog->aux->ctx_arg_info[i];
if (ctx_arg_info->offset == off) { if (ctx_arg_info->offset == off) {
info->reg_type = ctx_arg_info->reg_type; 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) { if (tgt_prog) {
ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg); ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg);
if (ret > 0) { if (ret > 0) {

View File

@ -4,6 +4,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/btf_ids.h>
struct bpf_iter_seq_map_info { struct bpf_iter_seq_map_info {
u32 mid; u32 mid;
@ -81,7 +82,10 @@ static const struct seq_operations bpf_map_seq_ops = {
.show = bpf_map_seq_show, .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", .target = "bpf_map",
.seq_ops = &bpf_map_seq_ops, .seq_ops = &bpf_map_seq_ops,
.init_seq_private = NULL, .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) 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); return bpf_iter_reg_target(&bpf_map_reg_info);
} }

View File

@ -7,6 +7,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/fdtable.h> #include <linux/fdtable.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/btf_ids.h>
struct bpf_iter_seq_task_common { struct bpf_iter_seq_task_common {
struct pid_namespace *ns; struct pid_namespace *ns;
@ -312,7 +313,11 @@ static const struct seq_operations task_file_seq_ops = {
.show = task_file_seq_show, .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", .target = "task",
.seq_ops = &task_seq_ops, .seq_ops = &task_seq_ops,
.init_seq_private = init_seq_pidns, .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", .target = "task_file",
.seq_ops = &task_file_seq_ops, .seq_ops = &task_file_seq_ops,
.init_seq_private = init_seq_pidns, .init_seq_private = init_seq_pidns,
@ -344,10 +349,13 @@ static int __init task_iter_init(void)
{ {
int ret; int ret;
task_reg_info.ctx_arg_info[0].btf_id = btf_task_file_ids[0];
ret = bpf_iter_reg_target(&task_reg_info); ret = bpf_iter_reg_target(&task_reg_info);
if (ret) if (ret)
return 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); return bpf_iter_reg_target(&task_file_reg_info);
} }
late_initcall(task_iter_init); late_initcall(task_iter_init);

View File

@ -76,6 +76,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/inetdevice.h> #include <linux/inetdevice.h>
#include <linux/btf_ids.h>
#include <crypto/hash.h> #include <crypto/hash.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
@ -2954,7 +2955,7 @@ static void bpf_iter_fini_tcp(void *priv_data)
bpf_iter_fini_seq_net(priv_data); bpf_iter_fini_seq_net(priv_data);
} }
static const struct bpf_iter_reg tcp_reg_info = { static struct bpf_iter_reg tcp_reg_info = {
.target = "tcp", .target = "tcp",
.seq_ops = &bpf_iter_tcp_seq_ops, .seq_ops = &bpf_iter_tcp_seq_ops,
.init_seq_private = bpf_iter_init_tcp, .init_seq_private = bpf_iter_init_tcp,
@ -2969,6 +2970,7 @@ static const struct bpf_iter_reg tcp_reg_info = {
static void __init bpf_iter_register(void) static void __init bpf_iter_register(void)
{ {
tcp_reg_info.ctx_arg_info[0].btf_id = btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON];
if (bpf_iter_reg_target(&tcp_reg_info)) if (bpf_iter_reg_target(&tcp_reg_info))
pr_warn("Warning: could not register bpf iterator tcp\n"); pr_warn("Warning: could not register bpf iterator tcp\n");
} }

View File

@ -106,6 +106,7 @@
#include <net/xfrm.h> #include <net/xfrm.h>
#include <trace/events/udp.h> #include <trace/events/udp.h>
#include <linux/static_key.h> #include <linux/static_key.h>
#include <linux/btf_ids.h>
#include <trace/events/skb.h> #include <trace/events/skb.h>
#include <net/busy_poll.h> #include <net/busy_poll.h>
#include "udp_impl.h" #include "udp_impl.h"
@ -3232,7 +3233,7 @@ static void bpf_iter_fini_udp(void *priv_data)
bpf_iter_fini_seq_net(priv_data); bpf_iter_fini_seq_net(priv_data);
} }
static const struct bpf_iter_reg udp_reg_info = { static struct bpf_iter_reg udp_reg_info = {
.target = "udp", .target = "udp",
.seq_ops = &bpf_iter_udp_seq_ops, .seq_ops = &bpf_iter_udp_seq_ops,
.init_seq_private = bpf_iter_init_udp, .init_seq_private = bpf_iter_init_udp,
@ -3247,6 +3248,7 @@ static const struct bpf_iter_reg udp_reg_info = {
static void __init bpf_iter_register(void) static void __init bpf_iter_register(void)
{ {
udp_reg_info.ctx_arg_info[0].btf_id = btf_sock_ids[BTF_SOCK_TYPE_UDP];
if (bpf_iter_reg_target(&udp_reg_info)) if (bpf_iter_reg_target(&udp_reg_info))
pr_warn("Warning: could not register bpf iterator udp\n"); pr_warn("Warning: could not register bpf iterator udp\n");
} }

View File

@ -61,6 +61,7 @@
#include <net/l3mdev.h> #include <net/l3mdev.h>
#include <net/ip.h> #include <net/ip.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/btf_ids.h>
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
#include <linux/sysctl.h> #include <linux/sysctl.h>
@ -6423,7 +6424,10 @@ void __init ip6_route_init_special_entries(void)
#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS) #if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
DEFINE_BPF_ITER_FUNC(ipv6_route, struct bpf_iter_meta *meta, struct fib6_info *rt) DEFINE_BPF_ITER_FUNC(ipv6_route, struct bpf_iter_meta *meta, struct fib6_info *rt)
static const struct bpf_iter_reg ipv6_route_reg_info = { BTF_ID_LIST(btf_fib6_info_id)
BTF_ID(struct, fib6_info)
static struct bpf_iter_reg ipv6_route_reg_info = {
.target = "ipv6_route", .target = "ipv6_route",
.seq_ops = &ipv6_route_seq_ops, .seq_ops = &ipv6_route_seq_ops,
.init_seq_private = bpf_iter_init_seq_net, .init_seq_private = bpf_iter_init_seq_net,
@ -6438,6 +6442,7 @@ static const struct bpf_iter_reg ipv6_route_reg_info = {
static int __init bpf_iter_register(void) static int __init bpf_iter_register(void)
{ {
ipv6_route_reg_info.ctx_arg_info[0].btf_id = *btf_fib6_info_id;
return bpf_iter_reg_target(&ipv6_route_reg_info); return bpf_iter_reg_target(&ipv6_route_reg_info);
} }

View File

@ -60,6 +60,7 @@
#include <linux/genetlink.h> #include <linux/genetlink.h>
#include <linux/net_namespace.h> #include <linux/net_namespace.h>
#include <linux/nospec.h> #include <linux/nospec.h>
#include <linux/btf_ids.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/netns/generic.h> #include <net/netns/generic.h>
@ -2803,7 +2804,10 @@ static const struct rhashtable_params netlink_rhashtable_params = {
}; };
#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS) #if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
static const struct bpf_iter_reg netlink_reg_info = { BTF_ID_LIST(btf_netlink_sock_id)
BTF_ID(struct, netlink_sock)
static struct bpf_iter_reg netlink_reg_info = {
.target = "netlink", .target = "netlink",
.seq_ops = &netlink_seq_ops, .seq_ops = &netlink_seq_ops,
.init_seq_private = bpf_iter_init_seq_net, .init_seq_private = bpf_iter_init_seq_net,
@ -2818,6 +2822,7 @@ static const struct bpf_iter_reg netlink_reg_info = {
static int __init bpf_iter_register(void) static int __init bpf_iter_register(void)
{ {
netlink_reg_info.ctx_arg_info[0].btf_id = *btf_netlink_sock_id;
return bpf_iter_reg_target(&netlink_reg_info); return bpf_iter_reg_target(&netlink_reg_info);
} }
#endif #endif