Blame SOURCES/0174-netdrv-net-mlx5e-Allow-mlx5e_switch_priv_channels-to.patch

d8f823
From a60735875b83703004c3c0cefa1afe5c28bfbb7c Mon Sep 17 00:00:00 2001
d8f823
From: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Date: Tue, 12 May 2020 10:54:46 -0400
d8f823
Subject: [PATCH 174/312] [netdrv] net/mlx5e: Allow mlx5e_switch_priv_channels
d8f823
 to fail and recover
d8f823
d8f823
Message-id: <20200512105530.4207-81-ahleihel@redhat.com>
d8f823
Patchwork-id: 306952
d8f823
Patchwork-instance: patchwork
d8f823
O-Subject: [RHEL8.3 BZ 1789382 080/124] net/mlx5e: Allow mlx5e_switch_priv_channels to fail and recover
d8f823
Bugzilla: 1789382
d8f823
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
d8f823
RH-Acked-by: Kamal Heib <kheib@redhat.com>
d8f823
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
d8f823
d8f823
Bugzilla: http://bugzilla.redhat.com/1789382
d8f823
Upstream: v5.7-rc1
d8f823
d8f823
commit 35a78ed4c351319e8840d99ba9032bf2d175e168
d8f823
Author: Maxim Mikityanskiy <maximmi@mellanox.com>
d8f823
Date:   Wed Nov 13 18:07:29 2019 +0200
d8f823
d8f823
    net/mlx5e: Allow mlx5e_switch_priv_channels to fail and recover
d8f823
d8f823
    Currently mlx5e_switch_priv_channels expects that the preactivate hook
d8f823
    doesn't fail, however, it can fail, because it may set hardware
d8f823
    parameters. This commit addresses this issue and provides a way to
d8f823
    recover from failures of the preactivate hook: the old channels are not
d8f823
    closed until the point where nothing can fail anymore, so in case
d8f823
    preactivate fails, the driver can roll back the old channels and
d8f823
    activate them again.
d8f823
d8f823
    Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
d8f823
    Reviewed-by: Tariq Toukan <tariqt@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/en_main.c | 34 ++++++++++++++++++-----
d8f823
 1 file changed, 27 insertions(+), 7 deletions(-)
d8f823
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
d8f823
index ae91592165ea..390db68727ff 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
d8f823
@@ -2955,33 +2955,45 @@ void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
d8f823
 	mlx5e_deactivate_channels(&priv->channels);
d8f823
 }
d8f823
 
d8f823
-static void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
d8f823
-				       struct mlx5e_channels *new_chs,
d8f823
-				       mlx5e_fp_preactivate preactivate)
d8f823
+static int mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
d8f823
+				      struct mlx5e_channels *new_chs,
d8f823
+				      mlx5e_fp_preactivate preactivate)
d8f823
 {
d8f823
 	struct net_device *netdev = priv->netdev;
d8f823
+	struct mlx5e_channels old_chs;
d8f823
 	int carrier_ok;
d8f823
+	int err = 0;
d8f823
 
d8f823
 	carrier_ok = netif_carrier_ok(netdev);
d8f823
 	netif_carrier_off(netdev);
d8f823
 
d8f823
 	mlx5e_deactivate_priv_channels(priv);
d8f823
-	mlx5e_close_channels(&priv->channels);
d8f823
 
d8f823
+	old_chs = priv->channels;
d8f823
 	priv->channels = *new_chs;
d8f823
 
d8f823
 	/* New channels are ready to roll, call the preactivate hook if needed
d8f823
 	 * to modify HW settings or update kernel parameters.
d8f823
 	 */
d8f823
-	if (preactivate)
d8f823
-		preactivate(priv);
d8f823
+	if (preactivate) {
d8f823
+		err = preactivate(priv);
d8f823
+		if (err) {
d8f823
+			priv->channels = old_chs;
d8f823
+			goto out;
d8f823
+		}
d8f823
+	}
d8f823
 
d8f823
+	mlx5e_close_channels(&old_chs);
d8f823
 	priv->profile->update_rx(priv);
d8f823
+
d8f823
+out:
d8f823
 	mlx5e_activate_priv_channels(priv);
d8f823
 
d8f823
 	/* return carrier back if needed */
d8f823
 	if (carrier_ok)
d8f823
 		netif_carrier_on(netdev);
d8f823
+
d8f823
+	return err;
d8f823
 }
d8f823
 
d8f823
 int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
d8f823
@@ -2994,8 +3006,16 @@ int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
d8f823
 	if (err)
d8f823
 		return err;
d8f823
 
d8f823
-	mlx5e_switch_priv_channels(priv, new_chs, preactivate);
d8f823
+	err = mlx5e_switch_priv_channels(priv, new_chs, preactivate);
d8f823
+	if (err)
d8f823
+		goto err_close;
d8f823
+
d8f823
 	return 0;
d8f823
+
d8f823
+err_close:
d8f823
+	mlx5e_close_channels(new_chs);
d8f823
+
d8f823
+	return err;
d8f823
 }
d8f823
 
d8f823
 int mlx5e_safe_reopen_channels(struct mlx5e_priv *priv)
d8f823
-- 
d8f823
2.13.6
d8f823