提交 24701ece 编写于 作者: D Daniel Borkmann 提交者: David S. Miller

ebpf: move read-only fields to bpf_prog and shrink bpf_prog_aux

is_gpl_compatible and prog_type should be moved directly into bpf_prog
as they stay immutable during bpf_prog's lifetime, are core attributes
and they can be locked as read-only later on via bpf_prog_select_runtime().

With a bit of rearranging, this also allows us to shrink bpf_prog_aux
to exactly 1 cacheline.
Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
Acked-by: NAlexei Starovoitov <ast@plumgrid.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 96be4325
...@@ -117,11 +117,9 @@ struct bpf_prog; ...@@ -117,11 +117,9 @@ struct bpf_prog;
struct bpf_prog_aux { struct bpf_prog_aux {
atomic_t refcnt; atomic_t refcnt;
bool is_gpl_compatible; u32 used_map_cnt;
enum bpf_prog_type prog_type;
const struct bpf_verifier_ops *ops; const struct bpf_verifier_ops *ops;
struct bpf_map **used_maps; struct bpf_map **used_maps;
u32 used_map_cnt;
struct bpf_prog *prog; struct bpf_prog *prog;
struct work_struct work; struct work_struct work;
}; };
......
...@@ -308,9 +308,11 @@ struct bpf_binary_header { ...@@ -308,9 +308,11 @@ struct bpf_binary_header {
struct bpf_prog { struct bpf_prog {
u16 pages; /* Number of allocated pages */ u16 pages; /* Number of allocated pages */
bool jited; /* Is our filter JIT'ed? */ bool jited; /* Is our filter JIT'ed? */
bool gpl_compatible; /* Is our filter GPL compatible? */
u32 len; /* Number of filter blocks */ u32 len; /* Number of filter blocks */
struct sock_fprog_kern *orig_prog; /* Original BPF program */ enum bpf_prog_type type; /* Type of BPF program */
struct bpf_prog_aux *aux; /* Auxiliary fields */ struct bpf_prog_aux *aux; /* Auxiliary fields */
struct sock_fprog_kern *orig_prog; /* Original BPF program */
unsigned int (*bpf_func)(const struct sk_buff *skb, unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct bpf_insn *filter); const struct bpf_insn *filter);
/* Instructions for interpreter */ /* Instructions for interpreter */
......
...@@ -354,10 +354,11 @@ static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog) ...@@ -354,10 +354,11 @@ static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
list_for_each_entry(tl, &bpf_prog_types, list_node) { list_for_each_entry(tl, &bpf_prog_types, list_node) {
if (tl->type == type) { if (tl->type == type) {
prog->aux->ops = tl->ops; prog->aux->ops = tl->ops;
prog->aux->prog_type = type; prog->type = type;
return 0; return 0;
} }
} }
return -EINVAL; return -EINVAL;
} }
...@@ -508,7 +509,7 @@ static int bpf_prog_load(union bpf_attr *attr) ...@@ -508,7 +509,7 @@ static int bpf_prog_load(union bpf_attr *attr)
prog->jited = false; prog->jited = false;
atomic_set(&prog->aux->refcnt, 1); atomic_set(&prog->aux->refcnt, 1);
prog->aux->is_gpl_compatible = is_gpl; prog->gpl_compatible = is_gpl;
/* find program type: socket_filter vs tracing_filter */ /* find program type: socket_filter vs tracing_filter */
err = find_prog_type(type, prog); err = find_prog_type(type, prog);
...@@ -517,7 +518,6 @@ static int bpf_prog_load(union bpf_attr *attr) ...@@ -517,7 +518,6 @@ static int bpf_prog_load(union bpf_attr *attr)
/* run eBPF verifier */ /* run eBPF verifier */
err = bpf_check(prog, attr); err = bpf_check(prog, attr);
if (err < 0) if (err < 0)
goto free_used_maps; goto free_used_maps;
...@@ -528,7 +528,6 @@ static int bpf_prog_load(union bpf_attr *attr) ...@@ -528,7 +528,6 @@ static int bpf_prog_load(union bpf_attr *attr)
bpf_prog_select_runtime(prog); bpf_prog_select_runtime(prog);
err = anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog, O_RDWR | O_CLOEXEC); err = anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog, O_RDWR | O_CLOEXEC);
if (err < 0) if (err < 0)
/* failed to allocate fd */ /* failed to allocate fd */
goto free_used_maps; goto free_used_maps;
......
...@@ -852,7 +852,7 @@ static int check_call(struct verifier_env *env, int func_id) ...@@ -852,7 +852,7 @@ static int check_call(struct verifier_env *env, int func_id)
} }
/* eBPF programs must be GPL compatible to use GPL-ed functions */ /* eBPF programs must be GPL compatible to use GPL-ed functions */
if (!env->prog->aux->is_gpl_compatible && fn->gpl_only) { if (!env->prog->gpl_compatible && fn->gpl_only) {
verbose("cannot call GPL only function from proprietary program\n"); verbose("cannot call GPL only function from proprietary program\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1205,7 +1205,7 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn) ...@@ -1205,7 +1205,7 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn)
struct reg_state *reg; struct reg_state *reg;
int i, err; int i, err;
if (!may_access_skb(env->prog->aux->prog_type)) { if (!may_access_skb(env->prog->type)) {
verbose("BPF_LD_ABS|IND instructions not allowed for this program type\n"); verbose("BPF_LD_ABS|IND instructions not allowed for this program type\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -814,7 +814,7 @@ static void bpf_release_orig_filter(struct bpf_prog *fp) ...@@ -814,7 +814,7 @@ static void bpf_release_orig_filter(struct bpf_prog *fp)
static void __bpf_prog_release(struct bpf_prog *prog) static void __bpf_prog_release(struct bpf_prog *prog)
{ {
if (prog->aux->prog_type == BPF_PROG_TYPE_SOCKET_FILTER) { if (prog->type == BPF_PROG_TYPE_SOCKET_FILTER) {
bpf_prog_put(prog); bpf_prog_put(prog);
} else { } else {
bpf_release_orig_filter(prog); bpf_release_orig_filter(prog);
...@@ -1105,7 +1105,7 @@ int sk_attach_bpf(u32 ufd, struct sock *sk) ...@@ -1105,7 +1105,7 @@ int sk_attach_bpf(u32 ufd, struct sock *sk)
if (IS_ERR(prog)) if (IS_ERR(prog))
return PTR_ERR(prog); return PTR_ERR(prog);
if (prog->aux->prog_type != BPF_PROG_TYPE_SOCKET_FILTER) { if (prog->type != BPF_PROG_TYPE_SOCKET_FILTER) {
bpf_prog_put(prog); bpf_prog_put(prog);
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册