[PATCH bpf-next v2 0/5] xdp: Support multiple programs on a single interface through chain calls

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux