lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200220070800.364235-6-idosch@idosch.org>
Date:   Thu, 20 Feb 2020 09:07:50 +0200
From:   Ido Schimmel <idosch@...sch.org>
To:     netdev@...r.kernel.org
Cc:     davem@...emloft.net, jiri@...lanox.com, mlxsw@...lanox.com,
        Ido Schimmel <idosch@...lanox.com>
Subject: [PATCH net-next 05/15] mlxsw: spectrum_span: Prepare work item to update mirroring agents

From: Ido Schimmel <idosch@...lanox.com>

The driver updates its mirroring agents whenever it receives a
notification about an event that can affect these. For example, the
addition of a route might require the driver to change the egress port
of an ERSPAN session.

Currently, RTNL needs to be held when these agents are updates, so the
driver either:

1. Calls directly into the mirroring code, in case RTNL is held

2. Schedules a work item that will take RTNL and call into the mirroring
code

Simplify this by having the mirroring code schedule the work item for
the update instead of requiring callers to schedule a work item
themselves.

The conversion of the callers will be done in the next patch to make
review easier.

This will later allow us to remove RTNL from different parts of the
driver. It will also allow us to only schedule the work item in case
there are active mirroring agents, which is information private to the
mirroring code.

Signed-off-by: Ido Schimmel <idosch@...lanox.com>
Acked-by: Jiri Pirko <jiri@...lanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_span.c   | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index aeb28486635c..24fd42d79607 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -3,6 +3,8 @@
 
 #include <linux/if_bridge.h>
 #include <linux/list.h>
+#include <linux/rtnetlink.h>
+#include <linux/workqueue.h>
 #include <net/arp.h>
 #include <net/gre.h>
 #include <net/lag.h>
@@ -15,10 +17,14 @@
 #include "spectrum_switchdev.h"
 
 struct mlxsw_sp_span {
+	struct work_struct work;
+	struct mlxsw_sp *mlxsw_sp;
 	int entries_count;
 	struct mlxsw_sp_span_entry entries[0];
 };
 
+static void mlxsw_sp_span_respin_work(struct work_struct *work);
+
 static u64 mlxsw_sp_span_occ_get(void *priv)
 {
 	const struct mlxsw_sp *mlxsw_sp = priv;
@@ -47,6 +53,7 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
 	if (!span)
 		return -ENOMEM;
 	span->entries_count = entries_count;
+	span->mlxsw_sp = mlxsw_sp;
 	mlxsw_sp->span = span;
 
 	for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
@@ -58,6 +65,7 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp)
 
 	devlink_resource_occ_get_register(devlink, MLXSW_SP_RESOURCE_SPAN,
 					  mlxsw_sp_span_occ_get, mlxsw_sp);
+	INIT_WORK(&span->work, mlxsw_sp_span_respin_work);
 
 	return 0;
 }
@@ -67,6 +75,7 @@ void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
 	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
 	int i;
 
+	cancel_work_sync(&mlxsw_sp->span->work);
 	devlink_resource_occ_get_unregister(devlink, MLXSW_SP_RESOURCE_SPAN);
 
 	for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
@@ -1016,3 +1025,32 @@ void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
 		}
 	}
 }
+
+static void mlxsw_sp_span_respin_work(struct work_struct *work)
+{
+	struct mlxsw_sp_span *span;
+	struct mlxsw_sp *mlxsw_sp;
+	int i, err;
+
+	span = container_of(work, struct mlxsw_sp_span, work);
+	mlxsw_sp = span->mlxsw_sp;
+
+	rtnl_lock();
+	for (i = 0; i < mlxsw_sp->span->entries_count; i++) {
+		struct mlxsw_sp_span_entry *curr = &mlxsw_sp->span->entries[i];
+		struct mlxsw_sp_span_parms sparms = {NULL};
+
+		if (!curr->ref_count)
+			continue;
+
+		err = curr->ops->parms(curr->to_dev, &sparms);
+		if (err)
+			continue;
+
+		if (memcmp(&sparms, &curr->parms, sizeof(sparms))) {
+			mlxsw_sp_span_entry_deconfigure(curr);
+			mlxsw_sp_span_entry_configure(mlxsw_sp, curr, sparms);
+		}
+	}
+	rtnl_unlock();
+}
-- 
2.24.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ