lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CALx6S37gn4mQx97xXUPpjW4Fm9NxOwfagunhygHrvaGS5Uxs4w@mail.gmail.com>
Date:   Sat, 27 Jun 2020 15:34:57 -0700
From:   Tom Herbert <tom@...bertland.com>
To:     Saeed Mahameed <saeedm@...lanox.com>
Cc:     "David S. Miller" <davem@...emloft.net>, kuba@...nel.org,
        Linux Kernel Network Developers <netdev@...r.kernel.org>,
        Boris Pismenny <borisp@...lanox.com>,
        Tariq Toukan <tariqt@...lanox.com>
Subject: Re: [net-next 04/15] net/mlx5e: Receive flow steering framework for
 accelerated TCP flows

On Sat, Jun 27, 2020 at 2:19 PM Saeed Mahameed <saeedm@...lanox.com> wrote:
>
> From: Boris Pismenny <borisp@...lanox.com>
>
> The framework allows creating flow tables to steer incoming traffic of
> TCP sockets to the acceleration TIRs.
> This is used in downstream patches for TLS, and will be used in the
> future for other offloads.
>
> Signed-off-by: Boris Pismenny <borisp@...lanox.com>
> Signed-off-by: Tariq Toukan <tariqt@...lanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@...lanox.com>
> ---
>  .../net/ethernet/mellanox/mlx5/core/Makefile  |   2 +-
>  .../net/ethernet/mellanox/mlx5/core/en/fs.h   |  10 +
>  .../mellanox/mlx5/core/en_accel/fs_tcp.c      | 280 ++++++++++++++++++
>  .../mellanox/mlx5/core/en_accel/fs_tcp.h      |  18 ++
>  .../net/ethernet/mellanox/mlx5/core/fs_core.c |   4 +-

Saeed,

What is the relationship between this and RFS, accelerated RFS, and
now PTQ? Is this something that we can generalize in the stack and
support in the driver/device with a simple interface like we do with
aRFS and ndo_rx_flow_steer?

Tom

>  5 files changed, 311 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
>  create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
> index b61e47bc16e8..8ffa1325a18f 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
> @@ -74,7 +74,7 @@ mlx5_core-$(CONFIG_MLX5_EN_IPSEC) += en_accel/ipsec.o en_accel/ipsec_rxtx.o \
>                                      en_accel/ipsec_stats.o
>
>  mlx5_core-$(CONFIG_MLX5_EN_TLS) += en_accel/tls.o en_accel/tls_rxtx.o en_accel/tls_stats.o \
> -                                  en_accel/ktls.o en_accel/ktls_tx.o
> +                                  en_accel/ktls.o en_accel/ktls_tx.o en_accel/fs_tcp.o
>
>  mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o \
>                                         steering/dr_matcher.o steering/dr_rule.o \
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
> index c633579474c3..385cbff1caf1 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
> @@ -123,6 +123,9 @@ enum {
>         MLX5E_L2_FT_LEVEL,
>         MLX5E_TTC_FT_LEVEL,
>         MLX5E_INNER_TTC_FT_LEVEL,
> +#ifdef CONFIG_MLX5_EN_TLS
> +       MLX5E_ACCEL_FS_TCP_FT_LEVEL,
> +#endif
>  #ifdef CONFIG_MLX5_EN_ARFS
>         MLX5E_ARFS_FT_LEVEL
>  #endif
> @@ -216,6 +219,10 @@ static inline int mlx5e_arfs_enable(struct mlx5e_priv *priv) { return -EOPNOTSUP
>  static inline int mlx5e_arfs_disable(struct mlx5e_priv *priv) {        return -EOPNOTSUPP; }
>  #endif
>
> +#ifdef CONFIG_MLX5_EN_TLS
> +struct mlx5e_accel_fs_tcp;
> +#endif
> +
>  struct mlx5e_flow_steering {
>         struct mlx5_flow_namespace      *ns;
>  #ifdef CONFIG_MLX5_EN_RXNFC
> @@ -229,6 +236,9 @@ struct mlx5e_flow_steering {
>  #ifdef CONFIG_MLX5_EN_ARFS
>         struct mlx5e_arfs_tables        arfs;
>  #endif
> +#ifdef CONFIG_MLX5_EN_TLS
> +       struct mlx5e_accel_fs_tcp      *accel_tcp;
> +#endif
>  };
>
>  struct ttc_params {
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
> new file mode 100644
> index 000000000000..a0e9082e15b0
> --- /dev/null
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c
> @@ -0,0 +1,280 @@
> +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
> +/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
> +
> +#include <linux/netdevice.h>
> +#include "en_accel/fs_tcp.h"
> +#include "fs_core.h"
> +
> +enum accel_fs_tcp_type {
> +       ACCEL_FS_IPV4_TCP,
> +       ACCEL_FS_IPV6_TCP,
> +       ACCEL_FS_TCP_NUM_TYPES,
> +};
> +
> +struct mlx5e_accel_fs_tcp {
> +       struct mlx5e_flow_table tables[ACCEL_FS_TCP_NUM_TYPES];
> +       struct mlx5_flow_handle *default_rules[ACCEL_FS_TCP_NUM_TYPES];
> +};
> +
> +static enum mlx5e_traffic_types fs_accel2tt(enum accel_fs_tcp_type i)
> +{
> +       switch (i) {
> +       case ACCEL_FS_IPV4_TCP:
> +               return MLX5E_TT_IPV4_TCP;
> +       default: /* ACCEL_FS_IPV6_TCP */
> +               return MLX5E_TT_IPV6_TCP;
> +       }
> +}
> +
> +static int accel_fs_tcp_add_default_rule(struct mlx5e_priv *priv,
> +                                        enum accel_fs_tcp_type type)
> +{
> +       struct mlx5e_flow_table *accel_fs_t;
> +       struct mlx5_flow_destination dest;
> +       struct mlx5e_accel_fs_tcp *fs_tcp;
> +       MLX5_DECLARE_FLOW_ACT(flow_act);
> +       struct mlx5_flow_handle *rule;
> +       int err = 0;
> +
> +       fs_tcp = priv->fs.accel_tcp;
> +       accel_fs_t = &fs_tcp->tables[type];
> +
> +       dest = mlx5e_ttc_get_default_dest(priv, fs_accel2tt(type));
> +       rule = mlx5_add_flow_rules(accel_fs_t->t, NULL, &flow_act, &dest, 1);
> +       if (IS_ERR(rule)) {
> +               err = PTR_ERR(rule);
> +               netdev_err(priv->netdev,
> +                          "%s: add default rule failed, accel_fs type=%d, err %d\n",
> +                          __func__, type, err);
> +               return err;
> +       }
> +
> +       fs_tcp->default_rules[type] = rule;
> +       return 0;
> +}
> +
> +#define MLX5E_ACCEL_FS_TCP_NUM_GROUPS  (2)
> +#define MLX5E_ACCEL_FS_TCP_GROUP1_SIZE (BIT(16) - 1)
> +#define MLX5E_ACCEL_FS_TCP_GROUP2_SIZE (BIT(0))
> +#define MLX5E_ACCEL_FS_TCP_TABLE_SIZE  (MLX5E_ACCEL_FS_TCP_GROUP1_SIZE +\
> +                                        MLX5E_ACCEL_FS_TCP_GROUP2_SIZE)
> +static int accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft,
> +                                     enum accel_fs_tcp_type type)
> +{
> +       int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
> +       void *outer_headers_c;
> +       int ix = 0;
> +       u32 *in;
> +       int err;
> +       u8 *mc;
> +
> +       ft->g = kcalloc(MLX5E_ACCEL_FS_TCP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
> +       in = kvzalloc(inlen, GFP_KERNEL);
> +       if  (!in || !ft->g) {
> +               kvfree(ft->g);
> +               kvfree(in);
> +               return -ENOMEM;
> +       }
> +
> +       mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
> +       outer_headers_c = MLX5_ADDR_OF(fte_match_param, mc, outer_headers);
> +       MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol);
> +       MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_version);
> +
> +       switch (type) {
> +       case ACCEL_FS_IPV4_TCP:
> +       case ACCEL_FS_IPV6_TCP:
> +               MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_dport);
> +               MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_sport);
> +               break;
> +       default:
> +               err = -EINVAL;
> +               goto out;
> +       }
> +
> +       switch (type) {
> +       case ACCEL_FS_IPV4_TCP:
> +               MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c,
> +                                src_ipv4_src_ipv6.ipv4_layout.ipv4);
> +               MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c,
> +                                dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
> +               break;
> +       case ACCEL_FS_IPV6_TCP:
> +               memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
> +                                   src_ipv4_src_ipv6.ipv6_layout.ipv6),
> +                      0xff, 16);
> +               memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c,
> +                                   dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
> +                      0xff, 16);
> +               break;
> +       default:
> +               err = -EINVAL;
> +               goto out;
> +       }
> +
> +       MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
> +       MLX5_SET_CFG(in, start_flow_index, ix);
> +       ix += MLX5E_ACCEL_FS_TCP_GROUP1_SIZE;
> +       MLX5_SET_CFG(in, end_flow_index, ix - 1);
> +       ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
> +       if (IS_ERR(ft->g[ft->num_groups]))
> +               goto err;
> +       ft->num_groups++;
> +
> +       /* Default Flow Group */
> +       memset(in, 0, inlen);
> +       MLX5_SET_CFG(in, start_flow_index, ix);
> +       ix += MLX5E_ACCEL_FS_TCP_GROUP2_SIZE;
> +       MLX5_SET_CFG(in, end_flow_index, ix - 1);
> +       ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
> +       if (IS_ERR(ft->g[ft->num_groups]))
> +               goto err;
> +       ft->num_groups++;
> +
> +       kvfree(in);
> +       return 0;
> +
> +err:
> +       err = PTR_ERR(ft->g[ft->num_groups]);
> +       ft->g[ft->num_groups] = NULL;
> +out:
> +       kvfree(in);
> +
> +       return err;
> +}
> +
> +static int accel_fs_tcp_create_table(struct mlx5e_priv *priv, enum accel_fs_tcp_type type)
> +{
> +       struct mlx5e_flow_table *ft = &priv->fs.accel_tcp->tables[type];
> +       struct mlx5_flow_table_attr ft_attr = {};
> +       int err;
> +
> +       ft->num_groups = 0;
> +
> +       ft_attr.max_fte = MLX5E_ACCEL_FS_TCP_TABLE_SIZE;
> +       ft_attr.level = MLX5E_ACCEL_FS_TCP_FT_LEVEL;
> +       ft_attr.prio = MLX5E_NIC_PRIO;
> +
> +       ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
> +       if (IS_ERR(ft->t)) {
> +               err = PTR_ERR(ft->t);
> +               ft->t = NULL;
> +               return err;
> +       }
> +
> +       netdev_dbg(priv->netdev, "Created fs accel table id %u level %u\n",
> +                  ft->t->id, ft->t->level);
> +
> +       err = accel_fs_tcp_create_groups(ft, type);
> +       if (err)
> +               goto err;
> +
> +       err = accel_fs_tcp_add_default_rule(priv, type);
> +       if (err)
> +               goto err;
> +
> +       return 0;
> +err:
> +       mlx5e_destroy_flow_table(ft);
> +       return err;
> +}
> +
> +static int accel_fs_tcp_disable(struct mlx5e_priv *priv)
> +{
> +       int err, i;
> +
> +       for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
> +               /* Modify ttc rules destination to point back to the indir TIRs */
> +               err = mlx5e_ttc_fwd_default_dest(priv, fs_accel2tt(i));
> +               if (err) {
> +                       netdev_err(priv->netdev,
> +                                  "%s: modify ttc[%d] default destination failed, err(%d)\n",
> +                                  __func__, fs_accel2tt(i), err);
> +                       return err;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int accel_fs_tcp_enable(struct mlx5e_priv *priv)
> +{
> +       struct mlx5_flow_destination dest = {};
> +       int err, i;
> +
> +       dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
> +       for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
> +               dest.ft = priv->fs.accel_tcp->tables[i].t;
> +
> +               /* Modify ttc rules destination to point on the accel_fs FTs */
> +               err = mlx5e_ttc_fwd_dest(priv, fs_accel2tt(i), &dest);
> +               if (err) {
> +                       netdev_err(priv->netdev,
> +                                  "%s: modify ttc[%d] destination to accel failed, err(%d)\n",
> +                                  __func__, fs_accel2tt(i), err);
> +                       return err;
> +               }
> +       }
> +       return 0;
> +}
> +
> +static void accel_fs_tcp_destroy_table(struct mlx5e_priv *priv, int i)
> +{
> +       struct mlx5e_accel_fs_tcp *fs_tcp;
> +
> +       fs_tcp = priv->fs.accel_tcp;
> +       if (IS_ERR_OR_NULL(fs_tcp->tables[i].t))
> +               return;
> +
> +       mlx5_del_flow_rules(fs_tcp->default_rules[i]);
> +       mlx5e_destroy_flow_table(&fs_tcp->tables[i]);
> +       fs_tcp->tables[i].t = NULL;
> +}
> +
> +void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv)
> +{
> +       int i;
> +
> +       if (!priv->fs.accel_tcp)
> +               return;
> +
> +       accel_fs_tcp_disable(priv);
> +
> +       for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++)
> +               accel_fs_tcp_destroy_table(priv, i);
> +
> +       kfree(priv->fs.accel_tcp);
> +       priv->fs.accel_tcp = NULL;
> +}
> +
> +int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv)
> +{
> +       int i, err;
> +
> +       if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version))
> +               return -EOPNOTSUPP;
> +
> +       priv->fs.accel_tcp = kzalloc(sizeof(*priv->fs.accel_tcp), GFP_KERNEL);
> +       if (!priv->fs.accel_tcp)
> +               return -ENOMEM;
> +
> +       for (i = 0; i < ACCEL_FS_TCP_NUM_TYPES; i++) {
> +               err = accel_fs_tcp_create_table(priv, i);
> +               if (err)
> +                       goto err_destroy_tables;
> +       }
> +
> +       err = accel_fs_tcp_enable(priv);
> +       if (err)
> +               goto err_destroy_tables;
> +
> +       return 0;
> +
> +err_destroy_tables:
> +       while (--i >= 0)
> +               accel_fs_tcp_destroy_table(priv, i);
> +
> +       kfree(priv->fs.accel_tcp);
> +       priv->fs.accel_tcp = NULL;
> +       return err;
> +}
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h
> new file mode 100644
> index 000000000000..0df53473550a
> --- /dev/null
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
> +/* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
> +
> +#ifndef __MLX5E_ACCEL_FS_TCP_H__
> +#define __MLX5E_ACCEL_FS_TCP_H__
> +
> +#include "en.h"
> +
> +#ifdef CONFIG_MLX5_EN_TLS
> +int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv);
> +void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv);
> +#else
> +static inline int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv) { return 0; }
> +static inline void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv) {}
> +#endif
> +
> +#endif /* __MLX5E_ACCEL_FS_TCP_H__ */
> +
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
> index e47a66983935..785b2960d6b5 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
> @@ -105,8 +105,8 @@
>  #define ETHTOOL_PRIO_NUM_LEVELS 1
>  #define ETHTOOL_NUM_PRIOS 11
>  #define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS)
> -/* Vlan, mac, ttc, inner ttc, aRFS */
> -#define KERNEL_NIC_PRIO_NUM_LEVELS 5
> +/* Vlan, mac, ttc, inner ttc, {aRFS/accel} */
> +#define KERNEL_NIC_PRIO_NUM_LEVELS 6
>  #define KERNEL_NIC_NUM_PRIOS 1
>  /* One more level for tc */
>  #define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 1)
> --
> 2.26.2
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ