If we use resources more wisely we may be able to use programmable engines in a denser fashion. Try to squeeze used registers together.
Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com> Reviewed-by: Dinan Gunawardena <dgunaward...@netronome.com> Reviewed-by: Simon Horman <simon.hor...@netronome.com> --- drivers/net/ethernet/netronome/nfp/nfp_bpf_jit.c | 51 +++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_bpf_jit.c b/drivers/net/ethernet/netronome/nfp/nfp_bpf_jit.c index a83e7404598f..b4dd04f4c653 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_bpf_jit.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_bpf_jit.c @@ -847,6 +847,42 @@ static void nfp_bpf_opt_reg_init(struct nfp_prog *nfp_prog) } } +/* Try to rename registers so that program uses only low ones */ +static int nfp_bpf_opt_reg_rename(struct nfp_prog *nfp_prog) +{ + bool reg_used[__MAX_BPF_REG] = {}; + u8 tgt_reg[__MAX_BPF_REG] = {}; + struct nfp_insn_meta *meta; + unsigned int i, j; + + list_for_each_entry(meta, &nfp_prog->insns, l) { + if (meta->skip) + continue; + + reg_used[meta->insn.src_reg] = true; + reg_used[meta->insn.dst_reg] = true; + } + + if (reg_used[BPF_REG_10]) { + pr_err("Detected use of stack ptr\n"); + return -EINVAL; + } + + for (i = 0, j = 0; i < ARRAY_SIZE(tgt_reg); i++) { + if (!reg_used[i]) + continue; + + tgt_reg[i] = j++; + } + + list_for_each_entry(meta, &nfp_prog->insns, l) { + meta->insn.src_reg = tgt_reg[meta->insn.src_reg]; + meta->insn.dst_reg = tgt_reg[meta->insn.dst_reg]; + } + + return 0; +} + /* Remove masking after load since our load guarantees this is not needed */ static void nfp_bpf_opt_ld_mask(struct nfp_prog *nfp_prog) { @@ -921,11 +957,20 @@ static void nfp_bpf_opt_ld_shift(struct nfp_prog *nfp_prog) } } -static void nfp_bpf_optimize(struct nfp_prog *nfp_prog) +static int nfp_bpf_optimize(struct nfp_prog *nfp_prog) { + int ret; + nfp_bpf_opt_reg_init(nfp_prog); + + ret = nfp_bpf_opt_reg_rename(nfp_prog); + if (ret) + return ret; + nfp_bpf_opt_ld_mask(nfp_prog); nfp_bpf_opt_ld_shift(nfp_prog); + + return 0; } /** @@ -961,7 +1006,9 @@ nfp_bpf_jit(struct bpf_prog *filter, void *prog_mem, unsigned int prog_start, if (ret) goto out; - nfp_bpf_optimize(nfp_prog); + ret = nfp_bpf_optimize(nfp_prog); + if (ret) + goto out; nfp_prog->prog = prog_mem; nfp_prog->__prog_alloc_len = prog_sz; -- 1.9.1