On 20 Dec 2022, at 14:58, Ilya Maximets wrote:

> On 12/20/22 14:01, Eelco Chaudron wrote:
>>
>>
>> On 19 Dec 2022, at 13:20, Ilya Maximets wrote:
>>
>>> AF_XDP functions was deprecated in libbpf 0.7 and moved to libxdp.
>>> Functions bpf_get/set_link_xdp_id() was deprecated in libbpf 0.8
>>> and replaced with bpf_xdp_query_id() and bpf_xdp_attach/detach().
>>>
>>> Updating configuration and source code to accommodate above changes
>>> and allow building OVS with AF_XDP support on newer systems:
>>>
>>>  - Checking availability of the libxdp in a system by looking
>>>    for a library providing libxdp_strerror().
>>>
>>>  - Checking for xsk.h header provided by libxdp-dev[el] first,
>>>    fall back to xsk.h from libbpf if not found.
>>>
>>>  - Check for the NEED_WAKEUP feature replaced with direct checking
>>>    in the source code if XDP_USE_NEED_WAKEUP is defined.
>>>
>>>  - Checking availability of bpf_xdp_query_id and bpf_xdp_detach
>>>    and using them instead of deprecated APIs.  Fall back to old
>>>    functions if not found.
>>
>> So I guess this requires our build environment to match our runtime 
>> environment, as these functions are from dynamic libraries, not statically 
>> linked?
>
> Not exactly match, but symbols available during the build should
> be present in the runtime.  In general it means that libraries
> at build time should be the same or older than runtime ones.
>
> If the build environment is newer that will obviously not work,
> but I don't think that is generally supported anyway.

Guess we will find out once we switch the default ;)

>>
>> I guess this is find, as long as people understand it.
>>
>>>
>>>  - Dropped LIBBPF_LDADD variable as it makes library and function
>>>    detection much harder without providing any actual benefits.
>>>    AC_SEARCH_LIBS is used instead and it allows use of AC_CHECK_FUNCS.
>>>
>>>  - Header includes moved around to files where they are actually used.
>>>
>>>  - Removed libelf dependency as it is not really used.
>>>
>>> With these changes it should be possible to build OVS with either:
>>>
>>>  - libbpf built from the kernel sources (5.19 or older).
>>>  - libbpf < 0.7 provided in distributions.
>>>  - libxdp and libbpf >= 0.7 provided in newer distributions.
>>>
>>> libxdp added as a build dependency for Fedora build since all
>>> supported versions of Fedora are packaging this library.
>>>
>>> Signed-off-by: Ilya Maximets <i.maxim...@ovn.org>
>>
>> I have problems building this on my fedora35 system with 
>> gcc-11.3.1-3.fc35.x86_64:
>>
>> libtool: link: ( cd "include/openvswitch/.libs" && rm -f "libcxxtest.la" && 
>> ln -s "../libcxxtest.la" "libcxxtest.la" )
>> In file included from lib/netdev-linux-private.h:30,
>>                  from lib/netdev-afxdp.c:19:
>> In function ‘dp_packet_delete’,
>>     inlined from ‘dp_packet_delete’ at lib/dp-packet.h:246:1,
>>     inlined from ‘dp_packet_batch_add__’ at lib/dp-packet.h:775:9,
>>     inlined from ‘dp_packet_batch_add’ at lib/dp-packet.h:783:5,
>>     inlined from ‘netdev_afxdp_rxq_recv’ at lib/netdev-afxdp.c:894:9:
>> lib/dp-packet.h:260:9: error: ‘free’ called on pointer ‘*umem.xpool.array’ 
>> with nonzero offset [8, 2558044588346441168] [-Werror=free-nonheap-object]
>>   260 |         free(b);
>>       |         ^~~~~~~
>>
>> Guess it does not recognise the (b->source == DPBUF_AFXDP) statement…
>
> This is annoying, I didn't found a way to trick compiler into
> doing the right thing.  The code path is fairly obvious and
> b->source is always set on that code path just a few lines above.
>
> So, it definitely looks like a compiler bug.
>
> Do you know of a good portable way disabling warnings in the code?
> Otherwise, we can disable it globally in the configure script if
> building with AF_XDP.

I know there is ‘#pragma clang diagnostic’ and ‘#pragma gcc diagnostic’ not 
sure what other compilers we support.

>>
>> This is my build config:
>>
>> ./configure --enable-Werror --enable-usdt-probes --localstatedir=/var 
>> --prefix=/usr --sysconfdir=/etc --enable-afxdp
>>
>> Guess this should be fixed before we enable afxdp by default?
>>
>>
>> Also when I build it without the Werror option I’m not able to start a 
>> sandbox:
>>
>> make[1]: Leaving directory '/home/echaudron/Documents/review/ovs_ilya_afxdp'
>> ovsdb-tool create conf.db 
>> /home/echaudron/Documents/review/ovs_ilya_afxdp/vswitchd/vswitch.ovsschema
>> ovsdb-tool: symbol lookup error: /lib64/libxdp.so.1: undefined symbol: 
>> silence_libbpf_logging
>> cat: 
>> '/home/echaudron/Documents/review/ovs_ilya_afxdp/tutorial/sandbox/*.pid': No 
>> such file or directory
>>
>> But this might be something specific to libxdp on my system, and libbpf :(
>
> Yeah, I guess libxdp and libbpf versions on f35 are not really compatible.
> We're not calling silence_libbpf_logging from OVS, so it's a call from the
> libbpf itself.
>
>>
>>> ---
>>>  NEWS                            |  2 ++
>>>  acinclude.m4                    | 21 +++++++++---------
>>>  lib/automake.mk                 |  1 -
>>>  lib/libopenvswitch.pc.in        |  2 +-
>>>  lib/netdev-afxdp-pool.c         |  2 ++
>>>  lib/netdev-afxdp-pool.h         |  5 -----
>>>  lib/netdev-afxdp.c              | 38 ++++++++++++++++++++++++++-------
>>>  rhel/openvswitch-fedora.spec.in |  2 +-
>>>  8 files changed, 46 insertions(+), 27 deletions(-)
>>>
>>> diff --git a/NEWS b/NEWS
>>> index 265375e1c..5d39c7d27 100644
>>> --- a/NEWS
>>> +++ b/NEWS
>>> @@ -1,5 +1,7 @@
>>>  Post-v3.0.0
>>>  --------------------
>>> +   - AF_XDP:
>>> +     * Added support for building with libxdp and libbpf >= 0.7.
>>>     - ovs-appctl:
>>>       * "ovs-appctl ofproto/trace" command can now display port names with 
>>> the
>>>         "--names" option.
>>> diff --git a/acinclude.m4 b/acinclude.m4
>>> index aa9af5506..aed01c967 100644
>>> --- a/acinclude.m4
>>> +++ b/acinclude.m4
>>> @@ -251,7 +251,7 @@ AC_DEFUN([OVS_FIND_DEPENDENCY], [
>>>
>>>  dnl OVS_CHECK_LINUX_AF_XDP
>>>  dnl
>>> -dnl Check both Linux kernel AF_XDP and libbpf support
>>> +dnl Check both Linux kernel AF_XDP and libbpf/libxdp support
>>>  AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [
>>>    AC_ARG_ENABLE([afxdp],
>>>                  [AS_HELP_STRING([--enable-afxdp], [Enable AF-XDP 
>>> support])],
>>> @@ -270,23 +270,22 @@ AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [
>>>      AC_CHECK_HEADER([linux/if_xdp.h], [],
>>>        [AC_MSG_ERROR([unable to find linux/if_xdp.h for AF_XDP support])])
>>>
>>> -    AC_CHECK_HEADER([bpf/xsk.h], [],
>>> -      [AC_MSG_ERROR([unable to find bpf/xsk.h for AF_XDP support])])
>>> +    AC_CHECK_HEADER([xdp/xsk.h],
>>> +      AC_DEFINE([HAVE_LIBXDP], [1], [xsk.h is supplied with libxdp]),
>>> +      AC_CHECK_HEADER([bpf/xsk.h], [],
>>> +        [AC_MSG_ERROR([unable to find xsk.h for AF_XDP support])]))
>>>
>>>      AC_CHECK_FUNCS([pthread_spin_lock], [],
>>>        [AC_MSG_ERROR([unable to find pthread_spin_lock for AF_XDP 
>>> support])])
>>>
>>>      OVS_FIND_DEPENDENCY([numa_alloc_onnode], [numa], [libnuma])
>>> +    OVS_FIND_DEPENDENCY([libbpf_strerror], [bpf], [libbpf])
>>> +    AC_SEARCH_LIBS([libxdp_strerror], [xdp])
>>> +
>>> +    AC_CHECK_FUNCS([bpf_xdp_query_id bpf_xdp_detach])
>>>
>>>      AC_DEFINE([HAVE_AF_XDP], [1],
>>>                [Define to 1 if AF_XDP support is available and enabled.])
>>> -    LIBBPF_LDADD=" -lbpf -lelf"
>>> -    AC_SUBST([LIBBPF_LDADD])
>>> -
>>> -    AC_CHECK_DECL([xsk_ring_prod__needs_wakeup], [
>>> -      AC_DEFINE([HAVE_XDP_NEED_WAKEUP], [1],
>>> -        [XDP need wakeup support detected in xsk.h.])
>>> -    ], [], [[#include <bpf/xsk.h>]])
>>>    fi
>>>    AM_CONDITIONAL([HAVE_AF_XDP], test "$AF_XDP_ENABLE" = true)
>>>  ])
>>> @@ -357,7 +356,7 @@ AC_DEFUN([OVS_CHECK_DPDK], [
>>>      ], [], [[#include <rte_config.h>]])
>>>
>>>      AC_CHECK_DECL([RTE_NET_AF_XDP], [
>>> -      LIBBPF_LDADD="-lbpf"
>>> +      OVS_FIND_DEPENDENCY([libbpf_strerror], [bpf], [libbpf])
>>>      ], [], [[#include <rte_config.h>]])
>>>
>>>      AC_CHECK_DECL([RTE_LIBRTE_VHOST_NUMA], [
>>> diff --git a/lib/automake.mk b/lib/automake.mk
>>> index a0fabe38f..61bdc308f 100644
>>> --- a/lib/automake.mk
>>> +++ b/lib/automake.mk
>>> @@ -9,7 +9,6 @@ lib_LTLIBRARIES += lib/libopenvswitch.la
>>>
>>>  lib_libopenvswitch_la_LIBADD = $(SSL_LIBS)
>>>  lib_libopenvswitch_la_LIBADD += $(CAPNG_LDADD)
>>> -lib_libopenvswitch_la_LIBADD += $(LIBBPF_LDADD)
>>>
>>>
>>>  if WIN32
>>> diff --git a/lib/libopenvswitch.pc.in b/lib/libopenvswitch.pc.in
>>> index 44fbb1f9f..a5f4d3947 100644
>>> --- a/lib/libopenvswitch.pc.in
>>> +++ b/lib/libopenvswitch.pc.in
>>> @@ -7,5 +7,5 @@ Name: libopenvswitch
>>>  Description: Open vSwitch library
>>>  Version: @VERSION@
>>>  Libs: -L${libdir} -lopenvswitch
>>> -Libs.private: @LIBS@ @SSL_LIBS@ @CAPNG_LDADD@ @LIBBPF_LDADD@
>>> +Libs.private: @LIBS@ @SSL_LIBS@ @CAPNG_LDADD@
>>>  Cflags: -I${includedir}
>>> diff --git a/lib/netdev-afxdp-pool.c b/lib/netdev-afxdp-pool.c
>>> index 3386d2dcf..f56a7b29e 100644
>>> --- a/lib/netdev-afxdp-pool.c
>>> +++ b/lib/netdev-afxdp-pool.c
>>> @@ -15,6 +15,8 @@
>>>   */
>>>  #include <config.h>
>>>
>>
>> Remove new line here?
>
> I just wanted to separate it from system headers, since
> it's not one of them.
>
>>
>>> +#include <errno.h>
>>> +
>>>  #include "dp-packet.h"
>>>  #include "netdev-afxdp-pool.h"
>>>  #include "openvswitch/util.h"
>>> diff --git a/lib/netdev-afxdp-pool.h b/lib/netdev-afxdp-pool.h
>>> index f929b9489..6681cf539 100644
>>> --- a/lib/netdev-afxdp-pool.h
>>> +++ b/lib/netdev-afxdp-pool.h
>>> @@ -19,12 +19,7 @@
>>>
>>>  #ifdef HAVE_AF_XDP
>>>
>>> -#include <bpf/xsk.h>
>>> -#include <errno.h>
>>> -#include <stdbool.h>
>>> -
>>>  #include "openvswitch/thread.h"
>>> -#include "ovs-atomic.h"
>>>
>>>  /* LIFO ptr_array. */
>>>  struct umem_pool {
>>> diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c
>>> index ca3f2431e..6ced8a2b6 100644
>>> --- a/lib/netdev-afxdp.c
>>> +++ b/lib/netdev-afxdp.c
>>> @@ -21,6 +21,11 @@
>>>  #include "netdev-afxdp.h"
>>>  #include "netdev-afxdp-pool.h"
>>>
>>> +#ifdef HAVE_LIBXDP
>>> +#include <xdp/xsk.h>
>>> +#else
>>> +#include <bpf/xsk.h>
>>> +#endif
>>>  #include <errno.h>
>>>  #include <inttypes.h>
>>>  #include <linux/rtnetlink.h>
>>> @@ -29,6 +34,7 @@
>>>  #include <numa.h>
>>>  #include <numaif.h>
>>>  #include <poll.h>
>>> +#include <stdbool.h>
>>>  #include <stdlib.h>
>>>  #include <sys/resource.h>
>>>  #include <sys/socket.h>
>>> @@ -44,6 +50,7 @@
>>>  #include "openvswitch/list.h"
>>>  #include "openvswitch/thread.h"
>>>  #include "openvswitch/vlog.h"
>>> +#include "ovs-atomic.h"
>>>  #include "ovs-numa.h"
>>>  #include "packets.h"
>>>  #include "socket-util.h"
>>> @@ -72,7 +79,7 @@ static struct vlog_rate_limit rl = 
>>> VLOG_RATE_LIMIT_INIT(5, 20);
>>>  #define PROD_NUM_DESCS      XSK_RING_PROD__DEFAULT_NUM_DESCS
>>>  #define CONS_NUM_DESCS      XSK_RING_CONS__DEFAULT_NUM_DESCS
>>>
>>> -#ifdef HAVE_XDP_NEED_WAKEUP
>>> +#ifdef XDP_USE_NEED_WAKEUP
>>>  #define NEED_WAKEUP_DEFAULT true
>>>  #else
>>>  #define NEED_WAKEUP_DEFAULT false
>>> @@ -169,7 +176,7 @@ struct netdev_afxdp_tx_lock {
>>>      );
>>>  };
>>>
>>> -#ifdef HAVE_XDP_NEED_WAKEUP
>>> +#ifdef XDP_USE_NEED_WAKEUP
>>>  static inline void
>>>  xsk_rx_wakeup_if_needed(struct xsk_umem_info *umem,
>>>                          struct netdev *netdev, int fd)
>>> @@ -201,7 +208,7 @@ xsk_tx_need_wakeup(struct xsk_socket_info *xsk_info)
>>>      return xsk_ring_prod__needs_wakeup(&xsk_info->tx);
>>>  }
>>>
>>> -#else /* !HAVE_XDP_NEED_WAKEUP */
>>> +#else /* !XDP_USE_NEED_WAKEUP */
>>>  static inline void
>>>  xsk_rx_wakeup_if_needed(struct xsk_umem_info *umem OVS_UNUSED,
>>>                          struct netdev *netdev OVS_UNUSED,
>>> @@ -215,7 +222,7 @@ xsk_tx_need_wakeup(struct xsk_socket_info *xsk_info 
>>> OVS_UNUSED)
>>>  {
>>>      return true;
>>>  }
>>> -#endif /* HAVE_XDP_NEED_WAKEUP */
>>> +#endif /* XDP_USE_NEED_WAKEUP */
>>>
>>>  static void
>>>  netdev_afxdp_cleanup_unused_pool(struct unused_pool *pool)
>>> @@ -351,7 +358,7 @@ xsk_configure_socket(struct xsk_umem_info *umem, 
>>> uint32_t ifindex,
>>>      cfg.bind_flags = xdp_modes[mode].bind_flags;
>>>      cfg.xdp_flags = xdp_modes[mode].xdp_flags | 
>>> XDP_FLAGS_UPDATE_IF_NOEXIST;
>>>
>>> -#ifdef HAVE_XDP_NEED_WAKEUP
>>> +#ifdef XDP_USE_NEED_WAKEUP
>>>      if (use_need_wakeup) {
>>>          cfg.bind_flags |= XDP_USE_NEED_WAKEUP;
>>>      }
>>> @@ -377,7 +384,11 @@ xsk_configure_socket(struct xsk_umem_info *umem, 
>>> uint32_t ifindex,
>>>      }
>>>
>>>      /* Make sure the built-in AF_XDP program is loaded. */
>>> +#ifdef HAVE_BPF_XDP_QUERY_ID
>>> +    ret = bpf_xdp_query_id(ifindex, cfg.xdp_flags, &prog_id);
>>> +#else
>>>      ret = bpf_get_link_xdp_id(ifindex, &prog_id, cfg.xdp_flags);
>>> +#endif
>>>      if (ret || !prog_id) {
>>>          if (ret) {
>>>              VLOG_ERR("Get XDP prog ID failed (%s)", ovs_strerror(errno));
>>> @@ -630,9 +641,9 @@ netdev_afxdp_set_config(struct netdev *netdev, const 
>>> struct smap *args,
>>>      }
>>>
>>>      need_wakeup = smap_get_bool(args, "use-need-wakeup", 
>>> NEED_WAKEUP_DEFAULT);
>>> -#ifndef HAVE_XDP_NEED_WAKEUP
>>> +#ifndef XDP_USE_NEED_WAKEUP
>>>      if (need_wakeup) {
>>> -        VLOG_WARN("XDP need_wakeup is not supported in libbpf.");
>>> +        VLOG_WARN("XDP need_wakeup is not supported in libbpf/libxdp.");
>>>          need_wakeup = false;
>>>      }
>>>  #endif
>>> @@ -742,7 +753,11 @@ xsk_remove_xdp_program(uint32_t ifindex, enum 
>>> afxdp_mode mode)
>>>      uint32_t ret, prog_id = 0;
>>>
>>>      /* Check whether XDP program is loaded. */
>>> +#ifdef HAVE_BPF_XDP_QUERY_ID
>>> +    ret = bpf_xdp_query_id(ifindex, flags, &prog_id);
>>> +#else
>>>      ret = bpf_get_link_xdp_id(ifindex, &prog_id, flags);
>>> +#endif
>>>      if (ret) {
>>>          VLOG_ERR("Failed to get XDP prog id (%s)", ovs_strerror(errno));
>>>          return;
>>> @@ -753,7 +768,14 @@ xsk_remove_xdp_program(uint32_t ifindex, enum 
>>> afxdp_mode mode)
>>>          return;
>>>      }
>>>
>>> -    bpf_set_link_xdp_fd(ifindex, -1, flags);
>>> +#ifdef HAVE_BPF_XDP_DETACH
>>> +    if (bpf_xdp_detach(ifindex, flags, NULL) != 0) {
>>> +#else
>>> +    if (bpf_set_link_xdp_fd(ifindex, -1, flags) != 0) {
>>> +#endif
>>> +        VLOG_ERR("Failed to detach XDP program (%s) at ifindex %d",
>>> +                 ovs_strerror(errno), ifindex);
>>> +    }
>>>  }
>>>
>>>  void
>>> diff --git a/rhel/openvswitch-fedora.spec.in 
>>> b/rhel/openvswitch-fedora.spec.in
>>> index 4a3e6294b..6564d5252 100644
>>> --- a/rhel/openvswitch-fedora.spec.in
>>> +++ b/rhel/openvswitch-fedora.spec.in
>>> @@ -75,7 +75,7 @@ BuildRequires: dpdk-devel >= 22.11
>>>  Provides: %{name}-dpdk = %{version}-%{release}
>>>  %endif
>>>  %if %{with afxdp}
>>> -BuildRequires: libbpf-devel numactl-devel
>>> +BuildRequires: libxdp-devel libbpf-devel numactl-devel
>>>  %endif
>>>  BuildRequires: unbound unbound-devel
>>>
>>> -- 
>>> 2.38.1
>>

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to