aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiong Wang <jiong.wang@netronome.com>2018-03-28 20:48:25 -0400
committerAlexei Starovoitov <ast@kernel.org>2018-03-28 22:36:12 -0400
commitbe75923786aa28774bf2b5ef8184590a52429103 (patch)
tree30e4964b10004950731a37c8f8ff3dd550bec108
parentf6ef56589374670b7c1939720dfa00212bd80a5b (diff)
nfp: bpf: read from packet data cache for PTR_TO_PACKET
This patch assumes there is a packet data cache, and would try to read packet data from the cache instead of from memory. This patch only implements the optimisation "backend", it doesn't build the packet data cache, so this optimisation is not enabled. This patch has only enabled aligned packet data read, i.e. when the read offset to the start of cache is REG_WIDTH aligned. Signed-off-by: Jiong Wang <jiong.wang@netronome.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/jit.c80
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/main.h9
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_asm.h1
3 files changed, 88 insertions, 2 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
index 56451edf01c2..0a2c1d87fed2 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
@@ -1838,6 +1838,74 @@ mem_ldx_emem(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
1838 tmp_reg, meta->insn.dst_reg * 2, size); 1838 tmp_reg, meta->insn.dst_reg * 2, size);
1839} 1839}
1840 1840
1841static void
1842mem_ldx_data_init_pktcache(struct nfp_prog *nfp_prog,
1843 struct nfp_insn_meta *meta)
1844{
1845 s16 range_start = meta->pkt_cache.range_start;
1846 s16 range_end = meta->pkt_cache.range_end;
1847 swreg src_base, off;
1848 u8 xfer_num, len;
1849 bool indir;
1850
1851 off = re_load_imm_any(nfp_prog, range_start, imm_b(nfp_prog));
1852 src_base = reg_a(meta->insn.src_reg * 2);
1853 len = range_end - range_start;
1854 xfer_num = round_up(len, REG_WIDTH) / REG_WIDTH;
1855
1856 indir = len > 8 * REG_WIDTH;
1857 /* Setup PREV_ALU for indirect mode. */
1858 if (indir)
1859 wrp_immed(nfp_prog, reg_none(),
1860 CMD_OVE_LEN | FIELD_PREP(CMD_OV_LEN, xfer_num - 1));
1861
1862 /* Cache memory into transfer-in registers. */
1863 emit_cmd_any(nfp_prog, CMD_TGT_READ32_SWAP, CMD_MODE_32b, 0, src_base,
1864 off, xfer_num - 1, true, indir);
1865}
1866
1867static int
1868mem_ldx_data_from_pktcache_aligned(struct nfp_prog *nfp_prog,
1869 struct nfp_insn_meta *meta,
1870 unsigned int size)
1871{
1872 swreg dst_lo, dst_hi, src_lo;
1873 u8 dst_gpr, idx;
1874
1875 idx = (meta->insn.off - meta->pkt_cache.range_start) / REG_WIDTH;
1876 dst_gpr = meta->insn.dst_reg * 2;
1877 dst_hi = reg_both(dst_gpr + 1);
1878 dst_lo = reg_both(dst_gpr);
1879 src_lo = reg_xfer(idx);
1880
1881 if (size < REG_WIDTH) {
1882 wrp_reg_subpart(nfp_prog, dst_lo, src_lo, size, 0);
1883 wrp_immed(nfp_prog, dst_hi, 0);
1884 } else if (size == REG_WIDTH) {
1885 wrp_mov(nfp_prog, dst_lo, src_lo);
1886 wrp_immed(nfp_prog, dst_hi, 0);
1887 } else {
1888 swreg src_hi = reg_xfer(idx + 1);
1889
1890 wrp_mov(nfp_prog, dst_lo, src_lo);
1891 wrp_mov(nfp_prog, dst_hi, src_hi);
1892 }
1893
1894 return 0;
1895}
1896
1897static int
1898mem_ldx_data_from_pktcache(struct nfp_prog *nfp_prog,
1899 struct nfp_insn_meta *meta, unsigned int size)
1900{
1901 u8 off = meta->insn.off - meta->pkt_cache.range_start;
1902
1903 if (WARN_ON_ONCE(!IS_ALIGNED(off, REG_WIDTH)))
1904 return -EOPNOTSUPP;
1905
1906 return mem_ldx_data_from_pktcache_aligned(nfp_prog, meta, size);
1907}
1908
1841static int 1909static int
1842mem_ldx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, 1910mem_ldx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
1843 unsigned int size) 1911 unsigned int size)
@@ -1852,8 +1920,16 @@ mem_ldx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
1852 return mem_ldx_skb(nfp_prog, meta, size); 1920 return mem_ldx_skb(nfp_prog, meta, size);
1853 } 1921 }
1854 1922
1855 if (meta->ptr.type == PTR_TO_PACKET) 1923 if (meta->ptr.type == PTR_TO_PACKET) {
1856 return mem_ldx_data(nfp_prog, meta, size); 1924 if (meta->pkt_cache.range_end) {
1925 if (meta->pkt_cache.do_init)
1926 mem_ldx_data_init_pktcache(nfp_prog, meta);
1927
1928 return mem_ldx_data_from_pktcache(nfp_prog, meta, size);
1929 } else {
1930 return mem_ldx_data(nfp_prog, meta, size);
1931 }
1932 }
1857 1933
1858 if (meta->ptr.type == PTR_TO_STACK) 1934 if (meta->ptr.type == PTR_TO_STACK)
1859 return mem_ldx_stack(nfp_prog, meta, size, 1935 return mem_ldx_stack(nfp_prog, meta, size,
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index 054df3dc0698..861211e27ea6 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -199,6 +199,10 @@ typedef int (*instr_cb_t)(struct nfp_prog *, struct nfp_insn_meta *);
199 * @ldst_gather_len: memcpy length gathered from load/store sequence 199 * @ldst_gather_len: memcpy length gathered from load/store sequence
200 * @paired_st: the paired store insn at the head of the sequence 200 * @paired_st: the paired store insn at the head of the sequence
201 * @ptr_not_const: pointer is not always constant 201 * @ptr_not_const: pointer is not always constant
202 * @pkt_cache: packet data cache information
203 * @pkt_cache.range_start: start offset for associated packet data cache
204 * @pkt_cache.range_end: end offset for associated packet data cache
205 * @pkt_cache.do_init: this read needs to initialize packet data cache
202 * @jmp_dst: destination info for jump instructions 206 * @jmp_dst: destination info for jump instructions
203 * @func_id: function id for call instructions 207 * @func_id: function id for call instructions
204 * @arg1: arg1 for call instructions 208 * @arg1: arg1 for call instructions
@@ -219,6 +223,11 @@ struct nfp_insn_meta {
219 struct bpf_insn *paired_st; 223 struct bpf_insn *paired_st;
220 s16 ldst_gather_len; 224 s16 ldst_gather_len;
221 bool ptr_not_const; 225 bool ptr_not_const;
226 struct {
227 s16 range_start;
228 s16 range_end;
229 bool do_init;
230 } pkt_cache;
222 }; 231 };
223 struct nfp_insn_meta *jmp_dst; 232 struct nfp_insn_meta *jmp_dst;
224 struct { 233 struct {
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_asm.h b/drivers/net/ethernet/netronome/nfp/nfp_asm.h
index 5f9291db98e0..150d28f9cd52 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_asm.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_asm.h
@@ -39,6 +39,7 @@
39#include <linux/types.h> 39#include <linux/types.h>
40 40
41#define REG_NONE 0 41#define REG_NONE 0
42#define REG_WIDTH 4
42 43
43#define RE_REG_NO_DST 0x020 44#define RE_REG_NO_DST 0x020
44#define RE_REG_IMM 0x020 45#define RE_REG_IMM 0x020