netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Maxim Mikityanskiy <maximmi@nvidia.com>
To: Yonghong Song <yhs@fb.com>
Cc: "Toke Høiland-Jørgensen" <toke@redhat.com>,
	"Lorenz Bauer" <lmb@cloudflare.com>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"Andrii Nakryiko" <andrii@kernel.org>,
	"Martin KaFai Lau" <kafai@fb.com>,
	"Song Liu" <songliubraving@fb.com>,
	"John Fastabend" <john.fastabend@gmail.com>,
	"KP Singh" <kpsingh@kernel.org>,
	"Eric Dumazet" <edumazet@google.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Hideaki YOSHIFUJI" <yoshfuji@linux-ipv6.org>,
	"David Ahern" <dsahern@kernel.org>,
	"Jesper Dangaard Brouer" <hawk@kernel.org>,
	"Nathan Chancellor" <nathan@kernel.org>,
	"Nick Desaulniers" <ndesaulniers@google.com>,
	"Brendan Jackman" <jackmanb@google.com>,
	"Florent Revest" <revest@chromium.org>,
	"Joe Stringer" <joe@cilium.io>,
	"Tariq Toukan" <tariqt@nvidia.com>,
	Networking <netdev@vger.kernel.org>, bpf <bpf@vger.kernel.org>,
	clang-built-linux@googlegroups.com
Subject: Re: [PATCH bpf-next 09/10] bpf: Add a helper to issue timestamp cookies in XDP
Date: Fri, 26 Nov 2021 18:50:10 +0200	[thread overview]
Message-ID: <cbd2e655-8113-e719-4b9d-b3987c398b04@nvidia.com> (raw)
In-Reply-To: <f08fa9aa-8b0d-8217-1823-2830b2b2587c@fb.com>

On 2021-11-26 07:43, Yonghong Song wrote:
> 
> 
> On 11/25/21 6:34 AM, Maxim Mikityanskiy wrote:
>> On 2021-11-09 09:11, Yonghong Song wrote:
>>>
>>>
>>> On 11/3/21 7:02 AM, Maxim Mikityanskiy wrote:
>>>> On 2021-11-03 04:10, Yonghong Song wrote:
>>>>>
>>>>>
>>>>> On 11/1/21 4:14 AM, Maxim Mikityanskiy wrote:
>>>>>> On 2021-10-20 19:16, Toke Høiland-Jørgensen wrote:
>>>>>>> Lorenz Bauer <lmb@cloudflare.com> writes:
>>>>>>>
>>>>>>>>> +bool cookie_init_timestamp_raw(struct tcphdr *th, __be32 
>>>>>>>>> *tsval, __be32 *tsecr)
>>>>>>>>
>>>>>>>> I'm probably missing context, Is there something in this 
>>>>>>>> function that
>>>>>>>> means you can't implement it in BPF?
>>>>>>>
>>>>>>> I was about to reply with some other comments but upon closer 
>>>>>>> inspection
>>>>>>> I ended up at the same conclusion: this helper doesn't seem to be 
>>>>>>> needed
>>>>>>> at all?
>>>>>>
>>>>>> After trying to put this code into BPF (replacing the underlying 
>>>>>> ktime_get_ns with ktime_get_mono_fast_ns), I experienced issues 
>>>>>> with passing the verifier.
>>>>>>
>>>>>> In addition to comparing ptr to end, I had to add checks that 
>>>>>> compare ptr to data_end, because the verifier can't deduce that 
>>>>>> end <= data_end. More branches will add a certain slowdown (not 
>>>>>> measured).
>>>>>>
>>>>>> A more serious issue is the overall program complexity. Even 
>>>>>> though the loop over the TCP options has an upper bound, and the 
>>>>>> pointer advances by at least one byte every iteration, I had to 
>>>>>> limit the total number of iterations artificially. The maximum 
>>>>>> number of iterations that makes the verifier happy is 10. With 
>>>>>> more iterations, I have the following error:
>>>>>>
>>>>>> BPF program is too large. Processed 1000001 insn
>>>>>>
>>>>>>                         processed 1000001 insns (limit 1000000) 
>>>>>> max_states_per_insn 29 total_states 35489 peak_states 596 
>>>>>> mark_read 45
>>>>>>
>>>>>> I assume that BPF_COMPLEXITY_LIMIT_INSNS (1 million) is the 
>>>>>> accumulated amount of instructions that the verifier can process 
>>>>>> in all branches, is that right? It doesn't look realistic that my 
>>>>>> program can run 1 million instructions in a single run, but it 
>>>>>> might be that if you take all possible flows and add up the 
>>>>>> instructions from these flows, it will exceed 1 million.
>>>>>>
>>>>>> The limitation of maximum 10 TCP options might be not enough, 
>>>>>> given that valid packets are permitted to include more than 10 
>>>>>> NOPs. An alternative of using bpf_load_hdr_opt and calling it 
>>>>>> three times doesn't look good either, because it will be about 
>>>>>> three times slower than going over the options once. So maybe 
>>>>>> having a helper for that is better than trying to fit it into BPF?
>>>>>>
>>>>>> One more interesting fact is the time that it takes for the 
>>>>>> verifier to check my program. If it's limited to 10 iterations, it 
>>>>>> does it pretty fast, but if I try to increase the number to 11 
>>>>>> iterations, it takes several minutes for the verifier to reach 1 
>>>>>> million instructions and print the error then. I also tried 
>>>>>> grouping the NOPs in an inner loop to count only 10 real options, 
>>>>>> and the verifier has been running for a few hours without any 
>>>>>> response. Is it normal? 
>>>>>
>>>>> Maxim, this may expose a verifier bug. Do you have a reproducer I 
>>>>> can access? I would like to debug this to see what is the root 
>>>>> case. Thanks!
>>>>
>>>> Thanks, I appreciate your help in debugging it. The reproducer is 
>>>> based on the modified XDP program from patch 10 in this series. 
>>>> You'll need to apply at least patches 6, 7, 8 from this series to 
>>>> get new BPF helpers needed for the XDP program (tell me if that's a 
>>>> problem, I can try to remove usage of new helpers, but it will 
>>>> affect the program length and may produce different results in the 
>>>> verifier).
>>>>
>>>> See the C code of the program that passes the verifier (compiled 
>>>> with clang version 12.0.0-1ubuntu1) in the bottom of this email. If 
>>>> you increase the loop boundary from 10 to at least 11 in 
>>>> cookie_init_timestamp_raw(), it fails the verifier after a few minutes. 
>>>
>>> I tried to reproduce with latest llvm (llvm-project repo),
>>> loop boundary 10 is okay and 11 exceeds the 1M complexity limit. For 10,
>>> the number of verified instructions is 563626 (more than 0.5M) so it is
>>> totally possible that one more iteration just blows past the limit.
>>
>> So, does it mean that the verifying complexity grows exponentially 
>> with increasing the number of loop iterations (options parsed)?
> 
> Depending on verification time pruning results, it is possible slightly 
> increase number of branches could result quite some (2x, 4x, etc.) of
> to-be-verified dynamic instructions.

Is it at least theoretically possible to make this coefficient below 2x? 
I.e. write a loop, so that adding another iteration will not double the 
number of verified instructions, but will have a smaller increase?

If that's not possible, then it looks like BPF can't have loops bigger 
than ~19 iterations (2^20 > 1M), and this function is not implementable 
in BPF.

>>
>> Is it a good enough reason to keep this code as a BPF helper, rather 
>> than trying to fit it into the BPF program?
> 
> Another option is to use global function, which is verified separately
> from the main bpf program.

Simply removing __always_inline didn't change anything. Do I need to 
make any other changes? Will it make sense to call a global function in 
a loop, i.e. will it increase chances to pass the verifier?

>>
>>>
>>>> If you apply this tiny change, it fails the verifier after about 3 
>>>> hours:
>>>>
> [...]


  reply	other threads:[~2021-11-26 16:52 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-19 14:46 [PATCH bpf-next 00/10] New BPF helpers to accelerate synproxy Maxim Mikityanskiy
2021-10-19 14:46 ` [PATCH bpf-next 01/10] bpf: Use ipv6_only_sock in bpf_tcp_gen_syncookie Maxim Mikityanskiy
2021-10-19 14:46 ` [PATCH bpf-next 02/10] bpf: Support dual-stack sockets in bpf_tcp_check_syncookie Maxim Mikityanskiy
2021-10-19 14:46 ` [PATCH bpf-next 03/10] bpf: Use EOPNOTSUPP " Maxim Mikityanskiy
2021-10-19 14:46 ` [PATCH bpf-next 04/10] bpf: Make errors of bpf_tcp_check_syncookie distinguishable Maxim Mikityanskiy
2021-10-20  3:28   ` John Fastabend
2021-10-20 13:16     ` Maxim Mikityanskiy
2021-10-20 15:26       ` Lorenz Bauer
2021-10-19 14:46 ` [PATCH bpf-next 05/10] bpf: Fix documentation of th_len in bpf_tcp_{gen,check}_syncookie Maxim Mikityanskiy
2021-10-19 14:46 ` [PATCH bpf-next 06/10] bpf: Expose struct nf_conn to BPF Maxim Mikityanskiy
2021-10-19 14:46 ` [PATCH bpf-next 07/10] bpf: Add helpers to query conntrack info Maxim Mikityanskiy
2021-10-20  3:56   ` Kumar Kartikeya Dwivedi
2021-10-20  9:28     ` Florian Westphal
2021-10-20  9:48       ` Toke Høiland-Jørgensen
2021-10-20  9:58         ` Florian Westphal
2021-10-20 12:21           ` Toke Høiland-Jørgensen
2021-10-20 12:44             ` Florian Westphal
2021-10-20 20:54               ` Toke Høiland-Jørgensen
2021-10-20 22:55                 ` David Ahern
2021-10-21  7:36                 ` Florian Westphal
2021-10-20 13:18     ` Maxim Mikityanskiy
2021-10-20 19:17       ` Kumar Kartikeya Dwivedi
2021-10-20  9:46   ` Toke Høiland-Jørgensen
2021-10-19 14:46 ` [PATCH bpf-next 08/10] bpf: Add helpers to issue and check SYN cookies in XDP Maxim Mikityanskiy
2021-10-19 14:46 ` [PATCH bpf-next 09/10] bpf: Add a helper to issue timestamp " Maxim Mikityanskiy
2021-10-19 16:45   ` Eric Dumazet
2021-10-20 13:16     ` Maxim Mikityanskiy
2021-10-20 15:56   ` Lorenz Bauer
2021-10-20 16:16     ` Toke Høiland-Jørgensen
2021-10-22 16:56       ` Maxim Mikityanskiy
2021-10-27  8:34         ` Lorenz Bauer
2021-11-01 11:14       ` Maxim Mikityanskiy
2021-11-03  2:10         ` Yonghong Song
2021-11-03 14:02           ` Maxim Mikityanskiy
2021-11-09  7:11             ` Yonghong Song
2021-11-25 14:34               ` Maxim Mikityanskiy
2021-11-26  5:43                 ` Yonghong Song
2021-11-26 16:50                   ` Maxim Mikityanskiy [this message]
2021-11-26 17:07                     ` Yonghong Song
2021-11-29 17:51                       ` Maxim Mikityanskiy
2021-12-01  6:39                         ` Yonghong Song
2021-12-01 18:06                           ` Andrii Nakryiko
2021-10-19 14:46 ` [PATCH bpf-next 10/10] bpf: Add sample for raw syncookie helpers Maxim Mikityanskiy
2021-10-20 18:01   ` Joe Stringer
2021-10-21 17:19     ` Maxim Mikityanskiy
2021-10-21  1:06   ` Alexei Starovoitov
2021-10-21 17:31     ` Maxim Mikityanskiy
2021-10-21 18:50       ` Alexei Starovoitov

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=cbd2e655-8113-e719-4b9d-b3987c398b04@nvidia.com \
    --to=maximmi@nvidia.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=clang-built-linux@googlegroups.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=hawk@kernel.org \
    --cc=jackmanb@google.com \
    --cc=joe@cilium.io \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=lmb@cloudflare.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=revest@chromium.org \
    --cc=songliubraving@fb.com \
    --cc=tariqt@nvidia.com \
    --cc=toke@redhat.com \
    --cc=yhs@fb.com \
    --cc=yoshfuji@linux-ipv6.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).