Skip to content

Commit 9a06927

Browse files
Jakub KicinskiAlexei Starovoitov
authored andcommitted
nfp: bpf: support removing dead code
Add a verifier callback to the nfp JIT to remove the instructions the verifier deemed to be dead. Signed-off-by: Jakub Kicinski <[email protected]> Reviewed-by: Quentin Monnet <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent a32014b commit 9a06927

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

drivers/net/ethernet/netronome/nfp/bpf/main.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,12 @@ struct nfp_bpf_reg_state {
247247
#define FLAG_INSN_SKIP_NOOP BIT(3)
248248
/* Instruction is optimized out based on preceding instructions */
249249
#define FLAG_INSN_SKIP_PREC_DEPENDENT BIT(4)
250+
/* Instruction is optimized by the verifier */
251+
#define FLAG_INSN_SKIP_VERIFIER_OPT BIT(5)
250252

251253
#define FLAG_INSN_SKIP_MASK (FLAG_INSN_SKIP_NOOP | \
252-
FLAG_INSN_SKIP_PREC_DEPENDENT)
254+
FLAG_INSN_SKIP_PREC_DEPENDENT | \
255+
FLAG_INSN_SKIP_VERIFIER_OPT)
253256

254257
/**
255258
* struct nfp_insn_meta - BPF instruction wrapper
@@ -533,6 +536,7 @@ int nfp_bpf_finalize(struct bpf_verifier_env *env);
533536

534537
int nfp_bpf_opt_replace_insn(struct bpf_verifier_env *env, u32 off,
535538
struct bpf_insn *insn);
539+
int nfp_bpf_opt_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt);
536540

537541
extern const struct bpf_prog_offload_ops nfp_bpf_dev_ops;
538542

drivers/net/ethernet/netronome/nfp/bpf/offload.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ static int nfp_bpf_translate(struct bpf_prog *prog)
220220
unsigned int max_instr;
221221
int err;
222222

223+
/* We depend on dead code elimination succeeding */
224+
if (prog->aux->offload->opt_failed)
225+
return -EINVAL;
226+
223227
max_instr = nn_readw(nn, NFP_NET_CFG_BPF_MAX_LEN);
224228
nfp_prog->__prog_alloc_len = max_instr * sizeof(u64);
225229

@@ -593,6 +597,7 @@ const struct bpf_prog_offload_ops nfp_bpf_dev_ops = {
593597
.insn_hook = nfp_verify_insn,
594598
.finalize = nfp_bpf_finalize,
595599
.replace_insn = nfp_bpf_opt_replace_insn,
600+
.remove_insns = nfp_bpf_opt_remove_insns,
596601
.prepare = nfp_bpf_verifier_prep,
597602
.translate = nfp_bpf_translate,
598603
.destroy = nfp_bpf_destroy,

drivers/net/ethernet/netronome/nfp/bpf/verifier.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,3 +820,27 @@ int nfp_bpf_opt_replace_insn(struct bpf_verifier_env *env, u32 off,
820820
meta->insn.code, insn->code);
821821
return -EINVAL;
822822
}
823+
824+
int nfp_bpf_opt_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt)
825+
{
826+
struct nfp_prog *nfp_prog = env->prog->aux->offload->dev_priv;
827+
struct bpf_insn_aux_data *aux_data = env->insn_aux_data;
828+
struct nfp_insn_meta *meta = nfp_prog->verifier_meta;
829+
unsigned int i;
830+
831+
meta = nfp_bpf_goto_meta(nfp_prog, meta, aux_data[off].orig_idx);
832+
833+
for (i = 0; i < cnt; i++) {
834+
if (WARN_ON_ONCE(&meta->l == &nfp_prog->insns))
835+
return -EINVAL;
836+
837+
/* doesn't count if it already has the flag */
838+
if (meta->flags & FLAG_INSN_SKIP_VERIFIER_OPT)
839+
i--;
840+
841+
meta->flags |= FLAG_INSN_SKIP_VERIFIER_OPT;
842+
meta = list_next_entry(meta, l);
843+
}
844+
845+
return 0;
846+
}

0 commit comments

Comments
 (0)