Commit e2fc6114 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Alexei Starovoitov
Browse files

nfp: bpf: save original program length



Instead of passing env->prog->len around, and trying to adjust
for optimized out instructions just save the initial number
of instructions in struct nfp_prog.

Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 91a87a58
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4327,7 +4327,7 @@ int nfp_bpf_jit(struct nfp_prog *nfp_prog)
	return ret;
}

void nfp_bpf_jit_prepare(struct nfp_prog *nfp_prog, unsigned int cnt)
void nfp_bpf_jit_prepare(struct nfp_prog *nfp_prog)
{
	struct nfp_insn_meta *meta;

@@ -4355,7 +4355,7 @@ void nfp_bpf_jit_prepare(struct nfp_prog *nfp_prog, unsigned int cnt)
		else
			dst_idx = meta->n + 1 + meta->insn.off;

		dst_meta = nfp_bpf_goto_meta(nfp_prog, meta, dst_idx, cnt);
		dst_meta = nfp_bpf_goto_meta(nfp_prog, meta, dst_idx);

		if (pseudo_call)
			dst_meta->flags |= FLAG_INSN_IS_SUBPROG_START;
+4 −2
Original line number Diff line number Diff line
@@ -462,6 +462,7 @@ struct nfp_bpf_subprog_info {
 * @subprog_cnt: number of sub-programs, including main function
 * @map_records: the map record pointers from bpf->maps_neutral
 * @subprog: pointer to an array of objects holding info about sub-programs
 * @n_insns: number of instructions on @insns list
 * @insns: list of BPF instruction wrappers (struct nfp_insn_meta)
 */
struct nfp_prog {
@@ -494,6 +495,7 @@ struct nfp_prog {
	struct nfp_bpf_neutral_map **map_records;
	struct nfp_bpf_subprog_info *subprog;

	unsigned int n_insns;
	struct list_head insns;
};

@@ -510,7 +512,7 @@ struct nfp_bpf_vnic {
};

bool nfp_is_subprog_start(struct nfp_insn_meta *meta);
void nfp_bpf_jit_prepare(struct nfp_prog *nfp_prog, unsigned int cnt);
void nfp_bpf_jit_prepare(struct nfp_prog *nfp_prog);
int nfp_bpf_jit(struct nfp_prog *prog);
bool nfp_bpf_supported_opcode(u8 code);

@@ -531,7 +533,7 @@ int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog,

struct nfp_insn_meta *
nfp_bpf_goto_meta(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
		  unsigned int insn_idx, unsigned int n_insns);
		  unsigned int insn_idx);

void *nfp_bpf_relo_for_vnic(struct nfp_prog *nfp_prog, struct nfp_bpf_vnic *bv);

+2 −1
Original line number Diff line number Diff line
@@ -163,8 +163,9 @@ nfp_prog_prepare(struct nfp_prog *nfp_prog, const struct bpf_insn *prog,

		list_add_tail(&meta->l, &nfp_prog->insns);
	}
	nfp_prog->n_insns = cnt;

	nfp_bpf_jit_prepare(nfp_prog, cnt);
	nfp_bpf_jit_prepare(nfp_prog);

	return 0;
}
+7 −9
Original line number Diff line number Diff line
@@ -18,15 +18,15 @@

struct nfp_insn_meta *
nfp_bpf_goto_meta(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
		  unsigned int insn_idx, unsigned int n_insns)
		  unsigned int insn_idx)
{
	unsigned int forward, backward, i;

	backward = meta->n - insn_idx;
	forward = insn_idx - meta->n;

	if (min(forward, backward) > n_insns - insn_idx - 1) {
		backward = n_insns - insn_idx - 1;
	if (min(forward, backward) > nfp_prog->n_insns - insn_idx - 1) {
		backward = nfp_prog->n_insns - insn_idx - 1;
		meta = nfp_prog_last_meta(nfp_prog);
	}
	if (min(forward, backward) > insn_idx && backward > insn_idx) {
@@ -629,7 +629,7 @@ int nfp_verify_insn(struct bpf_verifier_env *env, int insn_idx,
	struct nfp_prog *nfp_prog = env->prog->aux->offload->dev_priv;
	struct nfp_insn_meta *meta = nfp_prog->verifier_meta;

	meta = nfp_bpf_goto_meta(nfp_prog, meta, insn_idx, env->prog->len);
	meta = nfp_bpf_goto_meta(nfp_prog, meta, insn_idx);
	nfp_prog->verifier_meta = meta;

	if (!nfp_bpf_supported_opcode(meta->insn.code)) {
@@ -690,8 +690,7 @@ nfp_assign_subprog_idx_and_regs(struct bpf_verifier_env *env,
	return 0;
}

static unsigned int
nfp_bpf_get_stack_usage(struct nfp_prog *nfp_prog, unsigned int cnt)
static unsigned int nfp_bpf_get_stack_usage(struct nfp_prog *nfp_prog)
{
	struct nfp_insn_meta *meta = nfp_prog_first_meta(nfp_prog);
	unsigned int max_depth = 0, depth = 0, frame = 0;
@@ -726,7 +725,7 @@ continue_subprog:

		/* Find the callee and start processing it. */
		meta = nfp_bpf_goto_meta(nfp_prog, meta,
					 meta->n + 1 + meta->insn.imm, cnt);
					 meta->n + 1 + meta->insn.imm);
		idx = meta->subprog_idx;
		frame++;
		goto process_subprog;
@@ -778,8 +777,7 @@ int nfp_bpf_finalize(struct bpf_verifier_env *env)

	nn = netdev_priv(env->prog->aux->offload->netdev);
	max_stack = nn_readb(nn, NFP_NET_CFG_BPF_STACK_SZ) * 64;
	nfp_prog->stack_size = nfp_bpf_get_stack_usage(nfp_prog,
						       env->prog->len);
	nfp_prog->stack_size = nfp_bpf_get_stack_usage(nfp_prog);
	if (nfp_prog->stack_size > max_stack) {
		pr_vlog(env, "stack too large: program %dB > FW stack %dB\n",
			nfp_prog->stack_size, max_stack);