Takashi Iwai 14a3a1
From 1eaee3960114d3889f658e54006284a58d709f41 Mon Sep 17 00:00:00 2001
Takashi Iwai 14a3a1
From: Leon Romanovsky <leonro@nvidia.com>
Takashi Iwai 14a3a1
Date: Wed, 28 Jul 2021 10:33:45 +0300
Takashi Iwai 14a3a1
Subject: [PATCH] net: ti: am65-cpsw-nuss: fix wrong devlink release order
Takashi Iwai 14a3a1
Git-commit: acf34954efd17d4f65c7bb3e614381e6afc33222
Takashi Iwai 14a3a1
Patch-mainline: v5.15-rc1
Takashi Iwai 14a3a1
References: stable-5.14.4
Takashi Iwai 14a3a1
Takashi Iwai 14a3a1
[ Upstream commit acf34954efd17d4f65c7bb3e614381e6afc33222 ]
Takashi Iwai 14a3a1
Takashi Iwai 14a3a1
The commit that introduced devlink support released devlink resources in
Takashi Iwai 14a3a1
wrong order, that made an unwind flow to be asymmetrical. In addition,
Takashi Iwai 14a3a1
the am65-cpsw-nuss used internal to devlink core field - registered.
Takashi Iwai 14a3a1
Takashi Iwai 14a3a1
In order to fix the unwind flow and remove such access to the
Takashi Iwai 14a3a1
registered field, rewrite the code to call devlink_port_unregister only
Takashi Iwai 14a3a1
on registered ports.
Takashi Iwai 14a3a1
Takashi Iwai 14a3a1
Fixes: 58356eb31d60 ("net: ti: am65-cpsw-nuss: Add devlink support")
Takashi Iwai 14a3a1
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Takashi Iwai 14a3a1
Signed-off-by: David S. Miller <davem@davemloft.net>
Takashi Iwai 14a3a1
Signed-off-by: Sasha Levin <sashal@kernel.org>
Takashi Iwai 14a3a1
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 14a3a1
Takashi Iwai 14a3a1
---
Takashi Iwai 14a3a1
 drivers/net/ethernet/ti/am65-cpsw-nuss.c | 34 ++++++++++++------------
Takashi Iwai 14a3a1
 1 file changed, 17 insertions(+), 17 deletions(-)
Takashi Iwai 14a3a1
Takashi Iwai 14a3a1
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
Takashi Iwai 14a3a1
index 67a08cbba859..fb58fc470773 100644
Takashi Iwai 14a3a1
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
Takashi Iwai 14a3a1
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
Takashi Iwai 14a3a1
@@ -2388,21 +2388,6 @@ static const struct devlink_param am65_cpsw_devlink_params[] = {
Takashi Iwai 14a3a1
 			     am65_cpsw_dl_switch_mode_set, NULL),
Takashi Iwai 14a3a1
 };
Takashi Iwai 14a3a1
 
Takashi Iwai 14a3a1
-static void am65_cpsw_unregister_devlink_ports(struct am65_cpsw_common *common)
Takashi Iwai 14a3a1
-{
Takashi Iwai 14a3a1
-	struct devlink_port *dl_port;
Takashi Iwai 14a3a1
-	struct am65_cpsw_port *port;
Takashi Iwai 14a3a1
-	int i;
Takashi Iwai 14a3a1
-
Takashi Iwai 14a3a1
-	for (i = 1; i <= common->port_num; i++) {
Takashi Iwai 14a3a1
-		port = am65_common_get_port(common, i);
Takashi Iwai 14a3a1
-		dl_port = &port->devlink_port;
Takashi Iwai 14a3a1
-
Takashi Iwai 14a3a1
-		if (dl_port->registered)
Takashi Iwai 14a3a1
-			devlink_port_unregister(dl_port);
Takashi Iwai 14a3a1
-	}
Takashi Iwai 14a3a1
-}
Takashi Iwai 14a3a1
-
Takashi Iwai 14a3a1
 static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
Takashi Iwai 14a3a1
 {
Takashi Iwai 14a3a1
 	struct devlink_port_attrs attrs = {};
Takashi Iwai 14a3a1
@@ -2464,7 +2449,12 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
Takashi Iwai 14a3a1
 	return ret;
Takashi Iwai 14a3a1
 
Takashi Iwai 14a3a1
 dl_port_unreg:
Takashi Iwai 14a3a1
-	am65_cpsw_unregister_devlink_ports(common);
Takashi Iwai 14a3a1
+	for (i = i - 1; i >= 1; i--) {
Takashi Iwai 14a3a1
+		port = am65_common_get_port(common, i);
Takashi Iwai 14a3a1
+		dl_port = &port->devlink_port;
Takashi Iwai 14a3a1
+
Takashi Iwai 14a3a1
+		devlink_port_unregister(dl_port);
Takashi Iwai 14a3a1
+	}
Takashi Iwai 14a3a1
 dl_unreg:
Takashi Iwai 14a3a1
 	devlink_unregister(common->devlink);
Takashi Iwai 14a3a1
 dl_free:
Takashi Iwai 14a3a1
@@ -2475,6 +2465,17 @@ static int am65_cpsw_nuss_register_devlink(struct am65_cpsw_common *common)
Takashi Iwai 14a3a1
 
Takashi Iwai 14a3a1
 static void am65_cpsw_unregister_devlink(struct am65_cpsw_common *common)
Takashi Iwai 14a3a1
 {
Takashi Iwai 14a3a1
+	struct devlink_port *dl_port;
Takashi Iwai 14a3a1
+	struct am65_cpsw_port *port;
Takashi Iwai 14a3a1
+	int i;
Takashi Iwai 14a3a1
+
Takashi Iwai 14a3a1
+	for (i = 1; i <= common->port_num; i++) {
Takashi Iwai 14a3a1
+		port = am65_common_get_port(common, i);
Takashi Iwai 14a3a1
+		dl_port = &port->devlink_port;
Takashi Iwai 14a3a1
+
Takashi Iwai 14a3a1
+		devlink_port_unregister(dl_port);
Takashi Iwai 14a3a1
+	}
Takashi Iwai 14a3a1
+
Takashi Iwai 14a3a1
 	if (!AM65_CPSW_IS_CPSW2G(common) &&
Takashi Iwai 14a3a1
 	    IS_ENABLED(CONFIG_TI_K3_AM65_CPSW_SWITCHDEV)) {
Takashi Iwai 14a3a1
 		devlink_params_unpublish(common->devlink);
Takashi Iwai 14a3a1
@@ -2482,7 +2483,6 @@ static void am65_cpsw_unregister_devlink(struct am65_cpsw_common *common)
Takashi Iwai 14a3a1
 					  ARRAY_SIZE(am65_cpsw_devlink_params));
Takashi Iwai 14a3a1
 	}
Takashi Iwai 14a3a1
 
Takashi Iwai 14a3a1
-	am65_cpsw_unregister_devlink_ports(common);
Takashi Iwai 14a3a1
 	devlink_unregister(common->devlink);
Takashi Iwai 14a3a1
 	devlink_free(common->devlink);
Takashi Iwai 14a3a1
 }
Takashi Iwai 14a3a1
-- 
Takashi Iwai 14a3a1
2.26.2
Takashi Iwai 14a3a1