Add a verifier callback to the nfp JIT to remove the instructions
the verifier deemed to be dead.

Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Reviewed-by: Quentin Monnet <quentin.mon...@netronome.com>
---
 drivers/net/ethernet/netronome/nfp/bpf/main.h |  6 ++++-
 .../net/ethernet/netronome/nfp/bpf/offload.c  |  1 +
 .../net/ethernet/netronome/nfp/bpf/verifier.c | 23 +++++++++++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h 
b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index a33aa7df1979..5813c3e13ebe 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -247,9 +247,12 @@ struct nfp_bpf_reg_state {
 #define FLAG_INSN_SKIP_NOOP                    BIT(3)
 /* Instruction is optimized out based on preceding instructions */
 #define FLAG_INSN_SKIP_PREC_DEPENDENT          BIT(4)
+/* Instruction is optimized by the verifier */
+#define FLAG_INSN_SKIP_VERIFIER_OPT            BIT(5)
 
 #define FLAG_INSN_SKIP_MASK            (FLAG_INSN_SKIP_NOOP | \
-                                        FLAG_INSN_SKIP_PREC_DEPENDENT)
+                                        FLAG_INSN_SKIP_PREC_DEPENDENT | \
+                                        FLAG_INSN_SKIP_VERIFIER_OPT)
 
 /**
  * struct nfp_insn_meta - BPF instruction wrapper
@@ -533,6 +536,7 @@ int nfp_bpf_finalize(struct bpf_verifier_env *env);
 
 int nfp_bpf_opt_replace_insn(struct bpf_verifier_env *env, u32 off,
                             struct bpf_insn *insn);
+int nfp_bpf_opt_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt);
 
 extern const struct bpf_prog_offload_ops nfp_bpf_dev_ops;
 
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c 
b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index 877c1b8f95e2..1bf37b2c7eef 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -593,6 +593,7 @@ const struct bpf_prog_offload_ops nfp_bpf_dev_ops = {
        .insn_hook      = nfp_verify_insn,
        .finalize       = nfp_bpf_finalize,
        .replace_insn   = nfp_bpf_opt_replace_insn,
+       .remove_insns   = nfp_bpf_opt_remove_insns,
        .prepare        = nfp_bpf_verifier_prep,
        .translate      = nfp_bpf_translate,
        .destroy        = nfp_bpf_destroy,
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c 
b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c
index 02a4d1050a89..df584e035f9e 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c
@@ -810,3 +810,26 @@ int nfp_bpf_opt_replace_insn(struct bpf_verifier_env *env, 
u32 off,
                meta->insn.code, insn->code);
        return -EINVAL;
 }
+
+int nfp_bpf_opt_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt)
+{
+       struct nfp_prog *nfp_prog = env->prog->aux->offload->dev_priv;
+       struct nfp_insn_meta *meta;
+       unsigned int i;
+
+       meta = nfp_bpf_goto_meta(nfp_prog, nfp_prog->verifier_meta, off);
+
+       for (i = 0; i < cnt; i++) {
+               if (WARN_ON_ONCE(&meta->l == &nfp_prog->insns))
+                       return -EINVAL;
+
+               /* doesn't count if it already has the flag */
+               if (meta->flags & FLAG_INSN_SKIP_VERIFIER_OPT)
+                       i--;
+
+               meta->flags |= FLAG_INSN_SKIP_VERIFIER_OPT;
+               meta = list_next_entry(meta, l);
+       }
+
+       return 0;
+}
-- 
2.19.2

Reply via email to