DPDK patches and discussions
 help / color / mirror / Atom feed
From: Cody Cheng <ccheng@iol.unh.edu>
To: Stephen Hemminger <stephen@networkplumber.org>
Cc: dev@dpdk.org, ferruh.yigit@amd.com
Subject: Re: [PATCH v15 07/11] net/tap: use libbpf to load new BPF program
Date: Tue, 28 May 2024 12:33:41 -0400	[thread overview]
Message-ID: <CAMEVEZs15wA+EigtHhAMfxn2VBg=4j1Mke+oStdtFx4u3iGDcw@mail.gmail.com> (raw)
In-Reply-To: <20240521201410.126116-8-stephen@networkplumber.org>

[-- Attachment #1: Type: text/plain, Size: 37021 bytes --]

Hi, I've added the Ubuntu 24.04 environment to the Community Lab but
without werror enabled as the rte_pcapng.c warning would cause them to
fail. Once the rte_pcapng.c warning is fixed, I will re-enable werror. I
will send an email to the ci mailing list with the logs of the warning so
that people are aware of it.

Thanks,
Cody

On Tue, May 21, 2024 at 4:14 PM Stephen Hemminger <
stephen@networkplumber.org> wrote:

> There were multiple issues in the RSS queue support in the TAP
> driver. This required extensive rework of the BPF support.
>
> Change the BPF loading to use bpftool to
> create a skeleton header file, and load with libbpf.
> The BPF is always compiled from source so less chance that
> source and instructions diverge. Also resolves issue where
> libbpf and source get out of sync. The program
> is only loaded once, so if multiple rules are created
> only one BPF program is loaded in kernel.
>
> The new BPF program only needs a single action.
> No need for action and re-classification step.
>
> It also fixes the missing bits from the original.
>     - supports setting RSS key per flow
>     - level of hash can be L3 or L3/L4.
>
> Bugzilla ID: 1329
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  doc/guides/rel_notes/release_24_07.rst |   3 +
>  drivers/net/tap/bpf/meson.build        |  81 +++--
>  drivers/net/tap/meson.build            |  39 ++-
>  drivers/net/tap/rte_eth_tap.c          |  14 +-
>  drivers/net/tap/rte_eth_tap.h          |   6 +-
>  drivers/net/tap/tap_flow.c             | 416 ++++++-------------------
>  drivers/net/tap/tap_flow.h             |  17 +-
>  drivers/net/tap/tap_rss.h              |  10 +-
>  drivers/net/tap/tap_tcmsgs.h           |   4 +-
>  9 files changed, 186 insertions(+), 404 deletions(-)
>
> diff --git a/doc/guides/rel_notes/release_24_07.rst
> b/doc/guides/rel_notes/release_24_07.rst
> index a6295359b1..37a6e98637 100644
> --- a/doc/guides/rel_notes/release_24_07.rst
> +++ b/doc/guides/rel_notes/release_24_07.rst
> @@ -59,6 +59,9 @@ New Features
>
>    * Updated to support up to 8 queues when used by secondary process.
>
> +  * Fixed support of RSS flow action to work with current Linux
> +    kernels and BPF tooling. Will only be enabled if clang, libbpf 1.0
> +    and bpftool are available.
>
>  Removed Items
>  -------------
> diff --git a/drivers/net/tap/bpf/meson.build
> b/drivers/net/tap/bpf/meson.build
> index f2c03a19fd..df497948e2 100644
> --- a/drivers/net/tap/bpf/meson.build
> +++ b/drivers/net/tap/bpf/meson.build
> @@ -1,17 +1,26 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright 2024 Stephen Hemminger <stephen@networkplumber.org>
>
> -enable_tap_rss = false
> -
> -libbpf = dependency('libbpf', required: false, method: 'pkg-config')
> +# Loading BPF requires libbpf
> +# and the bpf_map__XXX API's were introduced in 0.8.0
> +libbpf = dependency('libbpf', version: '>= 1.0',
> +                    required: false, method: 'pkg-config')
>  if not libbpf.found()
>      message('net/tap: no RSS support missing libbpf')
>      subdir_done()
>  endif
>
> +# Making skeleton needs bpftool
>  # Debian install this in /usr/sbin which is not in $PATH
> -bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false,
> version: '>= 5.6.0')
> -if not bpftool.found()
> +bpftool_supports_skel = false
> +bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false)
> +if bpftool.found()
> +    # Some Ubuntu versions have non-functional bpftool
> +    bpftool_supports_skel = run_command(bpftool, 'gen', 'help',
> +                                        check:false).returncode() == 0
> +endif
> +
> +if not bpftool_supports_skel
>      message('net/tap: no RSS support missing bpftool')
>      subdir_done()
>  endif
> @@ -39,43 +48,47 @@ machine_name = run_command('uname',
> '-m').stdout().strip()
>  march_include_dir = '/usr/include/' + machine_name + '-linux-gnu'
>
>  clang_flags = [
> -    '-O2',
> -    '-Wall',
> -    '-Wextra',
> -    '-target',
> -    'bpf',
> -    '-g',
> -    '-c',
> +        # these are flags used to build the BPF code
> +        '-O2',
> +        '-Wall',
> +        '-Wextra',
> +        max_queues,
> +        '-target',
> +        'bpf',
> +        '-g',
> +        '-c',
>  ]
>
> +# Command used to compile BPF pgrograme
>  bpf_o_cmd = [
> -    clang,
> -    clang_flags,
> -    '-idirafter',
> -    libbpf_include_dir,
> -    '-idirafter',
> -    march_include_dir,
> -    '@INPUT@',
> -    '-o',
> -    '@OUTPUT@'
> +        clang,
> +        clang_flags,
> +        '-idirafter',
> +        libbpf_include_dir,
> +        '-idirafter',
> +        march_include_dir,
> +        '@INPUT@',
> +        '-o',
> +        '@OUTPUT@',
>  ]
>
> +# Command used to generate header file from BPF object
>  skel_h_cmd = [
> -    bpftool,
> -    'gen',
> -    'skeleton',
> -    '@INPUT@'
> +        bpftool,
> +        'gen',
> +        'skeleton',
> +        '@INPUT@',
>  ]
>
>  tap_rss_o = custom_target(
> -    'tap_rss.bpf.o',
> -    input: 'tap_rss.c',
> -    output: 'tap_rss.o',
> -    command: bpf_o_cmd)
> +        'tap_rss.bpf.o',
> +        input: 'tap_rss.c',
> +        output: 'tap_rss.o',
> +        command: bpf_o_cmd)
>
>  tap_rss_skel_h = custom_target(
> -    'tap_rss.skel.h',
> -    input: tap_rss_o,
> -    output: 'tap_rss.skel.h',
> -    command: skel_h_cmd,
> -    capture: true)
> +        'tap_rss.skel.h',
> +        input: tap_rss_o,
> +        output: 'tap_rss.skel.h',
> +        command: skel_h_cmd,
> +        capture: true)
> diff --git a/drivers/net/tap/meson.build b/drivers/net/tap/meson.build
> index 66647a1c62..5e5a3ad3c6 100644
> --- a/drivers/net/tap/meson.build
> +++ b/drivers/net/tap/meson.build
> @@ -5,36 +5,33 @@ if not is_linux
>      build = false
>      reason = 'only supported on Linux'
>  endif
> +
>  sources = files(
>          'rte_eth_tap.c',
>          'tap_intr.c',
>          'tap_netlink.c',
>  )
>
> +deps = ['bus_vdev', 'gso', 'hash']
> +
> +max_queues = '-DTAP_MAX_QUEUES=16'
> +cflags += max_queues
> +
> +require_iova_in_mbuf = false
> +
>  if cc.has_header_symbol('linux/pkt_cls.h', 'TCA_FLOWER_ACT')
>      cflags += '-DHAVE_TCA_FLOWER'
>      sources += files(
> -        'tap_bpf_api.c',
> -        'tap_flow.c',
> -        'tap_tcmsgs.c',
> +            'tap_flow.c',
> +            'tap_tcmsgs.c',
>      )
> -endif
> -
> -deps = ['bus_vdev', 'gso', 'hash']
>
> -cflags += '-DTAP_MAX_QUEUES=16'
> -
> -# input array for meson symbol search:
> -# [ "MACRO to define if found", "header for the search",
> -#   "enum/define", "symbol to search" ]
> -#
> -args = [
> -        [ 'HAVE_TC_ACT_BPF', 'linux/tc_act/tc_bpf.h',
> 'TCA_ACT_BPF_UNSPEC' ],
> -]
> -config = configuration_data()
> -foreach arg:args
> -    config.set(arg[0], cc.has_header_symbol(arg[1], arg[2]))
> -endforeach
> -configure_file(output : 'tap_autoconf.h', configuration : config)
> +    enable_tap_rss = false
>
> -require_iova_in_mbuf = false
> +    subdir('bpf')
> +    if enable_tap_rss
> +        cflags += '-DHAVE_BPF_RSS'
> +        ext_deps += libbpf
> +        sources += tap_rss_skel_h
> +    endif
> +endif
> diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
> index 9058a47295..d847565073 100644
> --- a/drivers/net/tap/rte_eth_tap.c
> +++ b/drivers/net/tap/rte_eth_tap.c
> @@ -1140,6 +1140,7 @@ tap_dev_close(struct rte_eth_dev *dev)
>                 tap_flow_implicit_flush(internals, NULL);
>                 tap_nl_final(internals->nlsk_fd);
>                 internals->nlsk_fd = -1;
> +               tap_flow_bpf_destroy(internals);
>         }
>  #endif
>
> @@ -1949,6 +1950,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev,
> const char *tap_name,
>         strlcpy(pmd->name, tap_name, sizeof(pmd->name));
>         pmd->type = type;
>         pmd->ka_fd = -1;
> +
>  #ifdef HAVE_TCA_FLOWER
>         pmd->nlsk_fd = -1;
>  #endif
> @@ -2031,13 +2033,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev,
> const char *tap_name,
>         /* Make network device persist after application exit */
>         pmd->persist = persist;
>
> -       pmd->if_index = if_nametoindex(pmd->name);
> -       if (!pmd->if_index) {
> -               TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name);
> -               goto disable_rte_flow;
> -       }
> -
> -
>  #ifdef HAVE_TCA_FLOWER
>         /*
>          * Set up everything related to rte_flow:
> @@ -2053,6 +2048,11 @@ eth_dev_tap_create(struct rte_vdev_device *vdev,
> const char *tap_name,
>                         pmd->name);
>                 goto disable_rte_flow;
>         }
> +       pmd->if_index = if_nametoindex(pmd->name);
> +       if (!pmd->if_index) {
> +               TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name);
> +               goto disable_rte_flow;
> +       }
>         if (qdisc_create_multiq(pmd->nlsk_fd, pmd->if_index) < 0) {
>                 TAP_LOG(ERR, "%s: failed to create multiq qdisc.",
>                         pmd->name);
> diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
> index af18b29090..ce4322ad04 100644
> --- a/drivers/net/tap/rte_eth_tap.h
> +++ b/drivers/net/tap/rte_eth_tap.h
> @@ -81,10 +81,8 @@ struct pmd_internals {
>  #ifdef HAVE_TCA_FLOWER
>         int nlsk_fd;                      /* Netlink socket fd */
>         int flow_isolate;                 /* 1 if flow isolation is
> enabled */
> -       int rss_enabled;                  /* 1 if RSS is enabled, else 0 */
> -       /* implicit rules set when RSS is enabled */
> -       int map_fd;                       /* BPF RSS map fd */
> -       int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */
> +
> +       struct tap_rss *rss;              /* BPF program */
>
>         LIST_HEAD(tap_flows, rte_flow) flows;        /* rte_flow rules */
>         /* implicit rte_flow rules set when a remote device is active */
> diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
> index 45321aee86..0a90c0487b 100644
> --- a/drivers/net/tap/tap_flow.c
> +++ b/drivers/net/tap/tap_flow.c
> @@ -15,25 +15,19 @@
>  #include <rte_random.h>
>  #include <rte_malloc.h>
>  #include <rte_eth_tap.h>
> +#include <rte_uuid.h>
>
>  #include <tap_flow.h>
> -#include <tap_autoconf.h>
>  #include <tap_tcmsgs.h>
>  #include <tap_rss.h>
>
> -/* RSS key management */
> -enum bpf_rss_key_e {
> -       KEY_CMD_GET = 1,
> -       KEY_CMD_RELEASE,
> -       KEY_CMD_INIT,
> -       KEY_CMD_DEINIT,
> -};
> -
> -enum key_status_e {
> -       KEY_STAT_UNSPEC,
> -       KEY_STAT_USED,
> -       KEY_STAT_AVAILABLE,
> -};
> +#ifdef HAVE_BPF_RSS
> +/* Workaround for warning in bpftool generated skeleton code */
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wcast-qual"
> +#include "tap_rss.skel.h"
> +#pragma GCC diagnostic pop
> +#endif
>
>  #define ISOLATE_HANDLE 1
>  #define REMOTE_PROMISCUOUS_HANDLE 2
> @@ -41,8 +35,6 @@ enum key_status_e {
>  struct rte_flow {
>         LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow
> structure */
>         struct rte_flow *remote_flow; /* associated remote flow */
> -       int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */
> -       uint32_t key_idx; /* RSS rule key index into BPF map */
>         struct nlmsg msg;
>  };
>
> @@ -69,12 +61,16 @@ struct action_data {
>                 struct skbedit {
>                         struct tc_skbedit skbedit;
>                         uint16_t queue;
> +                       uint32_t mark;
>                 } skbedit;
> +#ifdef HAVE_BPF_RSS
>                 struct bpf {
>                         struct tc_act_bpf bpf;
> +                       uint32_t map_key;
>                         int bpf_fd;
>                         const char *annotation;
>                 } bpf;
> +#endif
>         };
>  };
>
> @@ -112,13 +108,12 @@ tap_flow_isolate(struct rte_eth_dev *dev,
>                  int set,
>                  struct rte_flow_error *error);
>
> -static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx);
> -static int rss_enable(struct pmd_internals *pmd,
> -                       const struct rte_flow_attr *attr,
> -                       struct rte_flow_error *error);
> +#ifdef HAVE_BPF_RSS
> +static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error
> *error);
>  static int rss_add_actions(struct rte_flow *flow, struct pmd_internals
> *pmd,
>                         const struct rte_flow_action_rss *rss,
>                         struct rte_flow_error *error);
> +#endif
>
>  static const struct rte_flow_ops tap_flow_ops = {
>         .validate = tap_flow_validate,
> @@ -853,11 +848,13 @@ add_action(struct rte_flow *flow, size_t *act_index,
> struct action_data *adata)
>                            &adata->mirred);
>         } else if (strcmp("skbedit", adata->id) == 0) {
>                 tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
> -                          sizeof(adata->skbedit.skbedit),
> -                          &adata->skbedit.skbedit);
> -               tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
> -                            adata->skbedit.queue);
> +                          sizeof(adata->skbedit.skbedit),
> &adata->skbedit.skbedit);
> +               if (adata->skbedit.mark)
> +                       tap_nlattr_add32(&msg->nh, TCA_SKBEDIT_MARK,
> adata->skbedit.mark);
> +               else
> +                       tap_nlattr_add16(&msg->nh,
> TCA_SKBEDIT_QUEUE_MAPPING, adata->skbedit.queue);
>         } else if (strcmp("bpf", adata->id) == 0) {
> +#ifdef HAVE_BPF_RSS
>                 tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD,
> adata->bpf.bpf_fd);
>                 tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
>                            strlen(adata->bpf.annotation) + 1,
> @@ -865,7 +862,12 @@ add_action(struct rte_flow *flow, size_t *act_index,
> struct action_data *adata)
>                 tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS,
>                            sizeof(adata->bpf.bpf),
>                            &adata->bpf.bpf);
> +#else
> +               TAP_LOG(ERR, "Internal error: bpf requested but not
> supported");
> +               return -1;
> +#endif
>         } else {
> +               TAP_LOG(ERR, "Internal error: unknown action: %s",
> adata->id);
>                 return -1;
>         }
>         tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> @@ -1104,8 +1106,7 @@ priv_flow_process(struct pmd_internals *pmd,
>                                         },
>                                 };
>
> -                               err = add_actions(flow, 1, &adata,
> -                                                 TCA_FLOWER_ACT);
> +                               err = add_actions(flow, 1, &adata,
> TCA_FLOWER_ACT);
>                         }
>                 } else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
>                         const struct rte_flow_action_queue *queue =
> @@ -1135,6 +1136,7 @@ priv_flow_process(struct pmd_internals *pmd,
>                                 err = add_actions(flow, 1, &adata,
>                                         TCA_FLOWER_ACT);
>                         }
> +#ifdef HAVE_BPF_RSS
>                 } else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
>                         const struct rte_flow_action_rss *rss =
>                                 (const struct rte_flow_action_rss *)
> @@ -1143,13 +1145,14 @@ priv_flow_process(struct pmd_internals *pmd,
>                         if (action++)
>                                 goto exit_action_not_supported;
>
> -                       if (!pmd->rss_enabled) {
> -                               err = rss_enable(pmd, attr, error);
> +                       if (pmd->rss == NULL) {
> +                               err = rss_enable(pmd, error);
>                                 if (err)
>                                         goto exit_return_error;
>                         }
>                         if (flow)
>                                 err = rss_add_actions(flow, pmd, rss,
> error);
> +#endif
>                 } else {
>                         goto exit_action_not_supported;
>                 }
> @@ -1246,26 +1249,17 @@ tap_flow_set_handle(struct rte_flow *flow)
>   *
>   */
>  static void
> -tap_flow_free(struct pmd_internals *pmd, struct rte_flow *flow)
> +tap_flow_free(struct pmd_internals *pmd __rte_unused, struct rte_flow
> *flow)
>  {
> -       int i;
> -
>         if (!flow)
>                 return;
>
> -       if (pmd->rss_enabled) {
> -               /* Close flow BPF file descriptors */
> -               for (i = 0; i < SEC_MAX; i++)
> -                       if (flow->bpf_fd[i] != 0) {
> -                               close(flow->bpf_fd[i]);
> -                               flow->bpf_fd[i] = 0;
> -                       }
> -
> -               /* Release the map key for this RSS rule */
> -               bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx);
> -               flow->key_idx = 0;
> -       }
> -
> +#ifdef HAVE_BPF_RSS
> +       struct tap_rss *rss = pmd->rss;
> +       if (rss)
> +               bpf_map__delete_elem(rss->maps.rss_map,
> +                                    &flow->msg.t.tcm_handle,
> sizeof(uint32_t), 0);
> +#endif
>         /* Free flow allocated memory */
>         rte_free(flow);
>  }
> @@ -1733,14 +1727,18 @@ tap_flow_implicit_flush(struct pmd_internals *pmd,
> struct rte_flow_error *error)
>         return 0;
>  }
>
> -#define MAX_RSS_KEYS 256
> -#define KEY_IDX_OFFSET (3 * MAX_RSS_KEYS)
> -#define SEC_NAME_CLS_Q "cls_q"
> -
> -static const char *sec_name[SEC_MAX] = {
> -       [SEC_L3_L4] = "l3_l4",
> -};
> +/**
> + * Cleanup when device is closed
> + */
> +void tap_flow_bpf_destroy(struct pmd_internals *pmd __rte_unused)
> +{
> +#ifdef HAVE_BPF_RSS
> +       tap_rss__destroy(pmd->rss);
> +       pmd->rss = NULL;
> +#endif
> +}
>
> +#ifdef HAVE_BPF_RSS
>  /**
>   * Enable RSS on tap: create TC rules for queuing.
>   *
> @@ -1755,225 +1753,32 @@ static const char *sec_name[SEC_MAX] = {
>   *
>   * @return 0 on success, negative value on failure.
>   */
> -static int rss_enable(struct pmd_internals *pmd,
> -                       const struct rte_flow_attr *attr,
> -                       struct rte_flow_error *error)
> +static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error
> *error)
>  {
> -       struct rte_flow *rss_flow = NULL;
> -       struct nlmsg *msg = NULL;
> -       /* 4096 is the maximum number of instructions for a BPF program */
> -       char annotation[64];
> -       int i;
> -       int err = 0;
> -
> -       /* unlimit locked memory */
> -       struct rlimit memlock_limit = {
> -               .rlim_cur = RLIM_INFINITY,
> -               .rlim_max = RLIM_INFINITY,
> -       };
> -       setrlimit(RLIMIT_MEMLOCK, &memlock_limit);
> -
> -        /* Get a new map key for a new RSS rule */
> -       err = bpf_rss_key(KEY_CMD_INIT, NULL);
> -       if (err < 0) {
> -               rte_flow_error_set(
> -                       error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> -                       "Failed to initialize BPF RSS keys");
> -
> -               return -1;
> -       }
> -
> -       /*
> -        *  Create BPF RSS MAP
> -        */
> -       pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key
> size */
> -                               sizeof(struct rss_key),
> -                               MAX_RSS_KEYS);
> -       if (pmd->map_fd < 0) {
> -               TAP_LOG(ERR,
> -                       "Failed to create BPF map (%d): %s",
> -                               errno, strerror(errno));
> -               rte_flow_error_set(
> -                       error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> -                       "Kernel too old or not configured "
> -                       "to support BPF maps");
> -
> -               return -ENOTSUP;
> -       }
> -
> -       /*
> -        * Add a rule per queue to match reclassified packets and direct
> them to
> -        * the correct queue.
> -        */
> -       for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
> -               pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i);
> -               if (pmd->bpf_fd[i] < 0) {
> -                       TAP_LOG(ERR,
> -                               "Failed to load BPF section %s for queue
> %d",
> -                               SEC_NAME_CLS_Q, i);
> -                       rte_flow_error_set(
> -                               error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE,
> -                               NULL,
> -                               "Kernel too old or not configured "
> -                               "to support BPF programs loading");
> -
> -                       return -ENOTSUP;
> -               }
> -
> -               rss_flow = rte_zmalloc(__func__, sizeof(struct rte_flow),
> 0);
> -               if (!rss_flow) {
> -                       TAP_LOG(ERR,
> -                               "Cannot allocate memory for rte_flow");
> -                       return -1;
> -               }
> -               msg = &rss_flow->msg;
> -               tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER,
> NLM_F_REQUEST |
> -                           NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
> -               msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL));
> -               tap_flow_set_handle(rss_flow);
> -               uint16_t group = attr->group << GROUP_SHIFT;
> -               uint16_t prio = group | (i + PRIORITY_OFFSET);
> -               msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info);
> -               msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
> -
> -               tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
> -               if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0)
> -                       return -1;
> -               tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]);
> -               snprintf(annotation, sizeof(annotation), "[%s%d]",
> -                       SEC_NAME_CLS_Q, i);
> -               tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation)
> + 1,
> -                          annotation);
> -               /* Actions */
> -               {
> -                       struct action_data adata = {
> -                               .id = "skbedit",
> -                               .skbedit = {
> -                                       .skbedit = {
> -                                               .action = TC_ACT_PIPE,
> -                                       },
> -                                       .queue = i,
> -                               },
> -                       };
> -                       if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT)
> < 0)
> -                               return -1;
> -               }
> -               tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
> +       int err;
>
> -               /* Netlink message is now ready to be sent */
> -               if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0)
> -                       return -1;
> -               err = tap_nl_recv_ack(pmd->nlsk_fd);
> -               if (err < 0) {
> -                       TAP_LOG(ERR,
> -                               "Kernel refused TC filter rule creation
> (%d): %s",
> -                               errno, strerror(errno));
> -                       return err;
> -               }
> +       /* Load the BPF program (defined in tap_bpf.h from skeleton) */
> +       pmd->rss = tap_rss__open_and_load();
> +       if (pmd->rss == NULL) {
> +               TAP_LOG(ERR, "Failed to load BPF object: %s",
> strerror(errno));
> +               rte_flow_error_set(error, errno,
> RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +                       "BPF object could not be loaded");
> +               return -errno;
>         }
>
> -       pmd->rss_enabled = 1;
> -       return err;
> -}
> -
> -/**
> - * Manage bpf RSS keys repository with operations: init, get, release
> - *
> - * @param[in] cmd
> - *   Command on RSS keys: init, get, release
> - *
> - * @param[in, out] key_idx
> - *   Pointer to RSS Key index (out for get command, in for release
> command)
> - *
> - * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise.
> - */
> -static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx)
> -{
> -       __u32 i;
> -       int err = 0;
> -       static __u32 num_used_keys;
> -       static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC};
> -       static __u32 rss_keys_initialized;
> -       __u32 key;
> -
> -       switch (cmd) {
> -       case KEY_CMD_GET:
> -               if (!rss_keys_initialized) {
> -                       err = -1;
> -                       break;
> -               }
> -
> -               if (num_used_keys == RTE_DIM(rss_keys)) {
> -                       err = -1;
> -                       break;
> -               }
> -
> -               *key_idx = num_used_keys % RTE_DIM(rss_keys);
> -               while (rss_keys[*key_idx] == KEY_STAT_USED)
> -                       *key_idx = (*key_idx + 1) % RTE_DIM(rss_keys);
> -
> -               rss_keys[*key_idx] = KEY_STAT_USED;
> -
> -               /*
> -                * Add an offset to key_idx in order to handle a case of
> -                * RSS and non RSS flows mixture.
> -                * If a non RSS flow is destroyed it has an eBPF map
> -                * index 0 (initialized on flow creation) and might
> -                * unintentionally remove RSS entry 0 from eBPF map.
> -                * To avoid this issue, add an offset to the real index
> -                * during a KEY_CMD_GET operation and subtract this offset
> -                * during a KEY_CMD_RELEASE operation in order to restore
> -                * the real index.
> -                */
> -               *key_idx += KEY_IDX_OFFSET;
> -               num_used_keys++;
> -       break;
> -
> -       case KEY_CMD_RELEASE:
> -               if (!rss_keys_initialized)
> -                       break;
> -
> -               /*
> -                * Subtract offset to restore real key index
> -                * If a non RSS flow is falsely trying to release map
> -                * entry 0 - the offset subtraction will calculate the real
> -                * map index as an out-of-range value and the release
> operation
> -                * will be silently ignored.
> -                */
> -               key = *key_idx - KEY_IDX_OFFSET;
> -               if (key >= RTE_DIM(rss_keys))
> -                       break;
> -
> -               if (rss_keys[key] == KEY_STAT_USED) {
> -                       rss_keys[key] = KEY_STAT_AVAILABLE;
> -                       num_used_keys--;
> -               }
> -       break;
> -
> -       case KEY_CMD_INIT:
> -               for (i = 0; i < RTE_DIM(rss_keys); i++)
> -                       rss_keys[i] = KEY_STAT_AVAILABLE;
> -
> -               rss_keys_initialized = 1;
> -               num_used_keys = 0;
> -       break;
> -
> -       case KEY_CMD_DEINIT:
> -               for (i = 0; i < RTE_DIM(rss_keys); i++)
> -                       rss_keys[i] = KEY_STAT_UNSPEC;
> -
> -               rss_keys_initialized = 0;
> -               num_used_keys = 0;
> -       break;
> -
> -       default:
> -               break;
> +       /* Attach the maps defined in BPF program */
> +       err = tap_rss__attach(pmd->rss);
> +       if (err < 0) {
> +               TAP_LOG(ERR, "Failed to attach BPF object: %d", err);
> +               rte_flow_error_set(error, -err,
> RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> +                       "BPF object could not be attached");
> +               tap_flow_bpf_destroy(pmd);
> +               return err;
>         }
>
> -       return err;
> +       return 0;
>  }
>
> -
>  /* Default RSS hash key also used by mlx devices */
>  static const uint8_t rss_hash_default_key[] = {
>         0x2c, 0xc6, 0x81, 0xd1,
> @@ -2006,9 +1811,11 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>                            const struct rte_flow_action_rss *rss,
>                            struct rte_flow_error *error)
>  {
> +       const struct bpf_program *rss_prog =
> pmd->rss->progs.rss_flow_action;
>         struct rss_key rss_entry = { };
>         const uint8_t *key_in;
>         uint32_t hash_type = 0;
> +       uint32_t handle = flow->msg.t.tcm_handle;
>         unsigned int i;
>         int err;
>
> @@ -2067,34 +1874,24 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>         else if (rss->types & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 |
> RTE_ETH_RSS_IPV6_EX))
>                 hash_type |= RTE_BIT32(HASH_FIELD_IPV6_L3);
>
> -       /* Get a new map key for a new RSS rule */
> -       err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx);
> -       if (err < 0) {
> -               rte_flow_error_set(
> -                       error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> -                       "Failed to get BPF RSS key");
> -
> -               return -1;
> -       }
> +       rss_entry.hash_fields = hash_type;
> +       rte_convert_rss_key((const uint32_t *)key_in, (uint32_t
> *)rss_entry.key,
> +                           TAP_RSS_HASH_KEY_SIZE);
>
>         /* Update RSS map entry with queues */
>         rss_entry.nb_queues = rss->queue_num;
>         for (i = 0; i < rss->queue_num; i++)
>                 rss_entry.queues[i] = rss->queue[i];
>
> -       rss_entry.hash_fields = hash_type;
> -       rte_convert_rss_key((const uint32_t *)key_in, (uint32_t
> *)rss_entry.key,
> -                           TAP_RSS_HASH_KEY_SIZE);
> -
> -
> -       /* Add this RSS entry to map */
> -       err = tap_flow_bpf_update_rss_elem(pmd->map_fd,
> -                               &flow->key_idx, &rss_entry);
>
> +       /* Add this way for BPF to find  entry in map */
> +       err = bpf_map__update_elem(pmd->rss->maps.rss_map,
> +                                  &handle, sizeof(handle),
> +                                  &rss_entry, sizeof(rss_entry), 0);
>         if (err) {
>                 TAP_LOG(ERR,
> -                       "Failed to update BPF map entry #%u (%d): %s",
> -                       flow->key_idx, errno, strerror(errno));
> +                       "Failed to update BPF map entry %#x (%d): %s",
> +                       handle,  errno, strerror(errno));
>                 rte_flow_error_set(
>                         error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
>                         "Kernel too old or not configured "
> @@ -2103,47 +1900,28 @@ static int rss_add_actions(struct rte_flow *flow,
> struct pmd_internals *pmd,
>                 return -ENOTSUP;
>         }
>
> -
> -       /*
> -        * Load bpf rules to calculate hash for this key_idx
> -        */
> -
> -       flow->bpf_fd[SEC_L3_L4] =
> -               tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd);
> -       if (flow->bpf_fd[SEC_L3_L4] < 0) {
> -               TAP_LOG(ERR,
> -                       "Failed to load BPF section %s (%d): %s",
> -                               sec_name[SEC_L3_L4], errno,
> strerror(errno));
> -               rte_flow_error_set(
> -                       error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
> -                       "Kernel too old or not configured "
> -                       "to support BPF program loading");
> -
> -               return -ENOTSUP;
> -       }
> -
> -       /* Actions */
> -       {
> -               struct action_data adata[] = {
> -                       {
> -                               .id = "bpf",
> -                               .bpf = {
> -                                       .bpf_fd = flow->bpf_fd[SEC_L3_L4],
> -                                       .annotation = sec_name[SEC_L3_L4],
> -                                       .bpf = {
> -                                               .action = TC_ACT_PIPE,
> -                                       },
> -                               },
> +       /* Add actions to mark packet then run the RSS BPF program */
> +       struct action_data adata[] = {
> +               {
> +                       .id = "skbedit",
> +                       .skbedit = {
> +                               .skbedit.action = TC_ACT_PIPE,
> +                               .mark = handle,
>                         },
> -               };
> -
> -               if (add_actions(flow, RTE_DIM(adata), adata,
> -                       TCA_FLOWER_ACT) < 0)
> -                       return -1;
> -       }
> +               },
> +               {
> +                       .id = "bpf",
> +                       .bpf = {
> +                               .bpf.action = TC_ACT_PIPE,
> +                               .annotation = "tap_rss",
> +                               .bpf_fd = bpf_program__fd(rss_prog),
> +                       },
> +               },
> +       };
>
> -       return 0;
> +       return add_actions(flow, RTE_DIM(adata), adata, TCA_FLOWER_ACT);
>  }
> +#endif
>
>  /**
>   * Get rte_flow operations.
> diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h
> index 240fbc3dfa..8b19347a93 100644
> --- a/drivers/net/tap/tap_flow.h
> +++ b/drivers/net/tap/tap_flow.h
> @@ -9,7 +9,11 @@
>  #include <rte_flow.h>
>  #include <rte_flow_driver.h>
>  #include <rte_eth_tap.h>
> -#include <tap_autoconf.h>
> +
> +/**
> + * Mask of unsupported RSS types
> + */
> +#define TAP_RSS_HF_MASK (~(RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP |
> RTE_ETH_RSS_TCP))
>
>  /**
>   * In TC, priority 0 means we require the kernel to allocate one for us.
> @@ -41,11 +45,6 @@ enum implicit_rule_index {
>         TAP_REMOTE_MAX_IDX,
>  };
>
> -enum bpf_fd_idx {
> -       SEC_L3_L4,
> -       SEC_MAX,
> -};
> -
>  int tap_dev_flow_ops_get(struct rte_eth_dev *dev,
>                          const struct rte_flow_ops **ops);
>  int tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error);
> @@ -57,10 +56,6 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
>  int tap_flow_implicit_flush(struct pmd_internals *pmd,
>                             struct rte_flow_error *error);
>
> -int tap_flow_bpf_cls_q(__u32 queue_idx);
> -int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd);
> -int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int
> value_size,
> -                       unsigned int max_entries);
> -int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value);
> +void tap_flow_bpf_destroy(struct pmd_internals *pmd);
>
>  #endif /* _TAP_FLOW_H_ */
> diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h
> index 6009be7031..65bd8991b1 100644
> --- a/drivers/net/tap/tap_rss.h
> +++ b/drivers/net/tap/tap_rss.h
> @@ -5,16 +5,14 @@
>  #ifndef _TAP_RSS_H_
>  #define _TAP_RSS_H_
>
> -#ifndef TAP_MAX_QUEUES
> -#define TAP_MAX_QUEUES 16
> +/* Size of the map from BPF classid to queue table */
> +#ifndef TAP_RSS_MAX
> +#define TAP_RSS_MAX    32
>  #endif
>
> -/* Fixed RSS hash key size in bytes. */
> +/* Standard Toeplitz hash key size */
>  #define TAP_RSS_HASH_KEY_SIZE 40
>
> -/* Supported RSS */
> -#define TAP_RSS_HF_MASK (~(RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP |
> RTE_ETH_RSS_TCP))
> -
>  /* hashed fields for RSS */
>  enum hash_field {
>         HASH_FIELD_IPV4_L3,     /* IPv4 src/dst addr */
> diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h
> index a64cb29d6f..9411626661 100644
> --- a/drivers/net/tap/tap_tcmsgs.h
> +++ b/drivers/net/tap/tap_tcmsgs.h
> @@ -6,7 +6,6 @@
>  #ifndef _TAP_TCMSGS_H_
>  #define _TAP_TCMSGS_H_
>
> -#include <tap_autoconf.h>
>  #include <linux/if_ether.h>
>  #include <linux/rtnetlink.h>
>  #include <linux/pkt_sched.h>
> @@ -14,9 +13,10 @@
>  #include <linux/tc_act/tc_mirred.h>
>  #include <linux/tc_act/tc_gact.h>
>  #include <linux/tc_act/tc_skbedit.h>
> -#ifdef HAVE_TC_ACT_BPF
> +#ifdef HAVE_BPF_RSS
>  #include <linux/tc_act/tc_bpf.h>
>  #endif
> +
>  #include <inttypes.h>
>
>  #include <rte_ether.h>
> --
> 2.43.0
>
>

[-- Attachment #2: Type: text/html, Size: 45410 bytes --]

  reply	other threads:[~2024-05-28 16:33 UTC|newest]

Thread overview: 206+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-30  3:46 [RFC 0/2] net/tap RSS BPF rewrite Stephen Hemminger
2024-01-30  3:46 ` [RFC 1/2] tap: stop "vendoring" linux bpf headers Stephen Hemminger
2024-01-30  3:46 ` [RFC 2/2] tap: rework BPF handling Stephen Hemminger
2024-02-07 22:11 ` [PATCH v2 0/7] net/tap: RSS using BPF overhaul Stephen Hemminger
2024-02-07 22:11   ` [PATCH v2 1/7] net/tap: remove unused RSS hash types Stephen Hemminger
2024-02-07 22:11   ` [PATCH v2 2/7] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-02-07 22:11   ` [PATCH v2 3/7] net/tap: stop "vendoring" linux bpf headers Stephen Hemminger
2024-02-07 22:11   ` [PATCH v2 4/7] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-02-07 22:11   ` [PATCH v2 5/7] net/tap: use libbpf to load new " Stephen Hemminger
2024-02-07 22:11   ` [PATCH v2 6/7] net/tap: remove no longer used files Stephen Hemminger
2024-02-07 22:11   ` [PATCH v2 7/7] MAINTAINERS: add maintainer for TAP device Stephen Hemminger
2024-02-08  7:01     ` Morten Brørup
2024-02-08 17:41 ` [PATCH v3 0/7] net/tap: RSS using BPF overhaul Stephen Hemminger
2024-02-08 17:41   ` [PATCH v3 1/7] net/tap: remove unused RSS hash types Stephen Hemminger
2024-02-08 17:41   ` [PATCH v3 2/7] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-02-08 17:41   ` [PATCH v3 3/7] tap: stop "vendoring" linux bpf headers Stephen Hemminger
2024-02-08 17:41   ` [PATCH v3 4/7] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-02-08 17:41   ` [PATCH v3 5/7] net/tap: use libbpf to load new " Stephen Hemminger
2024-02-08 18:02     ` Stephen Hemminger
2024-02-08 17:41   ` [PATCH v3 6/7] net/tap: remove no longer used files Stephen Hemminger
2024-02-08 17:41   ` [PATCH v3 7/7] MAINTAINERS: add maintainer for TAP device Stephen Hemminger
2024-02-08 19:05 ` [PATCH v4 0/7] net/tap: queue flow action RSS using BPF redo Stephen Hemminger
2024-02-08 19:05   ` [PATCH v4 1/7] net/tap: remove unused RSS hash types Stephen Hemminger
2024-02-08 19:05   ` [PATCH v4 2/7] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-02-08 19:05   ` [PATCH v4 3/7] tap: stop "vendoring" linux bpf headers Stephen Hemminger
2024-02-08 19:05   ` [PATCH v4 4/7] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-02-10  0:54     ` Ferruh Yigit
2024-02-10  2:09       ` Stephen Hemminger
2024-02-28 17:27         ` Ferruh Yigit
2024-02-29 23:39           ` Stephen Hemminger
2024-02-08 19:05   ` [PATCH v4 5/7] net/tap: use libbpf to load new " Stephen Hemminger
2024-02-08 20:39     ` Stephen Hemminger
2024-02-08 19:05   ` [PATCH v4 6/7] net/tap: remove no longer used files Stephen Hemminger
2024-02-08 19:05   ` [PATCH v4 7/7] MAINTAINERS: add maintainer for TAP device Stephen Hemminger
2024-02-12 16:47   ` [PATCH v4 0/7] net/tap: queue flow action RSS using BPF redo Stephen Hemminger
2024-04-02 17:12 ` [PATCH v5 0/8] net/tap: cleanups and fix BPF flow Stephen Hemminger
2024-04-02 17:12   ` [PATCH v5 1/8] net/tap: do not duplicate fd's Stephen Hemminger
2024-04-02 17:12   ` [PATCH v5 2/8] doc: fix the requirements and building of TAP flow Stephen Hemminger
2024-04-02 17:12   ` [PATCH v5 3/8] net/tap: remove unused RSS hash types Stephen Hemminger
2024-04-02 17:12   ` [PATCH v5 4/8] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-04-02 17:12   ` [PATCH v5 5/8] net/tap: stop "vendoring" linux bpf headers Stephen Hemminger
2024-04-02 17:12   ` [PATCH v5 6/8] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-04-02 17:12   ` [PATCH v5 7/8] net/tap: use libbpf to load new " Stephen Hemminger
2024-04-03 11:50     ` Luca Boccassi
2024-04-03 14:53       ` Stephen Hemminger
2024-04-03 15:55       ` Stephen Hemminger
2024-04-03 21:19         ` Luca Boccassi
2024-04-03 23:41           ` Stephen Hemminger
2024-04-04  0:49             ` Luca Boccassi
2024-04-04 15:51               ` Stephen Hemminger
2024-04-04 16:12                 ` Luca Boccassi
2024-04-04 15:30           ` Stephen Hemminger
2024-04-04 16:11             ` Luca Boccassi
2024-04-02 17:12   ` [PATCH v5 8/8] net/tap: remove no longer used files Stephen Hemminger
2024-04-02 20:43     ` Stephen Hemminger
2024-04-05 21:14 ` [PATCH v6 0/8] net/tap: cleanup and fix BPF flow support Stephen Hemminger
2024-04-05 21:14   ` [PATCH v6 1/8] net/tap: do not duplicate fd's Stephen Hemminger
2024-04-05 21:14   ` [PATCH v6 2/8] doc: fix the requirements and building of TAP flow Stephen Hemminger
2024-04-05 21:14   ` [PATCH v6 3/8] net/tap: remove unused fields Stephen Hemminger
2024-04-05 21:14   ` [PATCH v6 4/8] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-04-05 21:14   ` [PATCH v6 5/8] net/tap: stop "vendoring" linux bpf headers Stephen Hemminger
2024-04-05 21:14   ` [PATCH v6 6/8] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-04-05 21:14   ` [PATCH v6 7/8] net/tap: use libbpf to load new " Stephen Hemminger
2024-04-05 21:15   ` [PATCH v6 8/8] net/tap: remove no longer used files Stephen Hemminger
2024-04-08 21:18 ` [PATCH v7 0/8] net/tap: cleanups and fix BPF support Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 1/8] net/tap: do not duplicate fd's Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 2/8] net/tap: remove unused fields Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 3/8] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 4/8] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 5/8] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 6/8] net/tap: use libbpf to load new " Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 7/8] net/tap: remove no longer used files Stephen Hemminger
2024-04-08 21:18   ` [PATCH v7 8/8] doc: update documentation of TAP PMD Stephen Hemminger
2024-04-09  3:40 ` [PATCH v8 0/8] net/tap: cleanups and fix BPF support Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 1/8] net/tap: do not duplicate fd's Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 2/8] net/tap: remove unused fields Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 3/8] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 4/8] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 5/8] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 6/8] net/tap: use libbpf to load new " Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 7/8] net/tap: remove no longer used files Stephen Hemminger
2024-04-09  3:40   ` [PATCH v8 8/8] doc: update documentation of TAP PMD Stephen Hemminger
2024-04-26 15:48 ` [PATCH v9 0/9] net/tap: fix RSS (BPF) support Stephen Hemminger
2024-04-26 15:48   ` [PATCH v9 1/9] net/tap: do not duplicate fd's Stephen Hemminger
2024-05-01 11:13     ` Ferruh Yigit
2024-05-01 23:53       ` Stephen Hemminger
2024-05-02 14:51         ` Ferruh Yigit
2024-05-02 16:22           ` Stephen Hemminger
2024-04-26 15:48   ` [PATCH v9 2/9] net/tap: remove unused fields Stephen Hemminger
2024-04-26 15:48   ` [PATCH v9 3/9] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-04-26 15:48   ` [PATCH v9 4/9] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-04-26 15:48   ` [PATCH v9 5/9] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-05-01 11:14     ` Ferruh Yigit
2024-04-26 15:48   ` [PATCH v9 6/9] net/tap: use libbpf to load new " Stephen Hemminger
2024-04-26 15:48   ` [PATCH v9 7/9] net/tap: remove no longer used files Stephen Hemminger
2024-04-26 15:48   ` [PATCH v9 8/9] doc: update documentation of TAP PMD Stephen Hemminger
2024-05-01 12:36     ` Ferruh Yigit
2024-04-26 15:48   ` [PATCH v9 9/9] net/tap: simplify the internal structure Stephen Hemminger
2024-05-01 11:18   ` [PATCH v9 0/9] net/tap: fix RSS (BPF) support Ferruh Yigit
2024-05-01 15:41     ` Stephen Hemminger
2024-05-01 16:11 ` [PATCH v10 0/9] net/tap: fix RSS (BPF) flow support Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 1/9] net/tap: do not duplicate fd's Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 2/9] net/tap: remove unused fields Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 3/9] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 4/9] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 5/9] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 6/9] net/tap: use libbpf to load new " Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 7/9] net/tap: remove no longer used files Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 8/9] net/tap: simplify internals Stephen Hemminger
2024-05-01 16:12   ` [PATCH v10 9/9] net/tap: update documentation Stephen Hemminger
2024-05-02  2:49 ` [PATCH v11 0/9] net/tap fix RSS (BPF) flow support Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 1/9] net/tap: do not duplicate fd's Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 2/9] net/tap: remove unused fields Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 3/9] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 4/9] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 5/9] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 6/9] net/tap: use libbpf to load new " Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 7/9] net/tap: remove no longer used files Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 8/9] net/tap: simplify internals Stephen Hemminger
2024-05-02  2:49   ` [PATCH v11 9/9] net/tap: update documentation Stephen Hemminger
2024-05-02 21:31 ` [PATCH v12 00/12] net/tap: RSS and other fixes Stephen Hemminger
2024-05-02 21:31   ` [PATCH v12 01/12] net/tap: fix fd check in flow_isolate Stephen Hemminger
2024-05-20 17:46     ` Ferruh Yigit
2024-05-02 21:31   ` [PATCH v12 02/12] net/tap: do not duplicate fd's Stephen Hemminger
2024-05-20 17:46     ` Ferruh Yigit
2024-05-20 18:16       ` Stephen Hemminger
2024-05-02 21:31   ` [PATCH v12 03/12] net/tap: remove unused fields Stephen Hemminger
2024-05-20 17:46     ` Ferruh Yigit
2024-05-02 21:31   ` [PATCH v12 04/12] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-05-20 17:47     ` Ferruh Yigit
2024-05-21  2:01       ` Stephen Hemminger
2024-05-21 14:17         ` Ferruh Yigit
2024-05-02 21:31   ` [PATCH v12 05/12] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-05-20 17:47     ` Ferruh Yigit
2024-05-02 21:31   ` [PATCH v12 06/12] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-05-02 21:31   ` [PATCH v12 07/12] net/tap: use libbpf to load new " Stephen Hemminger
2024-05-20 17:49     ` Ferruh Yigit
2024-05-20 18:18       ` Stephen Hemminger
2024-05-20 21:42         ` Luca Boccassi
2024-05-20 22:08           ` Ferruh Yigit
2024-05-20 22:25             ` Luca Boccassi
2024-05-20 23:20             ` Stephen Hemminger
2024-05-20 22:06         ` Ferruh Yigit
2024-05-21  4:23       ` Patrick Robb
2024-05-21 13:46         ` Ferruh Yigit
2024-05-21 14:33           ` Patrick Robb
2024-05-21 15:06           ` Aaron Conole
2024-05-21 15:41             ` Stephen Hemminger
2024-05-02 21:31   ` [PATCH v12 08/12] net/tap: remove no longer used files Stephen Hemminger
2024-05-20 17:50     ` Ferruh Yigit
2024-05-02 21:31   ` [PATCH v12 09/12] net/tap: simplify internals Stephen Hemminger
2024-05-20 17:51     ` Ferruh Yigit
2024-05-21 15:44       ` Stephen Hemminger
2024-05-22 14:00         ` Ferruh Yigit
2024-05-02 21:31   ` [PATCH v12 10/12] net/tap: remove extraneous newlines Stephen Hemminger
2024-05-20 17:51     ` Ferruh Yigit
2024-05-02 21:31   ` [PATCH v12 11/12] net/tap: do not mark queue full as error Stephen Hemminger
2024-05-20 17:52     ` Ferruh Yigit
2024-05-21 15:46       ` Stephen Hemminger
2024-05-02 21:31   ` [PATCH v12 12/12] net/tap: update documentation Stephen Hemminger
2024-05-20 17:53     ` Ferruh Yigit
2024-05-21  2:39       ` Stephen Hemminger
2024-05-21  2:47 ` [PATCH v13 00/11] net/tap: make RSS work again Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 01/11] net/tap: fix fd check in flow_isolate Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 02/11] net/tap: do not duplicate fd's Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 03/11] net/tap: remove unused fields Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 04/11] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 05/11] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 06/11] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 07/11] net/tap: use libbpf to load new " Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 08/11] net/tap: remove no longer used files Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 09/11] net/tap: simplify internals Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 10/11] net/tap: remove extraneous newlines Stephen Hemminger
2024-05-21  2:47   ` [PATCH v13 11/11] net/tap: update documentation Stephen Hemminger
2024-05-21 14:19   ` [PATCH v13 00/11] net/tap: make RSS work again Ferruh Yigit
2024-05-21 14:35     ` Ferruh Yigit
2024-05-21 14:38       ` Ferruh Yigit
2024-05-21 21:23         ` Patrick Robb
2024-05-21 21:26           ` Ferruh Yigit
2024-05-21 17:06 ` [PATCH v14 " Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 01/11] net/tap: fix fd check in flow_isolate Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 02/11] net/tap: do not duplicate fd's Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 03/11] net/tap: remove unused fields Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 04/11] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 05/11] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 06/11] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 07/11] net/tap: use libbpf to load new " Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 08/11] net/tap: remove no longer used files Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 09/11] net/tap: simplify internals Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 10/11] net/tap: remove extraneous newlines Stephen Hemminger
2024-05-21 17:06   ` [PATCH v14 11/11] net/tap: update documentation Stephen Hemminger
2024-05-21 20:12 ` [PATCH v15 00/11] net/tap: make RSS work again Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 01/11] net/tap: fix fd check in flow_isolate Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 02/11] net/tap: do not duplicate fd's Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 03/11] net/tap: remove unused fields Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 04/11] net/tap: validate and setup parameters for BPF RSS Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 05/11] net/tap: do not build flow support if header is out of date Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 06/11] net/tap: rewrite the RSS BPF program Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 07/11] net/tap: use libbpf to load new " Stephen Hemminger
2024-05-28 16:33     ` Cody Cheng [this message]
2024-05-21 20:12   ` [PATCH v15 08/11] net/tap: remove no longer used files Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 09/11] net/tap: simplify internals Stephen Hemminger
2024-05-22 16:15     ` Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 10/11] net/tap: remove extraneous newlines Stephen Hemminger
2024-05-21 20:12   ` [PATCH v15 11/11] net/tap: update documentation Stephen Hemminger
2024-05-22 15:42   ` [PATCH v15 00/11] net/tap: make RSS work again Ferruh Yigit

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='CAMEVEZs15wA+EigtHhAMfxn2VBg=4j1Mke+oStdtFx4u3iGDcw@mail.gmail.com' \
    --to=ccheng@iol.unh.edu \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=stephen@networkplumber.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).