bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next v2 0/5] xdp: Support multiple programs on a single interface through chain calls
@ 2019-10-04 17:22 Toke Høiland-Jørgensen
  2019-10-04 17:22 ` [PATCH bpf-next v2 1/5] bpf: Support injecting chain calls into BPF programs on load Toke Høiland-Jørgensen
                   ` (4 more replies)
  0 siblings, 5 replies; 21+ messages in thread
From: Toke Høiland-Jørgensen @ 2019-10-04 17:22 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: Alexei Starovoitov, Martin KaFai Lau, Song Liu, Yonghong Song,
	Marek Majkowski, Lorenz Bauer, Alan Maguire,
	Jesper Dangaard Brouer, David Miller, netdev, bpf

This series adds support for executing multiple XDP programs on a single
interface in sequence, through the use of chain calls, as discussed at the Linux
Plumbers Conference last month:

https://linuxplumbersconf.org/event/4/contributions/460/

# HIGH-LEVEL IDEA

Since the response to the previous iteration was pretty unanimous that this
should not be XDP-specific, this version takes a different approach: We add the
ability to inject chain call programs into the eBPF execution core itself. This
also turns out to be simpler, so that's good :)

The way this new approach works is the bpf() syscall gets a couple of new
commands which takes a pair of BPF program fds and a return code. It will then
attach the second program to the first one in a structured keyed by return code.
When a program chain is thus established, the former program will tail call to
the latter at the end of its execution.

The actual tail calling is achieved by having the verifier inject instructions
into the program that performs the chain call lookup and tail call before each
BPF_EXIT instruction. Since this rewriting has to be performed at program load
time, a new flag has to be set to trigger the rewriting. Only programs loaded
with this flag set can have other programs attached to them for chain calls.

Ideally, it shouldn't be necessary to set the flag on program load time,
but rather inject the calls when a chain call program is first loaded.
However, rewriting the program reallocates the bpf_prog struct, which is
obviously not possible after the program has been attached to something.

One way around this could be a sysctl to force the flag one (for enforcing
system-wide support). Another could be to have the chain call support
itself built into the interpreter and JIT, which could conceivably be
re-run each time we attach a new chain call program. This would also allow
the JIT to inject direct calls to the next program instead of using the
tail call infrastructure, which presumably would be a performance win. The
drawback is, of course, that it would require modifying all the JITs.


# PERFORMANCE

I performed a simple performance test to get an initial feel for the overhead of
the chain call mechanism. This test consists of running only two programs in
sequence: One that returns XDP_PASS and another that returns XDP_DROP. I then
measure the drop PPS performance and compare it to a baseline of just a single
program that only returns XDP_DROP.

For comparison, a test case that uses regular eBPF tail calls to sequence two
programs together is also included. I did not re-run the baseline tests from
before, so the two top values are the same

| Test case                        | Perf      | Overhead |
|----------------------------------+-----------+----------|
| Before patch (XDP DROP program)  | 31.0 Mpps |          |
| XDP tail call                    | 26.6 Mpps | 5.3 ns   |
|----------------------------------+-----------+----------|
| After patch (XDP DROP program)   | 31.2 Mpps |          |
| XDP chain call (wildcard return) | 26.8 Mpps | 5.3 ns   |
| XDP chain call (XDP_PASS return) | 27.2 Mpps | 4.7 ns   |

The difference between the wildcard and XDP_PASS cases for chain calls, is that
using the wildcard mode needs two tail call attempts where the first one fails,
(see the injected BPF code in patch 1) while XDP_PASS matches on the first tail
call.

# PATCH SET STRUCTURE
This series is structured as follows:

- Patch 1: Adds the code that injects the instructions into the programs
- Patch 2: Adds the new commands added to the bpf() syscall
- Patch 3-4: Tools/ update and libbpf syscall wrappers
- Patch 5: Selftest  with example user space code (a bit hacky still)

The whole series is also available in my git repo on kernel.org:
https://git.kernel.org/pub/scm/linux/kernel/git/toke/linux.git/log/?h=xdp-multiprog-02

Changelog:

v2:
  - Completely new approach that integrates chain calls into the core eBPF
    runtime instead of doing the map XDP-specific thing with a new map from v1.

---

Alan Maguire (1):
      bpf: Add support for setting chain call sequence for programs

Toke Høiland-Jørgensen (4):
      bpf: Support injecting chain calls into BPF programs on load
      tools: Update bpf.h header for program chain calls
      libbpf: Add syscall wrappers for BPF_PROG_CHAIN_* commands
      selftests: Add tests for XDP chain calls


 include/linux/bpf.h                           |    2 
 include/uapi/linux/bpf.h                      |   16 +
 kernel/bpf/core.c                             |   10 +
 kernel/bpf/syscall.c                          |   81 ++++++
 kernel/bpf/verifier.c                         |   76 ++++++
 tools/include/uapi/linux/bpf.h                |   16 +
 tools/lib/bpf/bpf.c                           |   34 +++
 tools/lib/bpf/bpf.h                           |    4 
 tools/lib/bpf/libbpf.map                      |    3 
 tools/testing/selftests/bpf/.gitignore        |    1 
 tools/testing/selftests/bpf/Makefile          |    3 
 tools/testing/selftests/bpf/progs/xdp_dummy.c |    6 
 tools/testing/selftests/bpf/test_xdp_chain.sh |   77 ++++++
 tools/testing/selftests/bpf/xdp_chain.c       |  313 +++++++++++++++++++++++++
 14 files changed, 640 insertions(+), 2 deletions(-)
 create mode 100755 tools/testing/selftests/bpf/test_xdp_chain.sh
 create mode 100644 tools/testing/selftests/bpf/xdp_chain.c


^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2019-10-08  9:02 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-04 17:22 [PATCH bpf-next v2 0/5] xdp: Support multiple programs on a single interface through chain calls Toke Høiland-Jørgensen
2019-10-04 17:22 ` [PATCH bpf-next v2 1/5] bpf: Support injecting chain calls into BPF programs on load Toke Høiland-Jørgensen
2019-10-04 20:51   ` kbuild test robot
2019-10-04 21:12   ` kbuild test robot
2019-10-04 23:17   ` Jakub Kicinski
2019-10-05 10:29     ` Toke Høiland-Jørgensen
2019-10-06  3:39       ` Jakub Kicinski
2019-10-06 15:52         ` Toke Høiland-Jørgensen
2019-10-05 10:32     ` Toke Høiland-Jørgensen
2019-10-07  0:27   ` Alexei Starovoitov
2019-10-07 10:11     ` Toke Høiland-Jørgensen
2019-10-07 20:22       ` Daniel Borkmann
2019-10-08  9:00         ` Toke Høiland-Jørgensen
2019-10-07 20:45       ` Alexei Starovoitov
2019-10-08  9:02         ` Toke Høiland-Jørgensen
2019-10-04 17:22 ` [PATCH bpf-next v2 2/5] bpf: Add support for setting chain call sequence for programs Toke Høiland-Jørgensen
2019-10-04 23:18   ` Jakub Kicinski
2019-10-05 10:30     ` Toke Høiland-Jørgensen
2019-10-04 17:22 ` [PATCH bpf-next v2 3/5] tools: Update bpf.h header for program chain calls Toke Høiland-Jørgensen
2019-10-04 17:22 ` [PATCH bpf-next v2 4/5] libbpf: Add syscall wrappers for BPF_PROG_CHAIN_* commands Toke Høiland-Jørgensen
2019-10-04 17:22 ` [PATCH bpf-next v2 5/5] selftests: Add tests for XDP chain calls Toke Høiland-Jørgensen

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).