Blame SOURCES/0023-netdrv-net-mlx5e-Generalize-tx-reporter-s-functional.patch

d8f823
From 6258b703b584c06c8f63788431a978bd4db8bb97 Mon Sep 17 00:00:00 2001
d8f823
From: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Date: Sun, 10 May 2020 14:51:47 -0400
d8f823
Subject: [PATCH 023/312] [netdrv] net/mlx5e: Generalize tx reporter's
d8f823
 functionality
d8f823
d8f823
Message-id: <20200510145245.10054-25-ahleihel@redhat.com>
d8f823
Patchwork-id: 306564
d8f823
Patchwork-instance: patchwork
d8f823
O-Subject: [RHEL8.3 BZ 1789378 v2 24/82] net/mlx5e: Generalize tx reporter's functionality
d8f823
Bugzilla: 1790198 1789378
d8f823
RH-Acked-by: Kamal Heib <kheib@redhat.com>
d8f823
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
d8f823
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
d8f823
RH-Acked-by: Jonathan Toppins <jtoppins@redhat.com>
d8f823
d8f823
Bugzilla: http://bugzilla.redhat.com/1789378
d8f823
Bugzilla: http://bugzilla.redhat.com/1790198
d8f823
Upstream: v5.4-rc1
d8f823
Conflicts:
d8f823
 - drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
d8f823
   Conext diff due to already mereged commit:
d8f823
   e7a981050a7f ("devlink: propagate extack down to health reporter ops")
d8f823
   ---> Function mlx5e_tx_reporter_recover takes also extact parameter now.
d8f823
d8f823
commit c50de4af1d635fab3a5c8bd358f55623c01f7ee5
d8f823
Author: Aya Levin <ayal@mellanox.com>
d8f823
Date:   Mon Jul 1 15:08:13 2019 +0300
d8f823
d8f823
    net/mlx5e: Generalize tx reporter's functionality
d8f823
d8f823
    Prepare for code sharing with rx reporter, which is added in the
d8f823
    following patches in the set. Introduce a generic error_ctx for
d8f823
    agnostic recovery despatch.
d8f823
d8f823
    Signed-off-by: Aya Levin <ayal@mellanox.com>
d8f823
    Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
d8f823
    Acked-by: Jiri Pirko <jiri@mellanox.com>
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/Makefile   |   5 +-
d8f823
 .../net/ethernet/mellanox/mlx5/core/en/health.c    |  82 ++++++++++++
d8f823
 .../net/ethernet/mellanox/mlx5/core/en/health.h    |  14 +++
d8f823
 .../ethernet/mellanox/mlx5/core/en/reporter_tx.c   | 140 ++++++---------------
d8f823
 4 files changed, 137 insertions(+), 104 deletions(-)
d8f823
 create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/en/health.c
d8f823
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
d8f823
index 35079e1f1f6f..4369dfd04a34 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
d8f823
@@ -23,8 +23,9 @@ mlx5_core-y :=	main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
d8f823
 #
d8f823
 mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
d8f823
 		en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \
d8f823
-		en_selftest.o en/port.o en/monitor_stats.o en/reporter_tx.o \
d8f823
-		en/params.o en/xsk/umem.o en/xsk/setup.o en/xsk/rx.o en/xsk/tx.o
d8f823
+		en_selftest.o en/port.o en/monitor_stats.o en/health.o \
d8f823
+		en/reporter_tx.o en/params.o en/xsk/umem.o en/xsk/setup.o \
d8f823
+		en/xsk/rx.o en/xsk/tx.o
d8f823
 
d8f823
 #
d8f823
 # Netdev extra
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/health.c b/drivers/net/ethernet/mellanox/mlx5/core/en/health.c
d8f823
new file mode 100644
d8f823
index 000000000000..fc3112921bd3
d8f823
--- /dev/null
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/health.c
d8f823
@@ -0,0 +1,82 @@
d8f823
+// SPDX-License-Identifier: GPL-2.0
d8f823
+// Copyright (c) 2019 Mellanox Technologies.
d8f823
+
d8f823
+#include "health.h"
d8f823
+#include "lib/eq.h"
d8f823
+
d8f823
+int mlx5e_health_sq_to_ready(struct mlx5e_channel *channel, u32 sqn)
d8f823
+{
d8f823
+	struct mlx5_core_dev *mdev = channel->mdev;
d8f823
+	struct net_device *dev = channel->netdev;
d8f823
+	struct mlx5e_modify_sq_param msp = {};
d8f823
+	int err;
d8f823
+
d8f823
+	msp.curr_state = MLX5_SQC_STATE_ERR;
d8f823
+	msp.next_state = MLX5_SQC_STATE_RST;
d8f823
+
d8f823
+	err = mlx5e_modify_sq(mdev, sqn, &msp;;
d8f823
+	if (err) {
d8f823
+		netdev_err(dev, "Failed to move sq 0x%x to reset\n", sqn);
d8f823
+		return err;
d8f823
+	}
d8f823
+
d8f823
+	memset(&msp, 0, sizeof(msp));
d8f823
+	msp.curr_state = MLX5_SQC_STATE_RST;
d8f823
+	msp.next_state = MLX5_SQC_STATE_RDY;
d8f823
+
d8f823
+	err = mlx5e_modify_sq(mdev, sqn, &msp;;
d8f823
+	if (err) {
d8f823
+		netdev_err(dev, "Failed to move sq 0x%x to ready\n", sqn);
d8f823
+		return err;
d8f823
+	}
d8f823
+
d8f823
+	return 0;
d8f823
+}
d8f823
+
d8f823
+int mlx5e_health_recover_channels(struct mlx5e_priv *priv)
d8f823
+{
d8f823
+	int err = 0;
d8f823
+
d8f823
+	rtnl_lock();
d8f823
+	mutex_lock(&priv->state_lock);
d8f823
+
d8f823
+	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
d8f823
+		goto out;
d8f823
+
d8f823
+	err = mlx5e_safe_reopen_channels(priv);
d8f823
+
d8f823
+out:
d8f823
+	mutex_unlock(&priv->state_lock);
d8f823
+	rtnl_unlock();
d8f823
+
d8f823
+	return err;
d8f823
+}
d8f823
+
d8f823
+int mlx5e_health_channel_eq_recover(struct mlx5_eq_comp *eq, struct mlx5e_channel *channel)
d8f823
+{
d8f823
+	u32 eqe_count;
d8f823
+
d8f823
+	netdev_err(channel->netdev, "EQ 0x%x: Cons = 0x%x, irqn = 0x%x\n",
d8f823
+		   eq->core.eqn, eq->core.cons_index, eq->core.irqn);
d8f823
+
d8f823
+	eqe_count = mlx5_eq_poll_irq_disabled(eq);
d8f823
+	if (!eqe_count)
d8f823
+		return -EIO;
d8f823
+
d8f823
+	netdev_err(channel->netdev, "Recovered %d eqes on EQ 0x%x\n",
d8f823
+		   eqe_count, eq->core.eqn);
d8f823
+
d8f823
+	channel->stats->eq_rearm++;
d8f823
+	return 0;
d8f823
+}
d8f823
+
d8f823
+int mlx5e_health_report(struct mlx5e_priv *priv,
d8f823
+			struct devlink_health_reporter *reporter, char *err_str,
d8f823
+			struct mlx5e_err_ctx *err_ctx)
d8f823
+{
d8f823
+	if (!reporter) {
d8f823
+		netdev_err(priv->netdev, err_str);
d8f823
+		return err_ctx->recover(&err_ctx->ctx);
d8f823
+	}
d8f823
+	return devlink_health_report(reporter, err_str, err_ctx);
d8f823
+}
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/health.h b/drivers/net/ethernet/mellanox/mlx5/core/en/health.h
d8f823
index c7a5a149011e..386bda6104aa 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/health.h
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/health.h
d8f823
@@ -11,4 +11,18 @@ void mlx5e_reporter_tx_destroy(struct mlx5e_priv *priv);
d8f823
 void mlx5e_reporter_tx_err_cqe(struct mlx5e_txqsq *sq);
d8f823
 int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq);
d8f823
 
d8f823
+#define MLX5E_REPORTER_PER_Q_MAX_LEN 256
d8f823
+
d8f823
+struct mlx5e_err_ctx {
d8f823
+	int (*recover)(void *ctx);
d8f823
+	void *ctx;
d8f823
+};
d8f823
+
d8f823
+int mlx5e_health_sq_to_ready(struct mlx5e_channel *channel, u32 sqn);
d8f823
+int mlx5e_health_channel_eq_recover(struct mlx5_eq_comp *eq, struct mlx5e_channel *channel);
d8f823
+int mlx5e_health_recover_channels(struct mlx5e_priv *priv);
d8f823
+int mlx5e_health_report(struct mlx5e_priv *priv,
d8f823
+			struct devlink_health_reporter *reporter, char *err_str,
d8f823
+			struct mlx5e_err_ctx *err_ctx);
d8f823
+
d8f823
 #endif
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
d8f823
index 62b95f62e4dc..6f9f42ab3005 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
d8f823
@@ -2,14 +2,6 @@
d8f823
 /* Copyright (c) 2019 Mellanox Technologies. */
d8f823
 
d8f823
 #include "health.h"
d8f823
-#include "lib/eq.h"
d8f823
-
d8f823
-#define MLX5E_TX_REPORTER_PER_SQ_MAX_LEN 256
d8f823
-
d8f823
-struct mlx5e_tx_err_ctx {
d8f823
-	int (*recover)(struct mlx5e_txqsq *sq);
d8f823
-	struct mlx5e_txqsq *sq;
d8f823
-};
d8f823
 
d8f823
 static int mlx5e_wait_for_sq_flush(struct mlx5e_txqsq *sq)
d8f823
 {
d8f823
@@ -39,41 +31,20 @@ static void mlx5e_reset_txqsq_cc_pc(struct mlx5e_txqsq *sq)
d8f823
 	sq->pc = 0;
d8f823
 }
d8f823
 
d8f823
-static int mlx5e_sq_to_ready(struct mlx5e_txqsq *sq, int curr_state)
d8f823
+static int mlx5e_tx_reporter_err_cqe_recover(void *ctx)
d8f823
 {
d8f823
-	struct mlx5_core_dev *mdev = sq->channel->mdev;
d8f823
-	struct net_device *dev = sq->channel->netdev;
d8f823
-	struct mlx5e_modify_sq_param msp = {0};
d8f823
+	struct mlx5_core_dev *mdev;
d8f823
+	struct net_device *dev;
d8f823
+	struct mlx5e_txqsq *sq;
d8f823
+	u8 state;
d8f823
 	int err;
d8f823
 
d8f823
-	msp.curr_state = curr_state;
d8f823
-	msp.next_state = MLX5_SQC_STATE_RST;
d8f823
-
d8f823
-	err = mlx5e_modify_sq(mdev, sq->sqn, &msp;;
d8f823
-	if (err) {
d8f823
-		netdev_err(dev, "Failed to move sq 0x%x to reset\n", sq->sqn);
d8f823
-		return err;
d8f823
-	}
d8f823
-
d8f823
-	memset(&msp, 0, sizeof(msp));
d8f823
-	msp.curr_state = MLX5_SQC_STATE_RST;
d8f823
-	msp.next_state = MLX5_SQC_STATE_RDY;
d8f823
-
d8f823
-	err = mlx5e_modify_sq(mdev, sq->sqn, &msp;;
d8f823
-	if (err) {
d8f823
-		netdev_err(dev, "Failed to move sq 0x%x to ready\n", sq->sqn);
d8f823
-		return err;
d8f823
-	}
d8f823
-
d8f823
-	return 0;
d8f823
-}
d8f823
+	sq = ctx;
d8f823
+	mdev = sq->channel->mdev;
d8f823
+	dev = sq->channel->netdev;
d8f823
 
d8f823
-static int mlx5e_tx_reporter_err_cqe_recover(struct mlx5e_txqsq *sq)
d8f823
-{
d8f823
-	struct mlx5_core_dev *mdev = sq->channel->mdev;
d8f823
-	struct net_device *dev = sq->channel->netdev;
d8f823
-	u8 state;
d8f823
-	int err;
d8f823
+	if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state))
d8f823
+		return 0;
d8f823
 
d8f823
 	err = mlx5_core_query_sq_state(mdev, sq->sqn, &state);
d8f823
 	if (err) {
d8f823
@@ -96,7 +67,7 @@ static int mlx5e_tx_reporter_err_cqe_recover(struct mlx5e_txqsq *sq)
d8f823
 	 * pending WQEs. SQ can safely reset the SQ.
d8f823
 	 */
d8f823
 
d8f823
-	err = mlx5e_sq_to_ready(sq, state);
d8f823
+	err = mlx5e_health_sq_to_ready(sq->channel, sq->sqn);
d8f823
 	if (err)
d8f823
 		goto out;
d8f823
 
d8f823
@@ -111,102 +82,66 @@ static int mlx5e_tx_reporter_err_cqe_recover(struct mlx5e_txqsq *sq)
d8f823
 	return err;
d8f823
 }
d8f823
 
d8f823
-static int mlx5_tx_health_report(struct devlink_health_reporter *tx_reporter,
d8f823
-				 char *err_str,
d8f823
-				 struct mlx5e_tx_err_ctx *err_ctx)
d8f823
-{
d8f823
-	if (!tx_reporter) {
d8f823
-		netdev_err(err_ctx->sq->channel->netdev, err_str);
d8f823
-		return err_ctx->recover(err_ctx->sq);
d8f823
-	}
d8f823
-
d8f823
-	return devlink_health_report(tx_reporter, err_str, err_ctx);
d8f823
-}
d8f823
-
d8f823
 void mlx5e_reporter_tx_err_cqe(struct mlx5e_txqsq *sq)
d8f823
 {
d8f823
-	char err_str[MLX5E_TX_REPORTER_PER_SQ_MAX_LEN];
d8f823
-	struct mlx5e_tx_err_ctx err_ctx = {0};
d8f823
+	struct mlx5e_priv *priv = sq->channel->priv;
d8f823
+	char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN];
d8f823
+	struct mlx5e_err_ctx err_ctx = {0};
d8f823
 
d8f823
-	err_ctx.sq       = sq;
d8f823
-	err_ctx.recover  = mlx5e_tx_reporter_err_cqe_recover;
d8f823
+	err_ctx.ctx = sq;
d8f823
+	err_ctx.recover = mlx5e_tx_reporter_err_cqe_recover;
d8f823
 	sprintf(err_str, "ERR CQE on SQ: 0x%x", sq->sqn);
d8f823
 
d8f823
-	mlx5_tx_health_report(sq->channel->priv->tx_reporter, err_str,
d8f823
-			      &err_ctx);
d8f823
+	mlx5e_health_report(priv, priv->tx_reporter, err_str, &err_ctx);
d8f823
 }
d8f823
 
d8f823
-static int mlx5e_tx_reporter_timeout_recover(struct mlx5e_txqsq *sq)
d8f823
+static int mlx5e_tx_reporter_timeout_recover(void *ctx)
d8f823
 {
d8f823
-	struct mlx5_eq_comp *eq = sq->cq.mcq.eq;
d8f823
-	u32 eqe_count;
d8f823
-
d8f823
-	netdev_err(sq->channel->netdev, "EQ 0x%x: Cons = 0x%x, irqn = 0x%x\n",
d8f823
-		   eq->core.eqn, eq->core.cons_index, eq->core.irqn);
d8f823
+	struct mlx5_eq_comp *eq;
d8f823
+	struct mlx5e_txqsq *sq;
d8f823
+	int err;
d8f823
 
d8f823
-	eqe_count = mlx5_eq_poll_irq_disabled(eq);
d8f823
-	if (!eqe_count) {
d8f823
+	sq = ctx;
d8f823
+	eq = sq->cq.mcq.eq;
d8f823
+	err = mlx5e_health_channel_eq_recover(eq, sq->channel);
d8f823
+	if (err)
d8f823
 		clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
d8f823
-		return -EIO;
d8f823
-	}
d8f823
 
d8f823
-	netdev_err(sq->channel->netdev, "Recover %d eqes on EQ 0x%x\n",
d8f823
-		   eqe_count, eq->core.eqn);
d8f823
-	sq->channel->stats->eq_rearm++;
d8f823
-	return 0;
d8f823
+	return err;
d8f823
 }
d8f823
 
d8f823
 int mlx5e_reporter_tx_timeout(struct mlx5e_txqsq *sq)
d8f823
 {
d8f823
-	char err_str[MLX5E_TX_REPORTER_PER_SQ_MAX_LEN];
d8f823
-	struct mlx5e_tx_err_ctx err_ctx;
d8f823
+	struct mlx5e_priv *priv = sq->channel->priv;
d8f823
+	char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN];
d8f823
+	struct mlx5e_err_ctx err_ctx;
d8f823
 
d8f823
-	err_ctx.sq       = sq;
d8f823
-	err_ctx.recover  = mlx5e_tx_reporter_timeout_recover;
d8f823
+	err_ctx.ctx = sq;
d8f823
+	err_ctx.recover = mlx5e_tx_reporter_timeout_recover;
d8f823
 	sprintf(err_str,
d8f823
 		"TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x, usecs since last trans: %u\n",
d8f823
 		sq->channel->ix, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc,
d8f823
 		jiffies_to_usecs(jiffies - sq->txq->trans_start));
d8f823
 
d8f823
-	return mlx5_tx_health_report(sq->channel->priv->tx_reporter, err_str,
d8f823
-				     &err_ctx);
d8f823
+	return mlx5e_health_report(priv, priv->tx_reporter, err_str, &err_ctx);
d8f823
 }
d8f823
 
d8f823
 /* state lock cannot be grabbed within this function.
d8f823
  * It can cause a dead lock or a read-after-free.
d8f823
  */
d8f823
-static int mlx5e_tx_reporter_recover_from_ctx(struct mlx5e_tx_err_ctx *err_ctx)
d8f823
-{
d8f823
-	return err_ctx->recover(err_ctx->sq);
d8f823
-}
d8f823
-
d8f823
-static int mlx5e_tx_reporter_recover_all(struct mlx5e_priv *priv)
d8f823
+static int mlx5e_tx_reporter_recover_from_ctx(struct mlx5e_err_ctx *err_ctx)
d8f823
 {
d8f823
-	int err = 0;
d8f823
-
d8f823
-	rtnl_lock();
d8f823
-	mutex_lock(&priv->state_lock);
d8f823
-
d8f823
-	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
d8f823
-		goto out;
d8f823
-
d8f823
-	err = mlx5e_safe_reopen_channels(priv);
d8f823
-
d8f823
-out:
d8f823
-	mutex_unlock(&priv->state_lock);
d8f823
-	rtnl_unlock();
d8f823
-
d8f823
-	return err;
d8f823
+	return err_ctx->recover(err_ctx->ctx);
d8f823
 }
d8f823
 
d8f823
 static int mlx5e_tx_reporter_recover(struct devlink_health_reporter *reporter,
d8f823
 				     void *context)
d8f823
 {
d8f823
 	struct mlx5e_priv *priv = devlink_health_reporter_priv(reporter);
d8f823
-	struct mlx5e_tx_err_ctx *err_ctx = context;
d8f823
+	struct mlx5e_err_ctx *err_ctx = context;
d8f823
 
d8f823
 	return err_ctx ? mlx5e_tx_reporter_recover_from_ctx(err_ctx) :
d8f823
-			 mlx5e_tx_reporter_recover_all(priv);
d8f823
+			 mlx5e_health_recover_channels(priv);
d8f823
 }
d8f823
 
d8f823
 static int
d8f823
@@ -289,8 +224,9 @@ int mlx5e_reporter_tx_create(struct mlx5e_priv *priv)
d8f823
 {
d8f823
 	struct devlink_health_reporter *reporter;
d8f823
 	struct mlx5_core_dev *mdev = priv->mdev;
d8f823
-	struct devlink *devlink = priv_to_devlink(mdev);
d8f823
+	struct devlink *devlink;
d8f823
 
d8f823
+	devlink = priv_to_devlink(mdev);
d8f823
 	reporter =
d8f823
 		devlink_health_reporter_create(devlink, &mlx5_tx_reporter_ops,
d8f823
 					       MLX5_REPORTER_TX_GRACEFUL_PERIOD,
d8f823
-- 
d8f823
2.13.6
d8f823