All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next 0/7] mlxsw: Offload FDB learning configuration
@ 2016-08-24 10:00 Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 1/7] mlxsw: spectrum: Limit number of FDB records per learning session Jiri Pirko
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Jiri Pirko <jiri@mellanox.com>

Ido says:
This patchset addresses two long standing issues in the mlxsw driver
concerning FDB learning.

Patch 1 limits the number of FDB records processed by the driver in a
single session. This is useful in situations in which many new records
need to be processed, thereby causing the RTNL mutex to be held for
long periods of time.

Patches 2-6 offload the learning configuration (on / off) of bridge
ports to the device instead of having the driver decide whether a
record needs to be learned or not.

The last patch is fallout and removes configuration no longer necessary
after the first patches are applied.

Ido Schimmel (7):
  mlxsw: spectrum: Limit number of FDB records per learning session
  mlxsw: spectrum: Make VLAN deletion function symmetric
  mlxsw: spectrum: Don't abort on first error when removing VLANs
  mlxsw: spectrum: Configure learning for VLAN-aware bridge port
  mlxsw: spectrum: Offload learning to the switch ASIC
  mlxsw: spectrum: Remove unnecessary check in FDB processing
  mlxsw: spectrum: Don't set learning when creating vPorts

 drivers/net/ethernet/mellanox/mlxsw/reg.h          |   7 ++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     |  24 ++--
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h     |   3 +
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 128 +++++++++++++++------
 4 files changed, 115 insertions(+), 47 deletions(-)

-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [patch net-next 1/7] mlxsw: spectrum: Limit number of FDB records per learning session
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
@ 2016-08-24 10:00 ` Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 2/7] mlxsw: spectrum: Make VLAN deletion function symmetric Jiri Pirko
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Ido Schimmel <idosch@mellanox.com>

Up until now a learning session ended whenever the number of queried
records was zero. This turned out to be problematic in situations where
a large number of MACs (48K) had to be processed by the switch driver,
as RTNL mutex is held during the learning session.

Instead, limit the number of FDB records that can be processed in a
session to 64. This means that every time the device is queried for
learning notifications (currently, every 100ms), up to 64 records will
be processed by the switch driver.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h          |  7 +++++++
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 22 ++++++++++------------
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 1721098..b83d0a7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -591,6 +591,12 @@ static const struct mlxsw_reg_info mlxsw_reg_sfn = {
  */
 MLXSW_ITEM32(reg, sfn, swid, 0x00, 24, 8);
 
+/* reg_sfn_end
+ * Forces the current session to end.
+ * Access: OP
+ */
+MLXSW_ITEM32(reg, sfn, end, 0x04, 20, 1);
+
 /* reg_sfn_num_rec
  * Request: Number of learned notifications and aged-out notification
  * records requested.
@@ -605,6 +611,7 @@ static inline void mlxsw_reg_sfn_pack(char *payload)
 {
 	MLXSW_REG_ZERO(sfn, payload);
 	mlxsw_reg_sfn_swid_set(payload, 0);
+	mlxsw_reg_sfn_end_set(payload, 1);
 	mlxsw_reg_sfn_num_rec_set(payload, MLXSW_REG_SFN_REC_MAX_COUNT);
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index d1b59cd..02de240 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1496,20 +1496,18 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
 	mlxsw_sp = container_of(work, struct mlxsw_sp, fdb_notify.dw.work);
 
 	rtnl_lock();
-	do {
-		mlxsw_reg_sfn_pack(sfn_pl);
-		err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(sfn), sfn_pl);
-		if (err) {
-			dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to get FDB notifications\n");
-			break;
-		}
-		num_rec = mlxsw_reg_sfn_num_rec_get(sfn_pl);
-		for (i = 0; i < num_rec; i++)
-			mlxsw_sp_fdb_notify_rec_process(mlxsw_sp, sfn_pl, i);
+	mlxsw_reg_sfn_pack(sfn_pl);
+	err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(sfn), sfn_pl);
+	if (err) {
+		dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to get FDB notifications\n");
+		goto out;
+	}
+	num_rec = mlxsw_reg_sfn_num_rec_get(sfn_pl);
+	for (i = 0; i < num_rec; i++)
+		mlxsw_sp_fdb_notify_rec_process(mlxsw_sp, sfn_pl, i);
 
-	} while (num_rec);
+out:
 	rtnl_unlock();
-
 	kfree(sfn_pl);
 	mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
 }
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [patch net-next 2/7] mlxsw: spectrum: Make VLAN deletion function symmetric
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 1/7] mlxsw: spectrum: Limit number of FDB records per learning session Jiri Pirko
@ 2016-08-24 10:00 ` Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 3/7] mlxsw: spectrum: Don't abort on first error when removing VLANs Jiri Pirko
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Ido Schimmel <idosch@mellanox.com>

Commit 05978481e77e ("mlxsw: spectrum: Create PVID vPort before
registering netdevice") removed __mlxsw_sp_port_vlans_del() from the
init sequence of the driver, which forced it to be non-symmetric with
regards to __mlxsw_sp_port_vlans_add().

Make both functions symmetric as the constraint no longer exists.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 02de240..2f38310 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1008,14 +1008,6 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
 	if (!mlxsw_sp_port->bridged)
 		return -EINVAL;
 
-	err = __mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end,
-					false, false);
-	if (err) {
-		netdev_err(dev, "Unable to del VIDs %d-%d\n", vid_begin,
-			   vid_end);
-		return err;
-	}
-
 	pvid = mlxsw_sp_port->pvid;
 	if (pvid >= vid_begin && pvid <= vid_end) {
 		err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0);
@@ -1025,6 +1017,14 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
 		}
 	}
 
+	err = __mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end,
+					false, false);
+	if (err) {
+		netdev_err(dev, "Unable to del VIDs %d-%d\n", vid_begin,
+			   vid_end);
+		return err;
+	}
+
 	mlxsw_sp_port_fid_leave(mlxsw_sp_port, vid_begin, vid_end);
 
 	/* Changing activity bits only if HW operation succeded */
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [patch net-next 3/7] mlxsw: spectrum: Don't abort on first error when removing VLANs
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 1/7] mlxsw: spectrum: Limit number of FDB records per learning session Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 2/7] mlxsw: spectrum: Make VLAN deletion function symmetric Jiri Pirko
@ 2016-08-24 10:00 ` Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 4/7] mlxsw: spectrum: Configure learning for VLAN-aware bridge port Jiri Pirko
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Ido Schimmel <idosch@mellanox.com>

When removing VLANs from the VLAN-aware bridge we shouldn't abort on the
first error, as we'll otherwise have resources that will never be freed.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 2f38310..e5cf8a5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1001,29 +1001,17 @@ static int mlxsw_sp_port_obj_add(struct net_device *dev,
 static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
 				     u16 vid_begin, u16 vid_end)
 {
-	struct net_device *dev = mlxsw_sp_port->dev;
 	u16 vid, pvid;
-	int err;
 
 	if (!mlxsw_sp_port->bridged)
 		return -EINVAL;
 
 	pvid = mlxsw_sp_port->pvid;
-	if (pvid >= vid_begin && pvid <= vid_end) {
-		err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0);
-		if (err) {
-			netdev_err(dev, "Unable to del PVID %d\n", pvid);
-			return err;
-		}
-	}
+	if (pvid >= vid_begin && pvid <= vid_end)
+		mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0);
 
-	err = __mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end,
-					false, false);
-	if (err) {
-		netdev_err(dev, "Unable to del VIDs %d-%d\n", vid_begin,
-			   vid_end);
-		return err;
-	}
+	__mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end, false,
+				  false);
 
 	mlxsw_sp_port_fid_leave(mlxsw_sp_port, vid_begin, vid_end);
 
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [patch net-next 4/7] mlxsw: spectrum: Configure learning for VLAN-aware bridge port
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
                   ` (2 preceding siblings ...)
  2016-08-24 10:00 ` [patch net-next 3/7] mlxsw: spectrum: Don't abort on first error when removing VLANs Jiri Pirko
@ 2016-08-24 10:00 ` Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 5/7] mlxsw: spectrum: Offload learning to the switch ASIC Jiri Pirko
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Ido Schimmel <idosch@mellanox.com>

We are going to prevent the device from generating learning
notifications for a port that was configured with learning disabled.

Since learning configuration is done per {Port, VID} we need to apply
the port's learning configuration for any VID that is added to the
bridge port's VLAN filter list.

When a VID is added to the VLAN filter list of a VLAN-aware bridge port,
configure the {Port, VID} learning status according to the port's
configuration. When the VID is removed, disable learning for the {Port,
VID}.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     | 16 +++++++---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h     |  3 ++
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 35 ++++++++++++++++++++++
 3 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 1f81689..3820317 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -555,8 +555,9 @@ int mlxsw_sp_port_vid_to_fid_set(struct mlxsw_sp_port *mlxsw_sp_port,
 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
 }
 
-static int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
-					  u16 vid, bool learn_enable)
+int __mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
+				     u16 vid_begin, u16 vid_end,
+				     bool learn_enable)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 	char *spvmlr_pl;
@@ -565,13 +566,20 @@ static int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
 	spvmlr_pl = kmalloc(MLXSW_REG_SPVMLR_LEN, GFP_KERNEL);
 	if (!spvmlr_pl)
 		return -ENOMEM;
-	mlxsw_reg_spvmlr_pack(spvmlr_pl, mlxsw_sp_port->local_port, vid, vid,
-			      learn_enable);
+	mlxsw_reg_spvmlr_pack(spvmlr_pl, mlxsw_sp_port->local_port, vid_begin,
+			      vid_end, learn_enable);
 	err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvmlr), spvmlr_pl);
 	kfree(spvmlr_pl);
 	return err;
 }
 
+static int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
+					  u16 vid, bool learn_enable)
+{
+	return __mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid,
+						learn_enable);
+}
+
 static int
 mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port)
 {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index ab3feb8..01537d3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -558,6 +558,9 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
 int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
 				  enum mlxsw_reg_qeec_hr hr, u8 index,
 				  u8 next_index, u32 maxrate);
+int __mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
+				     u16 vid_begin, u16 vid_end,
+				     bool learn_enable);
 
 #ifdef CONFIG_MLXSW_SPECTRUM_DCB
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index e5cf8a5..d1b2b11 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -635,6 +635,27 @@ static int __mlxsw_sp_port_vlans_set(struct mlxsw_sp_port *mlxsw_sp_port,
 	return 0;
 }
 
+static int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
+					  u16 vid_begin, u16 vid_end,
+					  bool learn_enable)
+{
+	u16 vid, vid_e;
+	int err;
+
+	for (vid = vid_begin; vid <= vid_end;
+	     vid += MLXSW_REG_SPVMLR_REC_MAX_COUNT) {
+		vid_e = min((u16) (vid + MLXSW_REG_SPVMLR_REC_MAX_COUNT - 1),
+			    vid_end);
+
+		err = __mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid,
+						       vid_e, learn_enable);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static int __mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
 				     u16 vid_begin, u16 vid_end,
 				     bool flag_untagged, bool flag_pvid)
@@ -675,6 +696,14 @@ static int __mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
 		}
 	}
 
+	err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid_begin, vid_end,
+					     mlxsw_sp_port->learning);
+	if (err) {
+		netdev_err(dev, "Failed to set learning for VIDs %d-%d\n",
+			   vid_begin, vid_end);
+		goto err_port_vid_learning_set;
+	}
+
 	/* Changing activity bits only if HW operation succeded */
 	for (vid = vid_begin; vid <= vid_end; vid++) {
 		set_bit(vid, mlxsw_sp_port->active_vlans);
@@ -697,6 +726,9 @@ static int __mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
 err_port_stp_state_set:
 	for (vid = vid_begin; vid <= vid_end; vid++)
 		clear_bit(vid, mlxsw_sp_port->active_vlans);
+	mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid_begin, vid_end,
+				       false);
+err_port_vid_learning_set:
 	if (old_pvid != mlxsw_sp_port->pvid)
 		mlxsw_sp_port_pvid_set(mlxsw_sp_port, old_pvid);
 err_port_pvid_set:
@@ -1006,6 +1038,9 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
 	if (!mlxsw_sp_port->bridged)
 		return -EINVAL;
 
+	mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid_begin, vid_end,
+				       false);
+
 	pvid = mlxsw_sp_port->pvid;
 	if (pvid >= vid_begin && pvid <= vid_end)
 		mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0);
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [patch net-next 5/7] mlxsw: spectrum: Offload learning to the switch ASIC
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
                   ` (3 preceding siblings ...)
  2016-08-24 10:00 ` [patch net-next 4/7] mlxsw: spectrum: Configure learning for VLAN-aware bridge port Jiri Pirko
@ 2016-08-24 10:00 ` Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 6/7] mlxsw: spectrum: Remove unnecessary check in FDB processing Jiri Pirko
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Ido Schimmel <idosch@mellanox.com>

Up until now we simply stored the learning configuration of a bridge
port in the driver and decided whether to learn a new FDB record based
on this value.

However, this is sub-optimal in cases where learning is disabled on the
bridge port, as the device repeatedly generates learning notifications
for the same record.

Instead, offload the learning configuration to the device, thereby
preventing it from generating notifications when learning is disabled.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 47 ++++++++++++++++++++--
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index d1b2b11..e0a7232 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -261,12 +261,40 @@ int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
 					 false);
 }
 
+static int mlxsw_sp_port_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
+				      bool set)
+{
+	u16 vid;
+	int err;
+
+	if (mlxsw_sp_port_is_vport(mlxsw_sp_port)) {
+		vid = mlxsw_sp_vport_vid_get(mlxsw_sp_port);
+
+		return __mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid,
+							set);
+	}
+
+	for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) {
+		err = __mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid,
+						       set);
+		if (err)
+			goto err_port_vid_learning_set;
+	}
+
+	return 0;
+
+err_port_vid_learning_set:
+	for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID)
+		__mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid, !set);
+	return err;
+}
+
 static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
 					   struct switchdev_trans *trans,
 					   unsigned long brport_flags)
 {
+	unsigned long learning = mlxsw_sp_port->learning ? BR_LEARNING : 0;
 	unsigned long uc_flood = mlxsw_sp_port->uc_flood ? BR_FLOOD : 0;
-	bool set;
 	int err;
 
 	if (!mlxsw_sp_port->bridged)
@@ -276,17 +304,30 @@ static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
 		return 0;
 
 	if ((uc_flood ^ brport_flags) & BR_FLOOD) {
-		set = mlxsw_sp_port->uc_flood ? false : true;
-		err = mlxsw_sp_port_uc_flood_set(mlxsw_sp_port, set);
+		err = mlxsw_sp_port_uc_flood_set(mlxsw_sp_port,
+						 !mlxsw_sp_port->uc_flood);
 		if (err)
 			return err;
 	}
 
+	if ((learning ^ brport_flags) & BR_LEARNING) {
+		err = mlxsw_sp_port_learning_set(mlxsw_sp_port,
+						 !mlxsw_sp_port->learning);
+		if (err)
+			goto err_port_learning_set;
+	}
+
 	mlxsw_sp_port->uc_flood = brport_flags & BR_FLOOD ? 1 : 0;
 	mlxsw_sp_port->learning = brport_flags & BR_LEARNING ? 1 : 0;
 	mlxsw_sp_port->learning_sync = brport_flags & BR_LEARNING_SYNC ? 1 : 0;
 
 	return 0;
+
+err_port_learning_set:
+	if ((uc_flood ^ brport_flags) & BR_FLOOD)
+		mlxsw_sp_port_uc_flood_set(mlxsw_sp_port,
+					   mlxsw_sp_port->uc_flood);
+	return err;
 }
 
 static int mlxsw_sp_ageing_set(struct mlxsw_sp *mlxsw_sp, u32 ageing_time)
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [patch net-next 6/7] mlxsw: spectrum: Remove unnecessary check in FDB processing
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
                   ` (4 preceding siblings ...)
  2016-08-24 10:00 ` [patch net-next 5/7] mlxsw: spectrum: Offload learning to the switch ASIC Jiri Pirko
@ 2016-08-24 10:00 ` Jiri Pirko
  2016-08-24 10:00 ` [patch net-next 7/7] mlxsw: spectrum: Don't set learning when creating vPorts Jiri Pirko
  2016-08-24 16:41 ` [patch net-next 0/7] mlxsw: Offload FDB learning configuration David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Ido Schimmel <idosch@mellanox.com>

We now offload the learning configuration to the device and don't rely
on the driver to decide whether to learn the FDB record, so remove the
check.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index e0a7232..0c3fbbc 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1430,8 +1430,6 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
 		vid = fid;
 	}
 
-	adding = adding && mlxsw_sp_port->learning;
-
 do_fdb_op:
 	err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid,
 				      adding, true);
@@ -1493,8 +1491,6 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
 		vid = fid;
 	}
 
-	adding = adding && mlxsw_sp_port->learning;
-
 do_fdb_op:
 	err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid,
 					  adding, true);
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [patch net-next 7/7] mlxsw: spectrum: Don't set learning when creating vPorts
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
                   ` (5 preceding siblings ...)
  2016-08-24 10:00 ` [patch net-next 6/7] mlxsw: spectrum: Remove unnecessary check in FDB processing Jiri Pirko
@ 2016-08-24 10:00 ` Jiri Pirko
  2016-08-24 16:41 ` [patch net-next 0/7] mlxsw: Offload FDB learning configuration David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Jiri Pirko @ 2016-08-24 10:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz

From: Ido Schimmel <idosch@mellanox.com>

Before commit 99724c18fc66 ("mlxsw: spectrum: Introduce support for
router interfaces") we used to assign vFIDs to the created vPorts. Since
these vPorts were used for slow path traffic we had to disable learning
for them, as it doesn't make sense to have it enabled.

This is no longer the case and now vPorts are either used for router
interfaces (for which learning is disabled by the firmware) or bridge
ports (for which learning is explicitly enabled by the driver).

Therefore, we can remove the learning configuration upon vPort creation.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 3820317..2713a64 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -981,10 +981,6 @@ static int mlxsw_sp_port_add_vid(struct net_device *dev,
 			goto err_port_vp_mode_trans;
 	}
 
-	err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false);
-	if (err)
-		goto err_port_vid_learning_set;
-
 	err = mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, true, untagged);
 	if (err)
 		goto err_port_add_vid;
@@ -992,8 +988,6 @@ static int mlxsw_sp_port_add_vid(struct net_device *dev,
 	return 0;
 
 err_port_add_vid:
-	mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
-err_port_vid_learning_set:
 	if (list_is_singular(&mlxsw_sp_port->vports_list))
 		mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
 err_port_vp_mode_trans:
@@ -1020,8 +1014,6 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
 
 	mlxsw_sp_port_vlan_set(mlxsw_sp_vport, vid, vid, false, false);
 
-	mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, true);
-
 	/* Drop FID reference. If this was the last reference the
 	 * resources will be freed.
 	 */
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [patch net-next 0/7] mlxsw: Offload FDB learning configuration
  2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
                   ` (6 preceding siblings ...)
  2016-08-24 10:00 ` [patch net-next 7/7] mlxsw: spectrum: Don't set learning when creating vPorts Jiri Pirko
@ 2016-08-24 16:41 ` David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2016-08-24 16:41 UTC (permalink / raw)
  To: jiri; +Cc: netdev, idosch, eladr, yotamg, nogahf, ogerlitz

From: Jiri Pirko <jiri@resnulli.us>
Date: Wed, 24 Aug 2016 12:00:22 +0200

> From: Jiri Pirko <jiri@mellanox.com>
> 
> Ido says:
> This patchset addresses two long standing issues in the mlxsw driver
> concerning FDB learning.
> 
> Patch 1 limits the number of FDB records processed by the driver in a
> single session. This is useful in situations in which many new records
> need to be processed, thereby causing the RTNL mutex to be held for
> long periods of time.
> 
> Patches 2-6 offload the learning configuration (on / off) of bridge
> ports to the device instead of having the driver decide whether a
> record needs to be learned or not.
> 
> The last patch is fallout and removes configuration no longer necessary
> after the first patches are applied.

Looks good, series applied, thanks!

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-08-24 16:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-24 10:00 [patch net-next 0/7] mlxsw: Offload FDB learning configuration Jiri Pirko
2016-08-24 10:00 ` [patch net-next 1/7] mlxsw: spectrum: Limit number of FDB records per learning session Jiri Pirko
2016-08-24 10:00 ` [patch net-next 2/7] mlxsw: spectrum: Make VLAN deletion function symmetric Jiri Pirko
2016-08-24 10:00 ` [patch net-next 3/7] mlxsw: spectrum: Don't abort on first error when removing VLANs Jiri Pirko
2016-08-24 10:00 ` [patch net-next 4/7] mlxsw: spectrum: Configure learning for VLAN-aware bridge port Jiri Pirko
2016-08-24 10:00 ` [patch net-next 5/7] mlxsw: spectrum: Offload learning to the switch ASIC Jiri Pirko
2016-08-24 10:00 ` [patch net-next 6/7] mlxsw: spectrum: Remove unnecessary check in FDB processing Jiri Pirko
2016-08-24 10:00 ` [patch net-next 7/7] mlxsw: spectrum: Don't set learning when creating vPorts Jiri Pirko
2016-08-24 16:41 ` [patch net-next 0/7] mlxsw: Offload FDB learning configuration David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.