Commit 1803e0fb authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum: Limit number of FDB records per learning session

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: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fff84d2a
...@@ -591,6 +591,12 @@ static const struct mlxsw_reg_info mlxsw_reg_sfn = { ...@@ -591,6 +591,12 @@ static const struct mlxsw_reg_info mlxsw_reg_sfn = {
*/ */
MLXSW_ITEM32(reg, sfn, swid, 0x00, 24, 8); 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 /* reg_sfn_num_rec
* Request: Number of learned notifications and aged-out notification * Request: Number of learned notifications and aged-out notification
* records requested. * records requested.
...@@ -605,6 +611,7 @@ static inline void mlxsw_reg_sfn_pack(char *payload) ...@@ -605,6 +611,7 @@ static inline void mlxsw_reg_sfn_pack(char *payload)
{ {
MLXSW_REG_ZERO(sfn, payload); MLXSW_REG_ZERO(sfn, payload);
mlxsw_reg_sfn_swid_set(payload, 0); 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); mlxsw_reg_sfn_num_rec_set(payload, MLXSW_REG_SFN_REC_MAX_COUNT);
} }
......
...@@ -1496,20 +1496,18 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work) ...@@ -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); mlxsw_sp = container_of(work, struct mlxsw_sp, fdb_notify.dw.work);
rtnl_lock(); rtnl_lock();
do { mlxsw_reg_sfn_pack(sfn_pl);
mlxsw_reg_sfn_pack(sfn_pl); err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(sfn), sfn_pl);
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(sfn), sfn_pl); if (err) {
if (err) { dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to get FDB notifications\n");
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to get FDB notifications\n"); goto out;
break; }
} num_rec = mlxsw_reg_sfn_num_rec_get(sfn_pl);
num_rec = mlxsw_reg_sfn_num_rec_get(sfn_pl); for (i = 0; i < num_rec; i++)
for (i = 0; i < num_rec; i++) mlxsw_sp_fdb_notify_rec_process(mlxsw_sp, sfn_pl, i);
mlxsw_sp_fdb_notify_rec_process(mlxsw_sp, sfn_pl, i);
} while (num_rec); out:
rtnl_unlock(); rtnl_unlock();
kfree(sfn_pl); kfree(sfn_pl);
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp); mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment