[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20180601092646.15353.28269.stgit@john-Precision-Tower-5810>
Date: Fri, 01 Jun 2018 02:32:18 -0700
From: John Fastabend <john.fastabend@...il.com>
To: alexei.starovoitov@...il.com, daniel@...earbox.net,
davem@...emloft.net
Cc: netdev@...r.kernel.org
Subject: [RFC PATCH 00/16] bpf, bounded loop support work in progress
This series is an early preview of ongoing work to support loops
inside BPF verifier. The code is rough in spots (more rough the
further you get into the series) but we have some signs of life!
The following code runs and is verified,
SEC("classifier_tc_loop1")
int _tc_loop(struct __sk_buff *ctx)
{
void *data = (void *)(unsigned long)ctx->data;
void *data_end = (void *)(unsigned long)ctx->data_end;
__u8 i = 0, j = 0, k = 0, *p;
if (data + 2 > data_end)
return TC_ACT_OK;
p = data;
j = p[0];
if (data + 101 > data_end)
return TC_ACT_OK;
if (j < 100)
return TC_ACT_OK;
#pragma nounroll
while (i < j) {
k += p[i];
i++;
}
ctx->mark = k;
return TC_ACT_OK;
}
perhaps even more important many invalid loops are caught and
rejected. There are still a few cases that need to be handled
but largely things are working. And lots of code cleanup,
polishing and improvements sill needed but worth sharing
I think. Even if no one reads the code line by line the commit
messages have the description.
The series is broken into three parts.
Part1: Build the basic infrastruce. Basic Blocks, CFG and DOM are
built. (work done by Jiong).
Part2: Verify loops are bounded and encourage the state pruning
logic to prune as many states as possible.
Part3: Tests. Largely tbd at this point although I've been
doing lots of manual poking around with good/bad/ugly C programs.
Some high level details around design decisions for each part but
please see patch descriptions for more.
First Part1 Jiong chose to use Tarjan algorithm to build DOM.
(We also have an iterative solution if that is prefered but in
theory at least Tarjan has better running time.) Also we have
calculated the pdom as well but it is currently unused.
For all Part2 gory details please see patch,
"bpf: verifier, add initial support to allow bounded loops"
The high level design is as follows,
i. Use DOM to find loops
ii. Find induction variables in loop
iii. Verify termination by comparing induction variable (inc/dec)
against the JMP op. Propagate min/max values into insn aux
data.
iv. At do_check time ensure induction variable is bounded as
required to ensure loop termination. These are a form of
restriction on valid values for the registers.
v. Encourage state pruning by using known bounds from
previous induction step. e.g. if a scalar increments from
0 to 100 we know min/max values that are vali for every
iteration.
vi. Loop state is usually pruned early but if not we can simply
run the loop costing verifier complexity.
There is still lots of work to finish up all the pieces but we wanted
to share the current design.
Thanks,
John
---
Jiong Wang (11):
bpf: cfg: partition basic blocks for each subprog
bpf: cfg: add edges between basic blocks to form CFG
bpf: cfg: build domination tree using Tarjan algorithm
bpf: cfg: detect loop use domination information
bpf: cfg: detect unreachable basic blocks
bpf: cfg: move find_subprog/add_subprog to cfg.c
bpf: cfg: build call graph and detect unreachable/recursive call
bpf: cfg: remove push_insn and check_cfg
bpf: cfg: reduce k*alloc/free call by using memory pool for allocating nodes
bpf: cfg: reduce memory usage by using singly list + compat pointer
bpf: cfg: detect irreducible loop using Eric Stoltz algorithm
John Fastabend (5):
bpf: cfg: pretty print CFG and DOM
bpf: verifier, can ptr range be calculated with scalar ALU op
bpf: verifier, add initial support to allow bounded loops
bpf: verifier, simple loop examples
bpf: tools: dbg patch to turn on debugging and add primitive examples
include/linux/bpf_verifier.h | 28
kernel/bpf/Makefile | 2
kernel/bpf/cfg.c | 2060 ++++++++++++++++++++++++
kernel/bpf/cfg.h | 56 +
kernel/bpf/verifier.c | 499 +++---
samples/bpf/xdp2skb_meta_kern.c | 57 +
tools/lib/bpf/bpf.c | 2
tools/lib/bpf/libbpf.c | 7
tools/testing/selftests/bpf/Makefile | 5
tools/testing/selftests/bpf/test_bad_loop1.c | 47 +
tools/testing/selftests/bpf/test_bad_loop2.c | 45 +
tools/testing/selftests/bpf/test_bad_loop3.c | 47 +
tools/testing/selftests/bpf/test_basic_loop1.c | 44 +
tools/testing/selftests/bpf/test_basic_loop2.c | 48 +
tools/testing/selftests/bpf/test_basic_loop3.c | 51 +
15 files changed, 2711 insertions(+), 287 deletions(-)
create mode 100644 kernel/bpf/cfg.c
create mode 100644 kernel/bpf/cfg.h
create mode 100644 tools/testing/selftests/bpf/test_bad_loop1.c
create mode 100644 tools/testing/selftests/bpf/test_bad_loop2.c
create mode 100644 tools/testing/selftests/bpf/test_bad_loop3.c
create mode 100644 tools/testing/selftests/bpf/test_basic_loop1.c
create mode 100644 tools/testing/selftests/bpf/test_basic_loop2.c
create mode 100644 tools/testing/selftests/bpf/test_basic_loop3.c
--
Signature
Powered by blists - more mailing lists