Commit 3ee61ebb authored by Paul Blakey's avatar Paul Blakey Committed by Saeed Mahameed

net/mlx5: CT: Add software steering ct flow steering provider

fs_core layer adds extra book keeping that is either unneeded for CT, or
unused by the underlying software steering, such as allocating FTEs and
FTE ids, saving the match key and mask, and autogroups management.
On top of that, direct steering has a translation layer (fs_dr) from PRM
commands to direct steering objects, for example, creating temporary
dr_action objects. This has a performance impact when dealing
with CT high insertion rate.

To use direct steering (smfs) directly for ct, add a tc ct fs smfs
implementation. Instead of dmfs autogroups, smfs ct fs uses one of 4
predefined dr matchers in CT and CT-NAT tables, for each combination
of tuple ethertype (ipv4/ipv6), and tuple ip_proto (udp/tcp) that
is currently used by nf flow table flow offload.

At rule insertions, validate the flow rule fits one of the predfined
matcher, and insert to it.

To fill the dr_actions of the rule efficiently, create the fwd to post_ct
tbl dr_action at fs init, the count dr_action at counter creation,
and re-use the already pre-allocated modify header dr_action.
Signed-off-by: default avatarPaul Blakey <paulb@nvidia.com>
Reviewed-by: default avatarOz Shlomo <ozsh@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent c6fef514
...@@ -55,7 +55,11 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en/tc/act/act.o en/tc/act/drop.o en/tc/a ...@@ -55,7 +55,11 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en/tc/act/act.o en/tc/act/drop.o en/tc/a
en/tc/act/ct.o en/tc/act/sample.o en/tc/act/ptype.o \ en/tc/act/ct.o en/tc/act/sample.o en/tc/act/ptype.o \
en/tc/act/redirect_ingress.o en/tc/act/redirect_ingress.o
mlx5_core-$(CONFIG_MLX5_TC_CT) += en/tc_ct.o en/tc/ct_fs_dmfs.o ifneq ($(CONFIG_MLX5_TC_CT),)
mlx5_core-y += en/tc_ct.o en/tc/ct_fs_dmfs.o
mlx5_core-$(CONFIG_MLX5_SW_STEERING) += en/tc/ct_fs_smfs.o
endif
mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o
# #
......
...@@ -7,18 +7,43 @@ ...@@ -7,18 +7,43 @@
struct mlx5_ct_fs { struct mlx5_ct_fs {
const struct net_device *netdev; const struct net_device *netdev;
struct mlx5_core_dev *dev; struct mlx5_core_dev *dev;
/* private data */
void *priv_data[];
}; };
struct mlx5_ct_fs_rule { struct mlx5_ct_fs_rule {
}; };
struct mlx5_ct_fs_ops { struct mlx5_ct_fs_ops {
int (*init)(struct mlx5_ct_fs *fs, struct mlx5_flow_table *ct,
struct mlx5_flow_table *ct_nat, struct mlx5_flow_table *post_ct);
void (*destroy)(struct mlx5_ct_fs *fs);
struct mlx5_ct_fs_rule * (*ct_rule_add)(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule * (*ct_rule_add)(struct mlx5_ct_fs *fs,
struct mlx5_flow_spec *spec, struct mlx5_flow_spec *spec,
struct mlx5_flow_attr *attr); struct mlx5_flow_attr *attr,
struct flow_rule *flow_rule);
void (*ct_rule_del)(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule); void (*ct_rule_del)(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule);
size_t priv_size;
}; };
static inline void *mlx5_ct_fs_priv(struct mlx5_ct_fs *fs)
{
return &fs->priv_data;
}
struct mlx5_ct_fs_ops *mlx5_ct_fs_dmfs_ops_get(void); struct mlx5_ct_fs_ops *mlx5_ct_fs_dmfs_ops_get(void);
#if IS_ENABLED(CONFIG_MLX5_SW_STEERING)
struct mlx5_ct_fs_ops *mlx5_ct_fs_smfs_ops_get(void);
#else
static inline struct mlx5_ct_fs_ops *
mlx5_ct_fs_smfs_ops_get(void)
{
return NULL;
}
#endif /* IS_ENABLED(CONFIG_MLX5_SW_STEERING) */
#endif /* __MLX5_EN_TC_CT_FS_H__ */ #endif /* __MLX5_EN_TC_CT_FS_H__ */
...@@ -14,9 +14,21 @@ struct mlx5_ct_fs_dmfs_rule { ...@@ -14,9 +14,21 @@ struct mlx5_ct_fs_dmfs_rule {
struct mlx5_flow_attr *attr; struct mlx5_flow_attr *attr;
}; };
static int
mlx5_ct_fs_dmfs_init(struct mlx5_ct_fs *fs, struct mlx5_flow_table *ct,
struct mlx5_flow_table *ct_nat, struct mlx5_flow_table *post_ct)
{
return 0;
}
static void
mlx5_ct_fs_dmfs_destroy(struct mlx5_ct_fs *fs)
{
}
static struct mlx5_ct_fs_rule * static struct mlx5_ct_fs_rule *
mlx5_ct_fs_dmfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec, mlx5_ct_fs_dmfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec,
struct mlx5_flow_attr *attr) struct mlx5_flow_attr *attr, struct flow_rule *flow_rule)
{ {
struct mlx5e_priv *priv = netdev_priv(fs->netdev); struct mlx5e_priv *priv = netdev_priv(fs->netdev);
struct mlx5_ct_fs_dmfs_rule *dmfs_rule; struct mlx5_ct_fs_dmfs_rule *dmfs_rule;
...@@ -56,6 +68,9 @@ mlx5_ct_fs_dmfs_ct_rule_del(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_ru ...@@ -56,6 +68,9 @@ mlx5_ct_fs_dmfs_ct_rule_del(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_ru
static struct mlx5_ct_fs_ops dmfs_ops = { static struct mlx5_ct_fs_ops dmfs_ops = {
.ct_rule_add = mlx5_ct_fs_dmfs_ct_rule_add, .ct_rule_add = mlx5_ct_fs_dmfs_ct_rule_add,
.ct_rule_del = mlx5_ct_fs_dmfs_ct_rule_del, .ct_rule_del = mlx5_ct_fs_dmfs_ct_rule_del,
.init = mlx5_ct_fs_dmfs_init,
.destroy = mlx5_ct_fs_dmfs_destroy,
}; };
struct mlx5_ct_fs_ops *mlx5_ct_fs_dmfs_ops_get(void) struct mlx5_ct_fs_ops *mlx5_ct_fs_dmfs_ops_get(void)
......
This diff is collapsed.
...@@ -26,9 +26,8 @@ ...@@ -26,9 +26,8 @@
#include "en.h" #include "en.h"
#include "en_tc.h" #include "en_tc.h"
#include "en_rep.h" #include "en_rep.h"
#include "fs_core.h"
#define MLX5_CT_ZONE_BITS (mlx5e_tc_attr_to_reg_mappings[ZONE_TO_REG].mlen)
#define MLX5_CT_ZONE_MASK GENMASK(MLX5_CT_ZONE_BITS - 1, 0)
#define MLX5_CT_STATE_ESTABLISHED_BIT BIT(1) #define MLX5_CT_STATE_ESTABLISHED_BIT BIT(1)
#define MLX5_CT_STATE_TRK_BIT BIT(2) #define MLX5_CT_STATE_TRK_BIT BIT(2)
#define MLX5_CT_STATE_NAT_BIT BIT(3) #define MLX5_CT_STATE_NAT_BIT BIT(3)
...@@ -819,7 +818,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv, ...@@ -819,7 +818,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
mlx5_tc_ct_set_tuple_match(ct_priv, spec, flow_rule); mlx5_tc_ct_set_tuple_match(ct_priv, spec, flow_rule);
mlx5e_tc_match_to_reg_match(spec, ZONE_TO_REG, entry->tuple.zone, MLX5_CT_ZONE_MASK); mlx5e_tc_match_to_reg_match(spec, ZONE_TO_REG, entry->tuple.zone, MLX5_CT_ZONE_MASK);
zone_rule->rule = ct_priv->fs_ops->ct_rule_add(ct_priv->fs, spec, attr); zone_rule->rule = ct_priv->fs_ops->ct_rule_add(ct_priv->fs, spec, attr, flow_rule);
if (IS_ERR(zone_rule->rule)) { if (IS_ERR(zone_rule->rule)) {
err = PTR_ERR(zone_rule->rule); err = PTR_ERR(zone_rule->rule);
ct_dbg("Failed to add ct entry rule, nat: %d", nat); ct_dbg("Failed to add ct entry rule, nat: %d", nat);
...@@ -1966,9 +1965,17 @@ mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv, ...@@ -1966,9 +1965,17 @@ mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
static int static int
mlx5_tc_ct_fs_init(struct mlx5_tc_ct_priv *ct_priv) mlx5_tc_ct_fs_init(struct mlx5_tc_ct_priv *ct_priv)
{ {
struct mlx5_flow_table *post_ct = mlx5e_tc_post_act_get_ft(ct_priv->post_act);
struct mlx5_ct_fs_ops *fs_ops = mlx5_ct_fs_dmfs_ops_get(); struct mlx5_ct_fs_ops *fs_ops = mlx5_ct_fs_dmfs_ops_get();
int err;
if (ct_priv->ns_type == MLX5_FLOW_NAMESPACE_FDB &&
ct_priv->dev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_SMFS) {
ct_dbg("Using SMFS ct flow steering provider");
fs_ops = mlx5_ct_fs_smfs_ops_get();
}
ct_priv->fs = kzalloc(sizeof(*ct_priv->fs), GFP_KERNEL); ct_priv->fs = kzalloc(sizeof(*ct_priv->fs) + fs_ops->priv_size, GFP_KERNEL);
if (!ct_priv->fs) if (!ct_priv->fs)
return -ENOMEM; return -ENOMEM;
...@@ -1976,7 +1983,15 @@ mlx5_tc_ct_fs_init(struct mlx5_tc_ct_priv *ct_priv) ...@@ -1976,7 +1983,15 @@ mlx5_tc_ct_fs_init(struct mlx5_tc_ct_priv *ct_priv)
ct_priv->fs->dev = ct_priv->dev; ct_priv->fs->dev = ct_priv->dev;
ct_priv->fs_ops = fs_ops; ct_priv->fs_ops = fs_ops;
err = ct_priv->fs_ops->init(ct_priv->fs, ct_priv->ct, ct_priv->ct_nat, post_ct);
if (err)
goto err_init;
return 0; return 0;
err_init:
kfree(ct_priv->fs);
return err;
} }
static int static int
...@@ -2155,6 +2170,7 @@ mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv) ...@@ -2155,6 +2170,7 @@ mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv)
chains = ct_priv->chains; chains = ct_priv->chains;
ct_priv->fs_ops->destroy(ct_priv->fs);
kfree(ct_priv->fs); kfree(ct_priv->fs);
mlx5_chains_destroy_global_table(chains, ct_priv->ct_nat); mlx5_chains_destroy_global_table(chains, ct_priv->ct_nat);
......
...@@ -86,6 +86,8 @@ struct mlx5_ct_attr { ...@@ -86,6 +86,8 @@ struct mlx5_ct_attr {
#define REG_MAPPING_MLEN(reg) (mlx5e_tc_attr_to_reg_mappings[reg].mlen) #define REG_MAPPING_MLEN(reg) (mlx5e_tc_attr_to_reg_mappings[reg].mlen)
#define REG_MAPPING_MOFFSET(reg) (mlx5e_tc_attr_to_reg_mappings[reg].moffset) #define REG_MAPPING_MOFFSET(reg) (mlx5e_tc_attr_to_reg_mappings[reg].moffset)
#define MLX5_CT_ZONE_BITS (mlx5e_tc_attr_to_reg_mappings[ZONE_TO_REG].mlen)
#define MLX5_CT_ZONE_MASK GENMASK(MLX5_CT_ZONE_BITS - 1, 0)
#if IS_ENABLED(CONFIG_MLX5_TC_CT) #if IS_ENABLED(CONFIG_MLX5_TC_CT)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment