net/mlx5: Add support for RDMA TX steering

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>
This commit is contained in:
Michael Guralnik 2020-03-24 08:14:24 +02:00 committed by Jason Gunthorpe
parent 826096d84f
commit 24670b1a31
6 changed files with 67 additions and 3 deletions

View 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_SNIFFER_TX:
case FS_FT_NIC_TX: case FS_FT_NIC_TX:
case FS_FT_RDMA_RX: case FS_FT_RDMA_RX:
case FS_FT_RDMA_TX:
return mlx5_fs_cmd_get_fw_cmds(); return mlx5_fs_cmd_get_fw_cmds();
default: default:
return mlx5_fs_cmd_get_stub_cmds(); return mlx5_fs_cmd_get_stub_cmds();

View File

@ -87,6 +87,15 @@
.identified_miss_table_mode), \ .identified_miss_table_mode), \
FS_CAP(flow_table_properties_nic_transmit.flow_table_modify)) 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_LEVELS 1
#define LEFTOVERS_NUM_PRIOS 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 { enum fs_i_lock_class {
FS_LOCK_GRANDPARENT, FS_LOCK_GRANDPARENT,
FS_LOCK_PARENT, 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) { } else if (type == MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL) {
root_ns = steering->rdma_rx_root_ns; root_ns = steering->rdma_rx_root_ns;
prio = RDMA_RX_KERNEL_PRIO; 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 */ } else { /* Must be NIC RX */
root_ns = steering->root_ns; root_ns = steering->root_ns;
prio = type; 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_rx_root_ns);
cleanup_root_ns(steering->sniffer_tx_root_ns); cleanup_root_ns(steering->sniffer_tx_root_ns);
cleanup_root_ns(steering->rdma_rx_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); cleanup_root_ns(steering->egress_root_ns);
mlx5_cleanup_fc_stats(dev); mlx5_cleanup_fc_stats(dev);
kmem_cache_destroy(steering->ftes_cache); kmem_cache_destroy(steering->ftes_cache);
@ -2591,6 +2615,29 @@ out_err:
return 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 /* 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. * 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. * 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; 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)) { if (MLX5_IPSEC_DEV(dev) || MLX5_CAP_FLOWTABLE_NIC_TX(dev, ft_support)) {
err = init_egress_root_ns(steering); err = init_egress_root_ns(steering);
if (err) if (err)

View File

@ -86,7 +86,8 @@ enum fs_flow_table_type {
FS_FT_SNIFFER_RX = 0X5, FS_FT_SNIFFER_RX = 0X5,
FS_FT_SNIFFER_TX = 0X6, FS_FT_SNIFFER_TX = 0X6,
FS_FT_RDMA_RX = 0X7, 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 { 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_tx_root_ns;
struct mlx5_flow_root_namespace *sniffer_rx_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_rx_root_ns;
struct mlx5_flow_root_namespace *rdma_tx_root_ns;
struct mlx5_flow_root_namespace *egress_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_RX) ? MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) : \
(type == FS_FT_SNIFFER_TX) ? MLX5_CAP_FLOWTABLE_SNIFFER_TX(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) : \ (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 #endif

View File

@ -1211,6 +1211,12 @@ enum mlx5_qcam_feature_groups {
#define MLX5_CAP_FLOWTABLE_RDMA_RX_MAX(mdev, cap) \ #define MLX5_CAP_FLOWTABLE_RDMA_RX_MAX(mdev, cap) \
MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_receive_rdma.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) \ #define MLX5_CAP_ESW_FLOWTABLE(mdev, cap) \
MLX5_GET(flow_table_eswitch_cap, \ MLX5_GET(flow_table_eswitch_cap, \
mdev->caps.hca_cur[MLX5_CAP_ESWITCH_FLOW_TABLE], cap) mdev->caps.hca_cur[MLX5_CAP_ESWITCH_FLOW_TABLE], cap)

View File

@ -77,6 +77,7 @@ enum mlx5_flow_namespace_type {
MLX5_FLOW_NAMESPACE_EGRESS, MLX5_FLOW_NAMESPACE_EGRESS,
MLX5_FLOW_NAMESPACE_RDMA_RX, MLX5_FLOW_NAMESPACE_RDMA_RX,
MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL, MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL,
MLX5_FLOW_NAMESPACE_RDMA_TX,
}; };
enum { enum {

View 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; 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; struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_transmit_sniffer;