Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24701ece authored by Daniel Borkmann's avatar Daniel Borkmann Committed by David S. Miller
Browse files

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: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 96be4325
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -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;
};
+3 −1
Original line number Diff line number Diff line
@@ -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 */
+3 −4
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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;
	}
+2 −2
Original line number Diff line number Diff line
@@ -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;
	}