Blob Blame History Raw
From: Ido Schimmel <idosch@mellanox.com>
Date: Fri, 21 Feb 2020 19:54:11 +0200
Subject: mlxsw: spectrum_dpipe: Take router lock from dpipe code
Patch-mainline: v5.7-rc1
Git-commit: 6a5c69cd5512b450816fa75b46ac244a980ad09f
References: bsc#1176774

The dpipe code traverses internal router structures such as neighbours
and adjacency entries and dumps them to user space via netlink. Up until
now the routing code did not have its own locks and relied on RTNL lock
to serialize access. This is going to change with the introduction of
the router lock.

Take the router lock in the code paths where RTNL lock is currently
taken so that the latter could be removed by subsequent patches.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
@@ -2,6 +2,7 @@
 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
 
 #include <linux/kernel.h>
+#include <linux/mutex.h>
 #include <net/devlink.h>
 
 #include "spectrum.h"
@@ -211,6 +212,7 @@ mlxsw_sp_dpipe_table_erif_entries_dump(v
 
 	rif_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
 	rtnl_lock();
+	mutex_lock(&mlxsw_sp->router->lock);
 	i = 0;
 start_again:
 	err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
@@ -241,6 +243,7 @@ start_again:
 	devlink_dpipe_entry_ctx_close(dump_ctx);
 	if (i != rif_count)
 		goto start_again;
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 
 	devlink_dpipe_entry_clear(&entry);
@@ -248,6 +251,7 @@ start_again:
 err_entry_append:
 err_entry_get:
 err_ctx_prepare:
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 	devlink_dpipe_entry_clear(&entry);
 	return err;
@@ -259,6 +263,7 @@ static int mlxsw_sp_dpipe_table_erif_cou
 	int i;
 
 	rtnl_lock();
+	mutex_lock(&mlxsw_sp->router->lock);
 	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
 		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
 
@@ -271,6 +276,7 @@ static int mlxsw_sp_dpipe_table_erif_cou
 			mlxsw_sp_rif_counter_free(mlxsw_sp, rif,
 						  MLXSW_SP_RIF_COUNTER_EGRESS);
 	}
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 	return 0;
 }
@@ -547,6 +553,7 @@ mlxsw_sp_dpipe_table_host_entries_get(st
 	int err;
 
 	rtnl_lock();
+	mutex_lock(&mlxsw_sp->router->lock);
 	i = 0;
 	rif_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
 start_again:
@@ -602,11 +609,13 @@ out:
 	if (i != rif_count)
 		goto start_again;
 
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 	return 0;
 
 err_ctx_prepare:
 err_entry_append:
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 	return err;
 }
@@ -663,6 +672,7 @@ mlxsw_sp_dpipe_table_host_counters_updat
 	int i;
 
 	rtnl_lock();
+	mutex_lock(&mlxsw_sp->router->lock);
 	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
 		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
 		struct mlxsw_sp_neigh_entry *neigh_entry;
@@ -684,6 +694,7 @@ mlxsw_sp_dpipe_table_host_counters_updat
 							    enable);
 		}
 	}
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 }
 
@@ -702,6 +713,7 @@ mlxsw_sp_dpipe_table_host_size_get(struc
 	int i;
 
 	rtnl_lock();
+	mutex_lock(&mlxsw_sp->router->lock);
 	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
 		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
 		struct mlxsw_sp_neigh_entry *neigh_entry;
@@ -721,6 +733,7 @@ mlxsw_sp_dpipe_table_host_size_get(struc
 			size++;
 		}
 	}
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 
 	return size;
@@ -1094,6 +1107,7 @@ mlxsw_sp_dpipe_table_adj_entries_get(str
 	int err;
 
 	rtnl_lock();
+	mutex_lock(&mlxsw_sp->router->lock);
 	nh_count_max = mlxsw_sp_dpipe_table_adj_size(mlxsw_sp);
 start_again:
 	err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
@@ -1130,12 +1144,14 @@ skip:
 	devlink_dpipe_entry_ctx_close(dump_ctx);
 	if (nh_count != nh_count_max)
 		goto start_again;
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 
 	return 0;
 
 err_ctx_prepare:
 err_entry_append:
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 	return err;
 }
@@ -1207,7 +1223,9 @@ mlxsw_sp_dpipe_table_adj_size_get(void *
 	u64 size;
 
 	rtnl_lock();
+	mutex_lock(&mlxsw_sp->router->lock);
 	size = mlxsw_sp_dpipe_table_adj_size(mlxsw_sp);
+	mutex_unlock(&mlxsw_sp->router->lock);
 	rtnl_unlock();
 
 	return size;