diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2019-01-22 22:45:28 -0800 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2019-01-23 17:35:32 -0800 |
commit | a32014b351662fd67c7e0f807855f527d0834d00 (patch) | |
tree | df4010a54481e94a3beda90fedf65f315e7517b0 /drivers/net/ethernet/netronome/nfp/bpf/verifier.c | |
parent | nfp: bpf: save original program length (diff) | |
download | linux-dev-a32014b351662fd67c7e0f807855f527d0834d00.tar.xz linux-dev-a32014b351662fd67c7e0f807855f527d0834d00.zip |
nfp: bpf: support optimizing dead branches
Verifier will now optimize out branches to dead code, implement
the replace_insn callback to take advantage of that optimization.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to '')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/bpf/verifier.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index 2712ab17d57c..32468e1b1b73 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -786,3 +786,37 @@ int nfp_bpf_finalize(struct bpf_verifier_env *env) return 0; } + +int nfp_bpf_opt_replace_insn(struct bpf_verifier_env *env, u32 off, + struct bpf_insn *insn) +{ + struct nfp_prog *nfp_prog = env->prog->aux->offload->dev_priv; + struct bpf_insn_aux_data *aux_data = env->insn_aux_data; + struct nfp_insn_meta *meta = nfp_prog->verifier_meta; + + meta = nfp_bpf_goto_meta(nfp_prog, meta, aux_data[off].orig_idx); + nfp_prog->verifier_meta = meta; + + /* conditional jump to jump conversion */ + if (is_mbpf_cond_jump(meta) && + insn->code == (BPF_JMP | BPF_JA | BPF_K)) { + unsigned int tgt_off; + + tgt_off = off + insn->off + 1; + + if (!insn->off) { + meta->jmp_dst = list_next_entry(meta, l); + meta->jump_neg_op = false; + } else if (meta->jmp_dst->n != aux_data[tgt_off].orig_idx) { + pr_vlog(env, "branch hard wire at %d changes target %d -> %d\n", + off, meta->jmp_dst->n, + aux_data[tgt_off].orig_idx); + return -EINVAL; + } + return 0; + } + + pr_vlog(env, "unsupported instruction replacement %hhx -> %hhx\n", + meta->insn.code, insn->code); + return -EINVAL; +} |