[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJ+HfNhOp_Rbcqer0K=mZ8h+uswYSv4hSa3wCTdjjxH26HUTCw@mail.gmail.com>
Date: Wed, 4 Mar 2020 06:59:17 +0100
From: Björn Töpel <bjorn.topel@...il.com>
To: Luke Nelson <lukenels@...washington.edu>
Cc: bpf <bpf@...r.kernel.org>, Luke Nelson <luke.r.nels@...il.com>,
Jonathan Corbet <corbet@....net>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Martin KaFai Lau <kafai@...com>,
Song Liu <songliubraving@...com>, Yonghong Song <yhs@...com>,
Andrii Nakryiko <andriin@...com>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Paul Walmsley <paul.walmsley@...ive.com>,
Palmer Dabbelt <palmer@...belt.com>,
Albert Ou <aou@...s.berkeley.edu>, Xi Wang <xi.wang@...il.com>,
Mauro Carvalho Chehab <mchehab+samsung@...nel.org>,
Stephen Hemminger <stephen@...workplumber.org>,
Rob Herring <robh@...nel.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Jonathan Cameron <Jonathan.Cameron@...wei.com>,
Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
linux-doc@...r.kernel.org, LKML <linux-kernel@...r.kernel.org>,
Netdev <netdev@...r.kernel.org>, linux-riscv@...ts.infradead.org
Subject: Re: [PATCH bpf-next v4 2/4] riscv, bpf: add RV32G eBPF JIT
On Wed, 4 Mar 2020 at 03:32, Luke Nelson <lukenels@...washington.edu> wrote:
>
[...]
>
> > > + case BPF_LSH:
> > > + if (imm >= 32) {
> > > + emit(rv_slli(hi(rd), lo(rd), imm - 32), ctx);
> > > + emit(rv_addi(lo(rd), RV_REG_ZERO, 0), ctx);
> > > + } else if (imm == 0) {
> > > + /* nop */
> >
> > Can we get rid of this, and just do if/else if?
>
> imm == 0 has been a tricky case for 32-bit JITs; see 6fa632e719ee
> ("bpf, x32: Fix bug with ALU64 {LSH, RSH, ARSH} BPF_K shift by 0").
> We wanted to make the imm == 0 case explicit and help future readers
> see that this case is handled correctly here.
>
> We could do the following if we really wanted to get rid of the
> check:
>
> if (imm >= 32) {
> ...
> } else if (imm != 0) {
> ...
> }
> /* Do nothing for imm == 0. */
>
> Though it's unclear if this is easier to read.
>
Thanks for clearing that up. *I* prefer the latter, but that's really
up to you! Keep the current one, if you prefer that! :-)
> > > + case BPF_ARSH:
> > > + if (is_12b_int(imm)) {
> > > + emit(rv_srai(lo(rd), lo(rd), imm), ctx);
> > > + } else {
> > > + emit_imm(RV_REG_T0, imm, ctx);
> > > + emit(rv_sra(lo(rd), lo(rd), RV_REG_T0), ctx);
> > > + }
> > > + break;
> >
> > Again nit; I like "early exit" code if possible. Instead of:
> >
> > if (bleh) {
> > foo();
> > } else {
> > bar();
> > }
> >
> > do:
> >
> > if (bleh) {
> > foo()
> > return/break;
> > }
> > bar();
> >
> > I find the latter easier to read -- but really a nit, and a matter of
> > style. There are number of places where that could be applied in the
> > file.
>
> I like "early exit" code, too, and agree that it's easier to read
> in general, especially when handling error conditions.
>
> But here we wanted to make it explicit that both branches are
> emitting equivalent instruction sequences (under different paths).
> Structured control flow seems a better fit for this particular
> context.
>
Ok!
> > At this point of the series, let's introduce the shared code .c-file
> > containing implementation for bpf_int_jit_compile() (with build_body
> > part of that)and bpf_jit_needs_zext(). That will make it easier to
> > catch bugs in both JITs and to avoid code duplication! Also, when
> > adding the stronger invariant suggested by Palmer [1], we only need to
> > do it in one place.
> >
> > The pull out refactoring can be a separate commit.
>
> I think the idea of deduplicating bpf_int_jit_compile is good and
> will lead to more maintainable JITs. How does the following proposal
> for v5 sound?
>
> In patch 1 of this series:
>
> - Factor structs and common helpers to bpf_jit.h (just like v4).
>
> - Factor out bpf_int_jit_compile(), bpf_jit_needs_zext(), and
> build_body() to a new file bpf_jit_core.c and tweak the code as in v4.
>
> - Rename emit_insn() and build_{prologue,epilogue}() to bpf_jit_emit_insn()
> and bpf_jit_build_{prologue,epilogue}, since these functions are
> now extern rather than static.
>
> - Rename bpf_jit_comp.c to bpf_jit_comp64.c to be more explicit
> about its contents (as the next patch will add bpf_jit_comp32.c).
>
> Then patch 2 can reuse the new header and won't need to define its
> own bpf_int_jit_compile() etc.
>
I like that, but keep the first patch as a refactoring patch only, and
then in a *new* patch 2 you add the rv32 specific code (sltu and
pseudo instructions + the xlen preprocessor check + copyright-things
;-)). Patch 3 will be the old patch 2. Wdyt?
Thanks for working on this!
Björn
> Thanks!
>
> Luke
Powered by blists - more mailing lists