nfp: bpf: save original program length
authorJakub Kicinski <jakub.kicinski@netronome.com>
Wed, 23 Jan 2019 06:45:27 +0000 (22:45 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 24 Jan 2019 01:35:32 +0000 (17:35 -0800)
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: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
drivers/net/ethernet/netronome/nfp/bpf/jit.c
drivers/net/ethernet/netronome/nfp/bpf/main.h
drivers/net/ethernet/netronome/nfp/bpf/offload.c
drivers/net/ethernet/netronome/nfp/bpf/verifier.c

index 054382b9cbe61f7781278891f6482a12e1945ad9..3308fd92c0178de7e75a2da394f61286eaf1e1bf 100644 (file)
@@ -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;
index 40291aedd89520f797eaecdbd2bca36427ee63c2..07879eee3d469445f3d461885d4bb37d0567cadf 100644 (file)
@@ -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);
 
index f0283854fade41fe2e3038318d64a7d12079354d..c10aab392cf6bed86420938d090080de14402992 100644 (file)
@@ -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;
 }
index 337bb862ec1dd96973b24b755caefee1e7ea3532..2712ab17d57c84a49a33ff485042cb1b40fe0209 100644 (file)
 
 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);