summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
diff options
context:
space:
mode:
authorOr Gerlitz2018-04-10 17:34:36 +0200
committerSaeed Mahameed2018-05-18 02:48:54 +0200
commit655dc3d2b91bf241f5baca5eb2bc2b1e22a561ff (patch)
tree79e9aaf7baa7d3ff9e93ced8cc77a7be3eb81b3c /drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
parentnet/mlx5e: Prepare for shared table to keep TC eswitch flows (diff)
downloadkernel-qcow2-linux-655dc3d2b91bf241f5baca5eb2bc2b1e22a561ff.tar.gz
kernel-qcow2-linux-655dc3d2b91bf241f5baca5eb2bc2b1e22a561ff.tar.xz
kernel-qcow2-linux-655dc3d2b91bf241f5baca5eb2bc2b1e22a561ff.zip
net/mlx5e: Use shared table for offloaded TC eswitch flows
Currently, each representor netdev use their own hash table to keep the mapping from TC flow (f->cookie) to the driver offloaded instance. The table is the one which originally was added for offloading TC NIC (not eswitch) rules. This scheme breaks when the core TC code calls us to add the same flow twice, (e.g under egdev use case) since we don't spot that and offload a 2nd flow into the HW with the wrong source vport. As a pre-step to solve that, we move to use a single table which keeps all offloaded TC eswitch flows. The table is located at the eswitch uplink representor object. Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Paul Blakey <paulb@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/en_tc.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 1c90586d7f58..05c90b4f8a31 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -76,6 +76,7 @@ enum {
struct mlx5e_tc_flow {
struct rhash_head node;
+ struct mlx5e_priv *priv;
u64 cookie;
u8 flags;
struct mlx5_flow_handle *rule;
@@ -2643,7 +2644,14 @@ static const struct rhashtable_params tc_ht_params = {
static struct rhashtable *get_tc_ht(struct mlx5e_priv *priv)
{
- return &priv->fs.tc.ht;
+ struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+ struct mlx5e_rep_priv *uplink_rpriv;
+
+ if (MLX5_VPORT_MANAGER(priv->mdev) && esw->mode == SRIOV_OFFLOADS) {
+ uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
+ return &uplink_rpriv->tc_ht;
+ } else
+ return &priv->fs.tc.ht;
}
int mlx5e_configure_flower(struct mlx5e_priv *priv,
@@ -2675,6 +2683,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv,
flow->cookie = f->cookie;
flow->flags = flow_flags;
+ flow->priv = priv;
err = parse_cls_flower(priv, flow, &parse_attr->spec, f);
if (err < 0)
@@ -2766,7 +2775,7 @@ int mlx5e_stats_flower(struct mlx5e_priv *priv,
return 0;
}
-int mlx5e_tc_init(struct mlx5e_priv *priv)
+int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
{
struct mlx5e_tc_table *tc = &priv->fs.tc;
@@ -2779,20 +2788,30 @@ int mlx5e_tc_init(struct mlx5e_priv *priv)
static void _mlx5e_tc_del_flow(void *ptr, void *arg)
{
struct mlx5e_tc_flow *flow = ptr;
- struct mlx5e_priv *priv = arg;
+ struct mlx5e_priv *priv = flow->priv;
mlx5e_tc_del_flow(priv, flow);
kfree(flow);
}
-void mlx5e_tc_cleanup(struct mlx5e_priv *priv)
+void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv)
{
struct mlx5e_tc_table *tc = &priv->fs.tc;
- rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, priv);
+ rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL);
if (!IS_ERR_OR_NULL(tc->t)) {
mlx5_destroy_flow_table(tc->t);
tc->t = NULL;
}
}
+
+int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
+{
+ return rhashtable_init(tc_ht, &tc_ht_params);
+}
+
+void mlx5e_tc_esw_cleanup(struct rhashtable *tc_ht)
+{
+ rhashtable_free_and_destroy(tc_ht, _mlx5e_tc_del_flow, NULL);
+}