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 5/9] nfp: bpf: optimize the RMW for stack accesses
Date: Mon, 23 Oct 2017 11:58:10 -0700 [thread overview]
Message-ID: <20171023185814.4797-6-jakub.kicinski@netronome.com> (raw)
In-Reply-To: <20171023185814.4797-1-jakub.kicinski@netronome.com>
When we are performing unaligned stack accesses in the 32-64B window
we have to do a read-modify-write cycle. E.g. for reading 8 bytes
from address 17:
0: tmp = stack[16]
1: gprLo = tmp >> 8
2: tmp = stack[20]
3: gprLo |= tmp << 24
4: tmp = stack[20]
5: gprHi = tmp >> 8
6: tmp = stack[24]
7: gprHi |= tmp << 24
The load on line 4 is unnecessary, because tmp already contains data
from stack[20].
For write we can optimize both loads and writebacks away.
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 | 33 +++++++++++++++++++++-------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
index 094acea35326..6730690cf9d8 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c
@@ -644,11 +644,11 @@ 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, bool new_gpr);
+ unsigned int size, bool first, bool new_gpr, bool last);
static int
wrp_lmem_load(struct nfp_prog *nfp_prog, u8 dst, u8 dst_byte, s32 off,
- unsigned int size, bool new_gpr)
+ unsigned int size, bool first, bool new_gpr, bool last)
{
u32 idx, src_byte;
enum shf_sc sc;
@@ -692,7 +692,13 @@ wrp_lmem_load(struct nfp_prog *nfp_prog, u8 dst, u8 dst_byte, s32 off,
reg = reg_lm(0, idx);
} else {
reg = imm_a(nfp_prog);
- wrp_mov(nfp_prog, reg, reg_lm(0, idx));
+ /* If it's not the first part of the load and we start a new GPR
+ * that means we are loading a second part of the LMEM word into
+ * a new GPR. IOW we've already looked that LMEM word and
+ * therefore it has been loaded into imm_a().
+ */
+ if (first || !new_gpr)
+ wrp_mov(nfp_prog, reg, reg_lm(0, idx));
}
emit_ld_field_any(nfp_prog, reg_both(dst), mask, reg, sc, shf, new_gpr);
@@ -702,7 +708,7 @@ wrp_lmem_load(struct nfp_prog *nfp_prog, u8 dst, u8 dst_byte, s32 off,
static int
wrp_lmem_store(struct nfp_prog *nfp_prog, u8 src, u8 src_byte, s32 off,
- unsigned int size, bool new_gpr)
+ unsigned int size, bool first, bool new_gpr, bool last)
{
u32 idx, dst_byte;
enum shf_sc sc;
@@ -746,13 +752,19 @@ wrp_lmem_store(struct nfp_prog *nfp_prog, u8 src, u8 src_byte, s32 off,
reg = reg_lm(0, idx);
} else {
reg = imm_a(nfp_prog);
- wrp_mov(nfp_prog, reg, reg_lm(0, idx));
+ /* Only first and last LMEM locations are going to need RMW,
+ * the middle location will be overwritten fully.
+ */
+ if (first || last)
+ wrp_mov(nfp_prog, reg, reg_lm(0, idx));
}
emit_ld_field(nfp_prog, reg, mask, reg_b(src), sc, shf);
- if (idx > RE_REG_LM_IDX_MAX)
- wrp_mov(nfp_prog, reg_lm(0, idx), reg);
+ if (new_gpr || last) {
+ if (idx > RE_REG_LM_IDX_MAX)
+ wrp_mov(nfp_prog, reg_lm(0, idx), reg);
+ }
return 0;
}
@@ -762,6 +774,7 @@ mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
unsigned int size, u8 gpr, bool clr_gpr, lmem_step step)
{
s32 off = nfp_prog->stack_depth + meta->insn.off;
+ bool first = true, last;
u8 prev_gpr = 255;
u32 gpr_byte = 0;
int ret;
@@ -777,12 +790,16 @@ 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;
+ last = slice_size == size;
+
ret = step(nfp_prog, gpr, gpr_byte, off, slice_size,
- gpr != prev_gpr);
+ first, gpr != prev_gpr, last);
if (ret)
return ret;
prev_gpr = gpr;
+ first = false;
+
gpr_byte += slice_size;
if (gpr_byte >= 4) {
gpr_byte -= 4;
--
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 ` [PATCH net-next 4/9] nfp: bpf: add stack read support Jakub Kicinski
2017-10-23 18:58 ` Jakub Kicinski [this message]
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-6-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