From: Jakub Kicinski <jakub.kicinski@netronome.com>
To: netdev@vger.kernel.org
Cc: oss-drivers@netronome.com, Jakub Kicinski <jakub.kicinski@netronome.com>
Subject: [PATCH net-next 4/9] nfp: bpf: add stack read support
Date: Mon, 23 Oct 2017 11:58:09 -0700 [thread overview]
Message-ID: <20171023185814.4797-5-jakub.kicinski@netronome.com> (raw)
In-Reply-To: <20171023185814.4797-1-jakub.kicinski@netronome.com>
Add simple stack read support, similar to write in every aspect,
but data flowing the other way. Note that unlike write which can
be done in smaller than word quantities, if registers are loaded
with less-than-word of stack contents - the values have to be
zero extended.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
---
drivers/net/ethernet/netronome/nfp/bpf/jit.c | 81 ++++++++++++++++++++++++++--
1 file changed, 76 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
index d2a3e9065dbe..094acea35326 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
@@ -644,11 +644,65 @@ data_st_host_order(struct nfp_prog *nfp_prog, u8 dst_gpr, swreg offset,
typedef int
(*lmem_step)(struct nfp_prog *nfp_prog, u8 gpr, u8 gpr_byte, s32 off,
- unsigned int size);
+ unsigned int size, bool new_gpr);
+
+static int
+wrp_lmem_load(struct nfp_prog *nfp_prog, u8 dst, u8 dst_byte, s32 off,
+ unsigned int size, bool new_gpr)
+{
+ u32 idx, src_byte;
+ enum shf_sc sc;
+ swreg reg;
+ int shf;
+ u8 mask;
+
+ if (WARN_ON_ONCE(dst_byte + size > 4 || off % 4 + size > 4))
+ return -EOPNOTSUPP;
+
+ idx = off / 4;
+
+ /* Move the entire word */
+ if (size == 4) {
+ wrp_mov(nfp_prog, reg_both(dst), reg_lm(0, idx));
+ return 0;
+ }
+
+ src_byte = off % 4;
+
+ mask = (1 << size) - 1;
+ mask <<= dst_byte;
+
+ if (WARN_ON_ONCE(mask > 0xf))
+ return -EOPNOTSUPP;
+
+ shf = abs(src_byte - dst_byte) * 8;
+ if (src_byte == dst_byte) {
+ sc = SHF_SC_NONE;
+ } else if (src_byte < dst_byte) {
+ shf = 32 - shf;
+ sc = SHF_SC_L_SHF;
+ } else {
+ sc = SHF_SC_R_SHF;
+ }
+
+ /* ld_field can address fewer indexes, if offset too large do RMW.
+ * Because we RMV twice we waste 2 cycles on unaligned 8 byte writes.
+ */
+ if (idx <= RE_REG_LM_IDX_MAX) {
+ reg = reg_lm(0, idx);
+ } else {
+ reg = imm_a(nfp_prog);
+ wrp_mov(nfp_prog, reg, reg_lm(0, idx));
+ }
+
+ emit_ld_field_any(nfp_prog, reg_both(dst), mask, reg, sc, shf, new_gpr);
+
+ return 0;
+}
static int
wrp_lmem_store(struct nfp_prog *nfp_prog, u8 src, u8 src_byte, s32 off,
- unsigned int size)
+ unsigned int size, bool new_gpr)
{
u32 idx, dst_byte;
enum shf_sc sc;
@@ -705,12 +759,16 @@ wrp_lmem_store(struct nfp_prog *nfp_prog, u8 src, u8 src_byte, s32 off,
static int
mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
- unsigned int size, u8 gpr, lmem_step step)
+ unsigned int size, u8 gpr, bool clr_gpr, lmem_step step)
{
s32 off = nfp_prog->stack_depth + meta->insn.off;
+ u8 prev_gpr = 255;
u32 gpr_byte = 0;
int ret;
+ if (clr_gpr && size < 8)
+ wrp_immed(nfp_prog, reg_both(gpr + 1), 0);
+
while (size) {
u32 slice_end;
u8 slice_size;
@@ -719,10 +777,12 @@ mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
slice_end = min(off + slice_size, round_up(off + 1, 4));
slice_size = slice_end - off;
- ret = step(nfp_prog, gpr, gpr_byte, off, slice_size);
+ ret = step(nfp_prog, gpr, gpr_byte, off, slice_size,
+ gpr != prev_gpr);
if (ret)
return ret;
+ prev_gpr = gpr;
gpr_byte += slice_size;
if (gpr_byte >= 4) {
gpr_byte -= 4;
@@ -1232,6 +1292,14 @@ static int data_ind_ld4(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
meta->insn.src_reg * 2, 4);
}
+static int
+mem_ldx_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
+ unsigned int size)
+{
+ return mem_op_stack(nfp_prog, meta, size, meta->insn.dst_reg * 2, true,
+ wrp_lmem_load);
+}
+
static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
u8 size)
{
@@ -1315,6 +1383,9 @@ mem_ldx(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
if (meta->ptr.type == PTR_TO_PACKET)
return mem_ldx_data(nfp_prog, meta, size);
+ if (meta->ptr.type == PTR_TO_STACK)
+ return mem_ldx_stack(nfp_prog, meta, size);
+
return -EOPNOTSUPP;
}
@@ -1396,7 +1467,7 @@ static int
mem_stx_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
unsigned int size)
{
- return mem_op_stack(nfp_prog, meta, size, meta->insn.src_reg * 2,
+ return mem_op_stack(nfp_prog, meta, size, meta->insn.src_reg * 2, false,
wrp_lmem_store);
}
--
2.14.1
next prev parent reply other threads:[~2017-10-23 18:58 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-23 18:58 [PATCH net-next 0/9] nfp: bpf: stack support in offload Jakub Kicinski
2017-10-23 18:58 ` [PATCH net-next 1/9] nfp: bpf: add helper for emitting nops Jakub Kicinski
2017-10-23 18:58 ` [PATCH net-next 2/9] nfp: bpf: refactor nfp_bpf_check_ptr() Jakub Kicinski
2017-10-23 18:58 ` [PATCH net-next 3/9] nfp: bpf: add stack write support Jakub Kicinski
2017-10-23 18:58 ` Jakub Kicinski [this message]
2017-10-23 18:58 ` [PATCH net-next 5/9] nfp: bpf: optimize the RMW for stack accesses Jakub Kicinski
2017-10-23 18:58 ` [PATCH net-next 6/9] nfp: bpf: allow stack accesses via modified stack registers Jakub Kicinski
2017-10-23 18:58 ` [PATCH net-next 7/9] nfp: bpf: support accessing the stack beyond 64 bytes Jakub Kicinski
2017-10-23 18:58 ` [PATCH net-next 8/9] nfp: bpf: support stack accesses via non-constant pointers Jakub Kicinski
2017-10-23 18:58 ` [PATCH net-next 9/9] nfp: bpf: optimize mov64 a little Jakub Kicinski
2017-10-24 8:39 ` [PATCH net-next 0/9] nfp: bpf: stack support in offload David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171023185814.4797-5-jakub.kicinski@netronome.com \
--to=jakub.kicinski@netronome.com \
--cc=netdev@vger.kernel.org \
--cc=oss-drivers@netronome.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox