Re: [PATCH bpf-next] bpf: Add multi-prog support for XDP BPF programs

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

 



On Fri, Nov 15, 2024 at 2:09 PM Andrii Nakryiko
<andrii.nakryiko@xxxxxxxxx> wrote:
>
> On Thu, Nov 14, 2024 at 9:07 AM Ryan Wilson <ryantimwilson@xxxxxxxxx> wrote:
> >
> > Currently, network devices only support a single XDP program. However,
> > there are use cases for multiple XDP programs per device. For example,
> > at Meta, we have XDP programs for firewalls, DDOS and logging that must
> > all run in a specific order. To work around the lack of multi-program
> > support, a single daemon loads all programs and uses bpf_tail_call()
> > in a loop to jump to each program contained in a BPF map.
> >
> > This patch proposes allowing multiple XDP programs per device based
> > on the mprog API from the below commit:
> >
> > Commit 053c8e1f235d ("bpf: Add generic attach/detach/query API for
> > multi-progs")
> >
> > This patch adds support for multi-progs for generic XDP and the tunnel
> > driver, as it shares many APIs with generic XDP. Each driver can be
> > migrated by:
> > 1. Return 0 for command = XDP_QUERY_MPROG_SUPPORT
> > 2. Codemod xdp.prog -> xdp.array in driver code
> > 3. Run programs with bpf_mprog_run_xdp()
> > 4. Change bpf_prog_put() to bpf_mprog_array_put()
> >
> > Note non-migrated driver are currently backwards compatible. They will
> > receive a single program object but attachment will fail if user tries
> > to attach multiple BPF programs.
> >
> > Note this patch is more complex than its TCX counterpart
> >
> > Commit e420bed02507 ("bpf: Add fd-based tcx multi-prog infra with
> > link support")
> >
> > This is because XDP program attachment/detachment is done via BPF links and
> > netlink socket unlike bpf_prog_attach() syscall. We only add multi-progs
> > support for BPF links in this commit but ensure the netlink socket is
> > backwards compatible with single program attachment/detachment/queries.
> >
> > Unlike TCX, each driver needs to own a reference to the BPF programs it
> > runs. Thus, we introduce struct bpf_mprog_array to copy from
> > bpf_mprog_entry owned by the network device. The BPF driver then will
> > release the array via bpf_mprog_array_put() which will decrement each
> > BPF program refcount and free the array memory.
> >
> > Furthermore, we typically set the BPF multi-prog flags via
> > link_create.flags e.g. BPF_F_BEFORE. However, there are already XDP_*
> > flags set via link_create.flags e.g. XDP_FLAGS_SKB_MODE. For example,
> > BPF_F_REPLACE and XDP_FLAGS_DRV_MODE both have the same value. Thus to
> > allow for setting both XDP_* mode and BPF_* multi-prog flags when using
> > BPF links, we introduce link_create.xdp.flags for setting BPF_* flags
> > specifically. However, feedback is needed on this approach to make sure
> > its compatible with libbpf.
> >
> > Note I am in the process of verifying no/minimal performance overhead
> > for a real driver but I am sending this patch for feedback on the overall
> > approach.
> >
> > Signed-off-by: Ryan Wilson <ryantimwilson@xxxxxxxxx>
> > ---
>
> So I looked through this once, but it's a bit too much code to grok at
> once, so please bear with me if I'm proposing something stupid. But
> just a few initial thoughts.
>
> First, you bundled everything into a single patch, which makes it
> harder to review. At the very least, split out selftests. If you can
> break it further, say into mprog_array abstraction patch, then generic
> XDP infrastructure patch, then tun-specific patch, etc, that would
> make it much easier to follow and review.

Good point. I'll split this up into multiple patches.

Note I really didn't add new selftests, I only changed an existing
selftest that expected multiple links attaching to an XDP device to
fail - that now works. I'll add a more complete selftest to the v2
patch set that makes use of all the relevant BPF_F_* multiprog flags.

>
> Looking at tun.c, I like how straightforward the conversion is thanks
> to bpf_mprog_array, nice job with that! Converting the other 50 use
> cases should be easy ;)
>
> There seems to be dev_xdp_attach_netlink() duplication, is it
> absolutely necessary or can we keep a common dev_xdp_attach()
> implementation between BPF link and netlink implementations?

So I ended up splitting these because I thought it was harder to read,
especially now that netlink doesn't support mprog and link does. :) I
tried to combine a lot of the logic in verify_dev_xdp_attach but maybe
that wasn't enough. I'll try recombining dev_xdp_attach() again and
see how it looks.

>
> But overall everything seems to make sense, but again, a bit much
> code, so I'll need few more passes (maybe next week).
>
>
> >  drivers/net/tun.c                             |  54 +--
> >  include/linux/bpf_mprog.h                     |  72 +++
> >  include/linux/netdevice.h                     |  23 +-
> >  include/linux/skbuff.h                        |   3 +-
> >  include/net/xdp.h                             |  94 ++++
> >  include/uapi/linux/bpf.h                      |  12 +
> >  net/core/dev.c                                | 422 ++++++++++++++----
> >  net/core/rtnetlink.c                          |  16 +-
> >  net/core/skbuff.c                             |  11 +-
> >  .../selftests/bpf/prog_tests/xdp_link.c       |  15 +-
> >  10 files changed, 571 insertions(+), 151 deletions(-)
>
> [...]





[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