Re: [PATCH net-next v1 00/11] net: flow_dissector: opt-in byte-identical fast paths for common shapes

Willem de Bruijn <[email protected]>
Newsgroups org.kernel.vger.netdev
Message-ID <[email protected]>
Dave Seddon wrote:
> Thanks Willem, for the quick response and the feedback.
> 
> I think your point about where to draw the protocol boundary is a good one.
> 
> Eth + IPv4/IPv6 + TCP/UDP is clearly the common case. Beyond that, choosing
> what belongs in-kernel becomes increasingly subjective: VLAN/QinQ, PPPoE,
> MPLS, GRE, GTP-U, etc. all have substantial deployments, but that's also an
> argument for leaving those cases to the BPF flow dissector rather than
> continuing to grow a parallel parser.
> 
> On the +2500 lines, most of that isn't actually the fast-path parser:
> 
>     01  +75    gate BPF lookup behind a static key
>     02  +302   Eth + IPv4/IPv6 + TCP/UDP fast path
>     03  +180   + VLAN / QinQ
>     04  +95    + PPPoE
>     05  +103   + MPLS
>     06  +134   + IP-in-IP (4in4 / 6in4 / 4in6)
>     07  +121   + GRE
>     08  +270   per-shape counters (/proc/net)
>     09  +37    bound tunnel recursion
>     10  +1102  KUnit fast/slow-path equivalence test
>     11  +137   Documentation
>         ------
>         ~+2500
> 
> The KUnit test is therefore a large fraction of the diff. I don't want to
> dismiss that as "just tests" -- it is code that has to be maintained -- but
> its purpose is specifically to make maintaining two implementations safer:
> the same corpus is dissected through both paths and the resulting flow_keys
> are compared byte-for-byte.
> 
> More importantly, if I take your protocol-selection concern to its logical
> conclusion, most of this series disappears.
> 
> A v2 could contain only:
> 
> 1. the static-key optimization for the existing BPF lookup; and
> 2. one fast path for Eth + IPv4/IPv6 + TCP/UDP.
> 
> That is roughly:
> 
>     +377 / -50 across 5 files
> 
> plus whatever reduced KUnit coverage we decide is appropriate for that one
> shape.
> 
> I think there is a useful distinction between that case and the less common
> protocols. A network operator or vendor with a specialized encapsulation can
> reasonably deploy a BPF flow dissector. Requiring BPF in order for ordinary
> hosts to optimize the overwhelmingly common Ethernet/IP/TCP/UDP case is a
> higher bar, especially since users of RPS/RFS, fq/fq_codel/cake and bonding
> benefit indirectly through skb_get_hash() without necessarily knowing that
> the flow dissector is involved.
> 
> The performance result is also fairly consistent across architectures. In
> the isolated Eth + IPv4 + TCP benchmark the straight-line path reduced
> dissection time by 47-55% across x86, ARM and RISC-V. With all shapes
> compiled in, the Eth/IP path still improved the tested CPUs, although by a
> wider 4.7-31.6% range.
> 
> I agree that duplicating parsing logic has a maintenance cost. The reason I
> think the single common shape may still be a reasonable trade is that the
> surface is small, the fast path is deliberately allowed to bail out to the
> generic dissector whenever the packet doesn't match, and equivalence with the
> generic path can be continuously tested rather than assumed.
> 
> For the other protocols, I've implemented the same idea as a loadable BPF
> flow dissector:
> 
> https://github.com/randomizedcoder/flow_dissector_ebpf
> 
> That seems like a better home for experimenting with specialized shapes
> without growing the in-kernel parser.
> 
> So rather than trying to justify seven in-kernel fast paths, I'd propose
> shrinking v2 to the static-key BPF lookup optimization plus the single
> Eth + IPv4/IPv6 + TCP/UDP fast path, with a correspondingly smaller
> equivalence test.
> 
> Would that reduced series be worth posting for review?

Mine is just one opinion and not the most important one at that.

Existing non-linear code can also be optimized quite well, e.g., with
direct-call optimizations to indirect calls, FDO, etc. That may be a
more promising path than logic duplication.

That said, showing a significant performance benefit end-to-end for a
representative workload benchmark may help. Say, a on a TCP_RR
transport test. It is harder to judge the real world impact of the
flow dissection micro-benchmark on its own. With transport level
improvement, a single fast patch could warrant a look.

And same independently for the BPF static-key. BPF hooks have been
highly optimized by default, I'm a bit skeptical without data that
is worthwhile.

But I think the bar would be high.

In my ideal world we would ship a BPF program with the kernel,
deprecate the whole C parser and have the BPF parser be autoloaded at
boot.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.