mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-20 12:59:33 +07:00
mlxsw: spectrum_switchdev: Optimize SFN records processing
Currently, only one SFN query is done from repetitive work at a time, processing 64 entries. Another work iteration is scheduled in 100ms, that means that the max rate of learned FDB entries is limited to 6400/s. That is slow. Fix this by doing 2 optimizations: 1) Run 10 SFN queries at a time. 2) In case the SFN is not drained, schedule work with 0 delay to allow to continue processing rest of the records. On a testing setup with 500K entries the time to process decreased from 870secs to 10secs. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Tested-by: Alex Kushnarov <alexanderk@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c535f92032
commit
648e53cac7
@ -621,7 +621,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_end_set(payload, 0);
|
||||
mlxsw_reg_sfn_num_rec_set(payload, MLXSW_REG_SFN_REC_MAX_COUNT);
|
||||
}
|
||||
|
||||
|
@ -2674,19 +2674,24 @@ static void mlxsw_sp_fdb_notify_rec_process(struct mlxsw_sp *mlxsw_sp,
|
||||
}
|
||||
}
|
||||
|
||||
static void mlxsw_sp_fdb_notify_work_schedule(struct mlxsw_sp *mlxsw_sp)
|
||||
static void mlxsw_sp_fdb_notify_work_schedule(struct mlxsw_sp *mlxsw_sp,
|
||||
bool no_delay)
|
||||
{
|
||||
struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
|
||||
unsigned int interval = no_delay ? 0 : bridge->fdb_notify.interval;
|
||||
|
||||
mlxsw_core_schedule_dw(&bridge->fdb_notify.dw,
|
||||
msecs_to_jiffies(bridge->fdb_notify.interval));
|
||||
msecs_to_jiffies(interval));
|
||||
}
|
||||
|
||||
#define MLXSW_SP_FDB_SFN_QUERIES_PER_SESSION 10
|
||||
|
||||
static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
|
||||
{
|
||||
struct mlxsw_sp_bridge *bridge;
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
char *sfn_pl;
|
||||
int queries;
|
||||
u8 num_rec;
|
||||
int i;
|
||||
int err;
|
||||
@ -2699,20 +2704,26 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
|
||||
mlxsw_sp = bridge->mlxsw_sp;
|
||||
|
||||
rtnl_lock();
|
||||
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;
|
||||
queries = MLXSW_SP_FDB_SFN_QUERIES_PER_SESSION;
|
||||
while (queries > 0) {
|
||||
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);
|
||||
if (num_rec != MLXSW_REG_SFN_REC_MAX_COUNT)
|
||||
goto out;
|
||||
queries--;
|
||||
}
|
||||
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);
|
||||
|
||||
out:
|
||||
rtnl_unlock();
|
||||
kfree(sfn_pl);
|
||||
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
|
||||
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp, !queries);
|
||||
}
|
||||
|
||||
struct mlxsw_sp_switchdev_event_work {
|
||||
@ -3458,7 +3469,7 @@ static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp)
|
||||
|
||||
INIT_DELAYED_WORK(&bridge->fdb_notify.dw, mlxsw_sp_fdb_notify_work);
|
||||
bridge->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL;
|
||||
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
|
||||
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp, false);
|
||||
return 0;
|
||||
|
||||
err_register_switchdev_blocking_notifier:
|
||||
|
Loading…
Reference in New Issue
Block a user