net/mlx5: Add support for RDMA TX steering
authorMichael Guralnik <michaelgur@mellanox.com>
Tue, 24 Mar 2020 06:14:24 +0000 (08:14 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 27 Mar 2020 16:24:48 +0000 (13:24 -0300)
Add new RDMA TX flow steering namespace. Flow steering rules in
this namespace are used to filter transmitted RDMA traffic.

Link: https://lore.kernel.org/r/20200324061425.1570190-2-leon@kernel.org
Signed-off-by: Michael Guralnik <michaelgur@mellanox.com>
Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
Reviewed-by: Mark Bloch <markb@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
include/linux/mlx5/device.h
include/linux/mlx5/fs.h
include/linux/mlx5/mlx5_ifc.h

index b25465d9e030f6fa8b9d6af60245dd82b0470389..90048697b2ffdf89f29f9b2814087d31f5953191 100644 (file)
@@ -904,6 +904,7 @@ const struct mlx5_flow_cmds *mlx5_fs_cmd_get_default(enum fs_flow_table_type typ
        case FS_FT_SNIFFER_TX:
        case FS_FT_NIC_TX:
        case FS_FT_RDMA_RX:
+       case FS_FT_RDMA_TX:
                return mlx5_fs_cmd_get_fw_cmds();
        default:
                return mlx5_fs_cmd_get_stub_cmds();
index 9dc24241dc91e67b2d7e8aace73d848b29724899..98c74a867ef4e4a53f47f807afe1fde4a52fd82e 100644 (file)
                               .identified_miss_table_mode),                   \
                FS_CAP(flow_table_properties_nic_transmit.flow_table_modify))
 
+#define FS_CHAINING_CAPS_RDMA_TX                                                \
+       FS_REQUIRED_CAPS(                                                       \
+               FS_CAP(flow_table_properties_nic_transmit_rdma.flow_modify_en), \
+               FS_CAP(flow_table_properties_nic_transmit_rdma.modify_root),    \
+               FS_CAP(flow_table_properties_nic_transmit_rdma                  \
+                              .identified_miss_table_mode),                    \
+               FS_CAP(flow_table_properties_nic_transmit_rdma                  \
+                              .flow_table_modify))
+
 #define LEFTOVERS_NUM_LEVELS 1
 #define LEFTOVERS_NUM_PRIOS 1
 
@@ -202,6 +211,18 @@ static struct init_tree_node rdma_rx_root_fs = {
        }
 };
 
+static struct init_tree_node rdma_tx_root_fs = {
+       .type = FS_TYPE_NAMESPACE,
+       .ar_size = 1,
+       .children = (struct init_tree_node[]) {
+               ADD_PRIO(0, MLX5_BY_PASS_NUM_PRIOS, 0,
+                        FS_CHAINING_CAPS_RDMA_TX,
+                        ADD_NS(MLX5_FLOW_TABLE_MISS_ACTION_DEF,
+                               ADD_MULTIPLE_PRIO(MLX5_BY_PASS_NUM_PRIOS,
+                                                 BY_PASS_PRIO_NUM_LEVELS))),
+       }
+};
+
 enum fs_i_lock_class {
        FS_LOCK_GRANDPARENT,
        FS_LOCK_PARENT,
@@ -2132,6 +2153,8 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
        } else if (type == MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL) {
                root_ns = steering->rdma_rx_root_ns;
                prio = RDMA_RX_KERNEL_PRIO;
+       } else if (type == MLX5_FLOW_NAMESPACE_RDMA_TX) {
+               root_ns = steering->rdma_tx_root_ns;
        } else { /* Must be NIC RX */
                root_ns = steering->root_ns;
                prio = type;
@@ -2535,6 +2558,7 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev)
        cleanup_root_ns(steering->sniffer_rx_root_ns);
        cleanup_root_ns(steering->sniffer_tx_root_ns);
        cleanup_root_ns(steering->rdma_rx_root_ns);
+       cleanup_root_ns(steering->rdma_tx_root_ns);
        cleanup_root_ns(steering->egress_root_ns);
        mlx5_cleanup_fc_stats(dev);
        kmem_cache_destroy(steering->ftes_cache);
@@ -2591,6 +2615,29 @@ out_err:
        return err;
 }
 
+static int init_rdma_tx_root_ns(struct mlx5_flow_steering *steering)
+{
+       int err;
+
+       steering->rdma_tx_root_ns = create_root_ns(steering, FS_FT_RDMA_TX);
+       if (!steering->rdma_tx_root_ns)
+               return -ENOMEM;
+
+       err = init_root_tree(steering, &rdma_tx_root_fs,
+                            &steering->rdma_tx_root_ns->ns.node);
+       if (err)
+               goto out_err;
+
+       set_prio_attrs(steering->rdma_tx_root_ns);
+
+       return 0;
+
+out_err:
+       cleanup_root_ns(steering->rdma_tx_root_ns);
+       steering->rdma_tx_root_ns = NULL;
+       return err;
+}
+
 /* FT and tc chains are stored in the same array so we can re-use the
  * mlx5_get_fdb_sub_ns() and tc api for FT chains.
  * When creating a new ns for each chain store it in the first available slot.
@@ -2890,6 +2937,12 @@ int mlx5_init_fs(struct mlx5_core_dev *dev)
                        goto err;
        }
 
+       if (MLX5_CAP_FLOWTABLE_RDMA_TX(dev, ft_support)) {
+               err = init_rdma_tx_root_ns(steering);
+               if (err)
+                       goto err;
+       }
+
        if (MLX5_IPSEC_DEV(dev) || MLX5_CAP_FLOWTABLE_NIC_TX(dev, ft_support)) {
                err = init_egress_root_ns(steering);
                if (err)
index be5f5e32c1e8a835d8f1404512eb3e18eedc02cc..508108c58dae13ab8aca240a2e2fa6de94483388 100644 (file)
@@ -86,7 +86,8 @@ enum fs_flow_table_type {
        FS_FT_SNIFFER_RX        = 0X5,
        FS_FT_SNIFFER_TX        = 0X6,
        FS_FT_RDMA_RX           = 0X7,
-       FS_FT_MAX_TYPE = FS_FT_RDMA_RX,
+       FS_FT_RDMA_TX           = 0X8,
+       FS_FT_MAX_TYPE = FS_FT_RDMA_TX,
 };
 
 enum fs_flow_table_op_mod {
@@ -116,6 +117,7 @@ struct mlx5_flow_steering {
        struct mlx5_flow_root_namespace *sniffer_tx_root_ns;
        struct mlx5_flow_root_namespace *sniffer_rx_root_ns;
        struct mlx5_flow_root_namespace *rdma_rx_root_ns;
+       struct mlx5_flow_root_namespace *rdma_tx_root_ns;
        struct mlx5_flow_root_namespace *egress_root_ns;
 };
 
@@ -316,7 +318,8 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev);
        (type == FS_FT_SNIFFER_RX) ? MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) :         \
        (type == FS_FT_SNIFFER_TX) ? MLX5_CAP_FLOWTABLE_SNIFFER_TX(mdev, cap) :         \
        (type == FS_FT_RDMA_RX) ? MLX5_CAP_FLOWTABLE_RDMA_RX(mdev, cap) :               \
-       (BUILD_BUG_ON_ZERO(FS_FT_RDMA_RX != FS_FT_MAX_TYPE))\
+       (type == FS_FT_RDMA_TX) ? MLX5_CAP_FLOWTABLE_RDMA_TX(mdev, cap) :      \
+       (BUILD_BUG_ON_ZERO(FS_FT_RDMA_TX != FS_FT_MAX_TYPE))\
        )
 
 #endif
index 0e62c3db45e5ce7a26298397b4e94d5ecda71dd7..2b90097a6cf9f32216aa904ed88f369b514f91de 100644 (file)
@@ -1211,6 +1211,12 @@ enum mlx5_qcam_feature_groups {
 #define MLX5_CAP_FLOWTABLE_RDMA_RX_MAX(mdev, cap) \
        MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_receive_rdma.cap)
 
+#define MLX5_CAP_FLOWTABLE_RDMA_TX(mdev, cap) \
+       MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_transmit_rdma.cap)
+
+#define MLX5_CAP_FLOWTABLE_RDMA_TX_MAX(mdev, cap) \
+       MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_transmit_rdma.cap)
+
 #define MLX5_CAP_ESW_FLOWTABLE(mdev, cap) \
        MLX5_GET(flow_table_eswitch_cap, \
                 mdev->caps.hca_cur[MLX5_CAP_ESWITCH_FLOW_TABLE], cap)
index 4cae16016b2bdd9c05d72577207b16fdbde887f1..44c9fe792fc45432e6369b5f2366bf5040c54c3e 100644 (file)
@@ -77,6 +77,7 @@ enum mlx5_flow_namespace_type {
        MLX5_FLOW_NAMESPACE_EGRESS,
        MLX5_FLOW_NAMESPACE_RDMA_RX,
        MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL,
+       MLX5_FLOW_NAMESPACE_RDMA_TX,
 };
 
 enum {
index 9b8ff4e57002c0edf196c5c9ddc7290a1c4b075e..600366ef2d84614d6a8552eca3951fd99e29607c 100644 (file)
@@ -705,7 +705,7 @@ struct mlx5_ifc_flow_table_nic_cap_bits {
 
        struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_transmit;
 
-       u8         reserved_at_a00[0x200];
+       struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_transmit_rdma;
 
        struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_transmit_sniffer;