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: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
96be4325f4
Коммит
24701ecea7
|
@ -117,11 +117,9 @@ struct bpf_prog;
|
|||
|
||||
struct bpf_prog_aux {
|
||||
atomic_t refcnt;
|
||||
bool is_gpl_compatible;
|
||||
enum bpf_prog_type prog_type;
|
||||
u32 used_map_cnt;
|
||||
const struct bpf_verifier_ops *ops;
|
||||
struct bpf_map **used_maps;
|
||||
u32 used_map_cnt;
|
||||
struct bpf_prog *prog;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
|
|
@ -308,9 +308,11 @@ struct bpf_binary_header {
|
|||
struct bpf_prog {
|
||||
u16 pages; /* Number of allocated pages */
|
||||
bool jited; /* Is our filter JIT'ed? */
|
||||
bool gpl_compatible; /* Is our filter GPL compatible? */
|
||||
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 sock_fprog_kern *orig_prog; /* Original BPF program */
|
||||
unsigned int (*bpf_func)(const struct sk_buff *skb,
|
||||
const struct bpf_insn *filter);
|
||||
/* Instructions for interpreter */
|
||||
|
|
|
@ -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) {
|
||||
if (tl->type == type) {
|
||||
prog->aux->ops = tl->ops;
|
||||
prog->aux->prog_type = type;
|
||||
prog->type = type;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -508,7 +509,7 @@ static int bpf_prog_load(union bpf_attr *attr)
|
|||
prog->jited = false;
|
||||
|
||||
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 */
|
||||
err = find_prog_type(type, prog);
|
||||
|
@ -517,7 +518,6 @@ static int bpf_prog_load(union bpf_attr *attr)
|
|||
|
||||
/* run eBPF verifier */
|
||||
err = bpf_check(prog, attr);
|
||||
|
||||
if (err < 0)
|
||||
goto free_used_maps;
|
||||
|
||||
|
@ -528,7 +528,6 @@ static int bpf_prog_load(union bpf_attr *attr)
|
|||
bpf_prog_select_runtime(prog);
|
||||
|
||||
err = anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog, O_RDWR | O_CLOEXEC);
|
||||
|
||||
if (err < 0)
|
||||
/* failed to allocate fd */
|
||||
goto free_used_maps;
|
||||
|
|
|
@ -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 */
|
||||
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");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1205,7 +1205,7 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn)
|
|||
struct reg_state *reg;
|
||||
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");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -814,7 +814,7 @@ static void bpf_release_orig_filter(struct bpf_prog *fp)
|
|||
|
||||
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);
|
||||
} else {
|
||||
bpf_release_orig_filter(prog);
|
||||
|
@ -1105,7 +1105,7 @@ int sk_attach_bpf(u32 ufd, struct sock *sk)
|
|||
if (IS_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);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче