Blame SOURCES/0211-netdrv-net-mlx5-TC-Offload-flow-table-rules.patch

d8f823
From b48be0498952550c01fb5de0769c8f1be1ac612d Mon Sep 17 00:00:00 2001
d8f823
From: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Date: Tue, 19 May 2020 07:48:32 -0400
d8f823
Subject: [PATCH 211/312] [netdrv] net/mlx5: TC: Offload flow table rules
d8f823
d8f823
Message-id: <20200519074934.6303-2-ahleihel@redhat.com>
d8f823
Patchwork-id: 310508
d8f823
Patchwork-instance: patchwork
d8f823
O-Subject: [RHEL8.3 BZ 1663246 01/63] net/mlx5: TC: Offload flow table rules
d8f823
Bugzilla: 1663246
d8f823
RH-Acked-by: Marcelo Leitner <mleitner@redhat.com>
d8f823
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
d8f823
RH-Acked-by: John Linville <linville@redhat.com>
d8f823
RH-Acked-by: Ivan Vecera <ivecera@redhat.com>
d8f823
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
d8f823
RH-Acked-by: Kamal Heib <kheib@redhat.com>
d8f823
d8f823
Bugzilla: http://bugzilla.redhat.com/1663246
d8f823
Upstream: v5.5-rc1
d8f823
Conflicts:
d8f823
 - drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
d8f823
   Small context diff due to already backported commit:
d8f823
   554fe75c1b3f ("net/mlx5e: Avoid duplicating rule destinations")
d8f823
   ---> Different list of local variables in function parse_tc_fdb_actions.
d8f823
d8f823
commit 84179981317fb4fb3e9df5acd42ea33cf6037793
d8f823
Author: Paul Blakey <paulb@mellanox.com>
d8f823
Date:   Tue Nov 12 00:34:30 2019 +0100
d8f823
d8f823
    net/mlx5: TC: Offload flow table rules
d8f823
d8f823
    Since both tc rules and flow table rules are of the same format,
d8f823
    we can re-use tc parsing for that, and move the flow table rules
d8f823
    to their steering domain - In this case, the next chain after
d8f823
    max tc chain.
d8f823
d8f823
    Signed-off-by: Paul Blakey <paulb@mellanox.com>
d8f823
    Reviewed-by: Mark Bloch <markb@mellanox.com>
d8f823
    Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
d8f823
    Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
d8f823
d8f823
Signed-off-by: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
d8f823
---
d8f823
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 45 ++++++++++++++++++++++--
d8f823
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c  | 28 ++++++++++++++-
d8f823
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h  |  3 +-
d8f823
 3 files changed, 71 insertions(+), 5 deletions(-)
d8f823
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
d8f823
index 7ba784575a23..d03d80e162df 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
d8f823
@@ -1220,21 +1220,60 @@ static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
d8f823
 	}
d8f823
 }
d8f823
 
d8f823
-static LIST_HEAD(mlx5e_rep_block_cb_list);
d8f823
+static int mlx5e_rep_setup_ft_cb(enum tc_setup_type type, void *type_data,
d8f823
+				 void *cb_priv)
d8f823
+{
d8f823
+	struct flow_cls_offload *f = type_data;
d8f823
+	struct flow_cls_offload cls_flower;
d8f823
+	struct mlx5e_priv *priv = cb_priv;
d8f823
+	struct mlx5_eswitch *esw;
d8f823
+	unsigned long flags;
d8f823
+	int err;
d8f823
+
d8f823
+	flags = MLX5_TC_FLAG(INGRESS) |
d8f823
+		MLX5_TC_FLAG(ESW_OFFLOAD) |
d8f823
+		MLX5_TC_FLAG(FT_OFFLOAD);
d8f823
+	esw = priv->mdev->priv.eswitch;
d8f823
 
d8f823
+	switch (type) {
d8f823
+	case TC_SETUP_CLSFLOWER:
d8f823
+		if (!mlx5_eswitch_prios_supported(esw) || f->common.chain_index)
d8f823
+			return -EOPNOTSUPP;
d8f823
+
d8f823
+		/* Re-use tc offload path by moving the ft flow to the
d8f823
+		 * reserved ft chain.
d8f823
+		 */
d8f823
+		memcpy(&cls_flower, f, sizeof(*f));
d8f823
+		cls_flower.common.chain_index = FDB_FT_CHAIN;
d8f823
+		err = mlx5e_rep_setup_tc_cls_flower(priv, &cls_flower, flags);
d8f823
+		memcpy(&f->stats, &cls_flower.stats, sizeof(f->stats));
d8f823
+		return err;
d8f823
+	default:
d8f823
+		return -EOPNOTSUPP;
d8f823
+	}
d8f823
+}
d8f823
+
d8f823
+static LIST_HEAD(mlx5e_rep_block_tc_cb_list);
d8f823
+static LIST_HEAD(mlx5e_rep_block_ft_cb_list);
d8f823
 static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
d8f823
 			      void *type_data)
d8f823
 {
d8f823
 	struct mlx5e_priv *priv = netdev_priv(dev);
d8f823
 	struct flow_block_offload *f = type_data;
d8f823
 
d8f823
+	f->unlocked_driver_cb = true;
d8f823
+
d8f823
 	switch (type) {
d8f823
 	case TC_SETUP_BLOCK:
d8f823
-		f->unlocked_driver_cb = true;
d8f823
 		return flow_block_cb_setup_simple(type_data,
d8f823
-						  &mlx5e_rep_block_cb_list,
d8f823
+						  &mlx5e_rep_block_tc_cb_list,
d8f823
 						  mlx5e_rep_setup_tc_cb,
d8f823
 						  priv, priv, true);
d8f823
+	case TC_SETUP_FT:
d8f823
+		return flow_block_cb_setup_simple(type_data,
d8f823
+						  &mlx5e_rep_block_ft_cb_list,
d8f823
+						  mlx5e_rep_setup_ft_cb,
d8f823
+						  priv, priv, true);
d8f823
 	default:
d8f823
 		return -EOPNOTSUPP;
d8f823
 	}
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
d8f823
index 3461aec49d9e..3df69f8ed58a 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
d8f823
@@ -74,6 +74,7 @@ enum {
d8f823
 	MLX5E_TC_FLOW_FLAG_INGRESS	= MLX5E_TC_FLAG_INGRESS_BIT,
d8f823
 	MLX5E_TC_FLOW_FLAG_EGRESS	= MLX5E_TC_FLAG_EGRESS_BIT,
d8f823
 	MLX5E_TC_FLOW_FLAG_ESWITCH	= MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
d8f823
+	MLX5E_TC_FLOW_FLAG_FT		= MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
d8f823
 	MLX5E_TC_FLOW_FLAG_NIC		= MLX5E_TC_FLAG_NIC_OFFLOAD_BIT,
d8f823
 	MLX5E_TC_FLOW_FLAG_OFFLOADED	= MLX5E_TC_FLOW_BASE,
d8f823
 	MLX5E_TC_FLOW_FLAG_HAIRPIN	= MLX5E_TC_FLOW_BASE + 1,
d8f823
@@ -276,6 +277,11 @@ static bool mlx5e_is_eswitch_flow(struct mlx5e_tc_flow *flow)
d8f823
 	return flow_flag_test(flow, ESWITCH);
d8f823
 }
d8f823
 
d8f823
+static bool mlx5e_is_ft_flow(struct mlx5e_tc_flow *flow)
d8f823
+{
d8f823
+	return flow_flag_test(flow, FT);
d8f823
+}
d8f823
+
d8f823
 static bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow)
d8f823
 {
d8f823
 	return flow_flag_test(flow, OFFLOADED);
d8f823
@@ -1171,7 +1177,12 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
d8f823
 		return -EOPNOTSUPP;
d8f823
 	}
d8f823
 
d8f823
-	if (attr->chain > max_chain) {
d8f823
+	/* We check chain range only for tc flows.
d8f823
+	 * For ft flows, we checked attr->chain was originally 0 and set it to
d8f823
+	 * FDB_FT_CHAIN which is outside tc range.
d8f823
+	 * See mlx5e_rep_setup_ft_cb().
d8f823
+	 */
d8f823
+	if (!mlx5e_is_ft_flow(flow) && attr->chain > max_chain) {
d8f823
 		NL_SET_ERR_MSG(extack, "Requested chain is out of supported range");
d8f823
 		return -EOPNOTSUPP;
d8f823
 	}
d8f823
@@ -3315,6 +3326,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
d8f823
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
d8f823
 	const struct ip_tunnel_info *info = NULL;
d8f823
 	int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS];
d8f823
+	bool ft_flow = mlx5e_is_ft_flow(flow);
d8f823
 	const struct flow_action_entry *act;
d8f823
 	int err, i, if_count = 0;
d8f823
 	bool encap = false;
d8f823
@@ -3362,6 +3374,14 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
d8f823
 				return -EINVAL;
d8f823
 			}
d8f823
 
d8f823
+			if (ft_flow && out_dev == priv->netdev) {
d8f823
+				/* Ignore forward to self rules generated
d8f823
+				 * by adding both mlx5 devs to the flow table
d8f823
+				 * block on a normal nft offload setup.
d8f823
+				 */
d8f823
+				return -EOPNOTSUPP;
d8f823
+			}
d8f823
+
d8f823
 			if (attr->out_count >= MLX5_MAX_FLOW_FWD_VPORTS) {
d8f823
 				NL_SET_ERR_MSG_MOD(extack,
d8f823
 						   "can't support more output ports, can't offload forwarding");
d8f823
@@ -3518,6 +3538,10 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
d8f823
 			u32 dest_chain = act->chain_index;
d8f823
 			u32 max_chain = mlx5_eswitch_get_chain_range(esw);
d8f823
 
d8f823
+			if (ft_flow) {
d8f823
+				NL_SET_ERR_MSG_MOD(extack, "Goto action is not supported");
d8f823
+				return -EOPNOTSUPP;
d8f823
+			}
d8f823
 			if (dest_chain <= attr->chain) {
d8f823
 				NL_SET_ERR_MSG(extack, "Goto earlier chain isn't supported");
d8f823
 				return -EOPNOTSUPP;
d8f823
@@ -3608,6 +3632,8 @@ static void get_flags(int flags, unsigned long *flow_flags)
d8f823
 		__flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_ESWITCH);
d8f823
 	if (flags & MLX5_TC_FLAG(NIC_OFFLOAD))
d8f823
 		__flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_NIC);
d8f823
+	if (flags & MLX5_TC_FLAG(FT_OFFLOAD))
d8f823
+		__flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_FT);
d8f823
 
d8f823
 	*flow_flags = __flow_flags;
d8f823
 }
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
d8f823
index 924c6ef86a14..262cdb7b69b1 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
d8f823
@@ -44,7 +44,8 @@ enum {
d8f823
 	MLX5E_TC_FLAG_EGRESS_BIT,
d8f823
 	MLX5E_TC_FLAG_NIC_OFFLOAD_BIT,
d8f823
 	MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
d8f823
-	MLX5E_TC_FLAG_LAST_EXPORTED_BIT = MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
d8f823
+	MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
d8f823
+	MLX5E_TC_FLAG_LAST_EXPORTED_BIT = MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
d8f823
 };
d8f823
 
d8f823
 #define MLX5_TC_FLAG(flag) BIT(MLX5E_TC_FLAG_##flag##_BIT)
d8f823
-- 
d8f823
2.13.6
d8f823