netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	Alexei Starovoitov <ast@kernel.org>
Subject: Re: eBPF - little-endian load instructions?
Date: Wed, 12 Apr 2017 21:38:39 +0200	[thread overview]
Message-ID: <1492025919.2855.20.camel@sipsolutions.net> (raw)
In-Reply-To: <20170412165804.GA75807@ast-mbp.thefacebook.com> (sfid-20170412_185811_142047_71F34A05)

On Wed, 2017-04-12 at 09:58 -0700, Alexei Starovoitov wrote:
> 
> > Are these hooked up to llvm intrinsics or so? If not, can I do that
> > through some kind of inline asm statement?
> 
> llvm doesn't support bpf inline asm yet.

Ok.

> > In the samples, I only see people doing
> > 
> > #define _htonl __builtin_bswap32
> > 
> > but I'm not even completely convinced that's correct, since it
> > assumes
> > a little-endian host?
> 
> oh well, time to face the music.
> 
> In llvm backend I did:
> // bswap16, bswap32, bswap64
> class BSWAP<bits<32> SizeOp, string OpcodeStr, list<dag> Pattern>
> ...
>   let op = 0xd;     // BPF_END
>   let BPFSrc = 1;   // BPF_TO_BE (TODO: use BPF_TO_LE for big-endian
> target)
>   let BPFClass = 4; // BPF_ALU
> 
> so __builtin_bswap32() is not a normal bswap. It's only doing bswap
> if the compiled program running on little endian arch.
> The plan was to fix it up for -march=bpfeb target (hence the comment
> above), but it turned out that such __builtin_bswap32 matches
> perfectly to _htonl() semantics, so I left it as-is even for
> -march=bpfeb.
> 
> On little endian:
> ld_abs_W = *(u32*) + real bswap32
> __builtin_bswap32() == bpf_to_be insn = real bswap32
> 
> On big endian:
> ld_abs_W = *(u32*)
> __builtin_bswap32() == bpf_to_be insn = nop
> 
> so in samples/bpf/*.c:
> load_word() + _htonl()(__builtin_bswap32) has the same semantics
> for both little and big endian archs, hence all networking sample
> code in
> samples/bpf/*_kern.c works fine.
> 
> imo the whole thing is crazy ugly. llvm doesn't have 'htonl'
> equivalent builtin, so builtin_bswap was the closest I could use to
> generate bpf_to_[bl]e insn.
> 

Awkward. How can this even be fixed without breaking all the existing
code?

I assume the BPF machine is intended to be endian-independent, which is
really the problem - normally you'd either
	#define be32_to_cpu bswap32
or
	#define be32_to_cpu(x) (x)
depending on the build architecture, I guess.

> To solve this properly I think we need two things:
> . proper bswap32 insn in BPF

Not sure you need that - what for? Normally this doesn't really get used directly, I think? At least I don't really see a good reason for using it directly. And reimplementing that now would break existing C code.

> . extend llvm with bpf_to_be/le builtins
> Both are not trivial amount of work.

It seems that perhaps the best way to solve this would be to actually
implement inline assembly. Then, existing C code that relies on the
(broken) bswap32 semantics can actually continue to work, if that
built-in isn't touched, and one could then implement the various
cpu_to_be32 and friends as inline assembly?

That would make it invisible to the LLVM optimiser though, so perhaps
not the best idea either.

johannes

  reply	other threads:[~2017-04-12 19:38 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-11 10:38 eBPF - little-endian load instructions? Johannes Berg
2017-04-11 11:06 ` Daniel Borkmann
2017-04-11 11:15   ` Johannes Berg
2017-04-11 11:22     ` Daniel Borkmann
2017-04-11 11:26       ` Johannes Berg
2017-04-12 13:02   ` Johannes Berg
2017-04-12 16:58     ` Alexei Starovoitov
2017-04-12 19:38       ` Johannes Berg [this message]
2017-04-13  3:08         ` Alexei Starovoitov
2017-04-13  5:58           ` Johannes Berg
2017-04-14 18:42             ` Alexei Starovoitov
2017-04-15  7:06               ` Johannes Berg

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=1492025919.2855.20.camel@sipsolutions.net \
    --to=johannes@sipsolutions.net \
    --cc=alexei.starovoitov@gmail.com \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=netdev@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).