aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2018-01-10 07:26:02 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2018-01-10 07:49:35 -0500
commit44a12ecc1cab7dcf4647dfef7d94f5c559c01407 (patch)
treef5fa8149f2de8a7826ee0ad8ef63ef3485b30d28
parent2314fe9ed0a1760ceab96b81e6b7181963c93254 (diff)
nfp: bpf: don't depend on high order allocations for program image
The translator pre-allocates a buffer of maximal program size. Due to HW/FW limitations the program buffer can't currently be longer than 128Kb, so we used to kmalloc() it, and then map for DMA directly. Now that the late branch resolution is copying the program image anyway, we can just kvmalloc() the buffer. While at it, after translation reallocate the buffer to save space. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/jit.c16
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/offload.c5
2 files changed, 19 insertions, 2 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
index 3a5c747fd12b..5deebbc18cfd 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
@@ -2676,6 +2676,20 @@ static int nfp_bpf_ustore_calc(u64 *prog, unsigned int len)
2676 return 0; 2676 return 0;
2677} 2677}
2678 2678
2679static void nfp_bpf_prog_trim(struct nfp_prog *nfp_prog)
2680{
2681 void *prog;
2682
2683 prog = kvmalloc_array(nfp_prog->prog_len, sizeof(u64), GFP_KERNEL);
2684 if (!prog)
2685 return;
2686
2687 nfp_prog->__prog_alloc_len = nfp_prog->prog_len * sizeof(u64);
2688 memcpy(prog, nfp_prog->prog, nfp_prog->__prog_alloc_len);
2689 kvfree(nfp_prog->prog);
2690 nfp_prog->prog = prog;
2691}
2692
2679int nfp_bpf_jit(struct nfp_prog *nfp_prog) 2693int nfp_bpf_jit(struct nfp_prog *nfp_prog)
2680{ 2694{
2681 int ret; 2695 int ret;
@@ -2691,6 +2705,8 @@ int nfp_bpf_jit(struct nfp_prog *nfp_prog)
2691 return -EINVAL; 2705 return -EINVAL;
2692 } 2706 }
2693 2707
2708 nfp_bpf_prog_trim(nfp_prog);
2709
2694 return ret; 2710 return ret;
2695} 2711}
2696 2712
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
index 5f165e1d7648..f63560550753 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -42,6 +42,7 @@
42#include <linux/jiffies.h> 42#include <linux/jiffies.h>
43#include <linux/timer.h> 43#include <linux/timer.h>
44#include <linux/list.h> 44#include <linux/list.h>
45#include <linux/mm.h>
45 46
46#include <net/pkt_cls.h> 47#include <net/pkt_cls.h>
47#include <net/tc_act/tc_gact.h> 48#include <net/tc_act/tc_gact.h>
@@ -135,7 +136,7 @@ int nfp_bpf_translate(struct nfp_app *app, struct nfp_net *nn,
135 max_instr = nn_readw(nn, NFP_NET_CFG_BPF_MAX_LEN); 136 max_instr = nn_readw(nn, NFP_NET_CFG_BPF_MAX_LEN);
136 nfp_prog->__prog_alloc_len = max_instr * sizeof(u64); 137 nfp_prog->__prog_alloc_len = max_instr * sizeof(u64);
137 138
138 nfp_prog->prog = kmalloc(nfp_prog->__prog_alloc_len, GFP_KERNEL); 139 nfp_prog->prog = kvmalloc(nfp_prog->__prog_alloc_len, GFP_KERNEL);
139 if (!nfp_prog->prog) 140 if (!nfp_prog->prog)
140 return -ENOMEM; 141 return -ENOMEM;
141 142
@@ -147,7 +148,7 @@ int nfp_bpf_destroy(struct nfp_app *app, struct nfp_net *nn,
147{ 148{
148 struct nfp_prog *nfp_prog = prog->aux->offload->dev_priv; 149 struct nfp_prog *nfp_prog = prog->aux->offload->dev_priv;
149 150
150 kfree(nfp_prog->prog); 151 kvfree(nfp_prog->prog);
151 nfp_prog_free(nfp_prog); 152 nfp_prog_free(nfp_prog);
152 153
153 return 0; 154 return 0;