mlxsw: core_env: Defer handling of module temperature warning events
Module temperature events are currently handled in softIRQ context, requiring the 'module_info_lock' to be a spin lock. In future patchsets we will need to be able to hold the lock while sleeping. Therefore, defer handling of these events using a work queue so that the next patch will be able to convert the lock to a mutex. Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
25a91f835a
Коммит
163f3d2dd0
|
@ -482,20 +482,30 @@ static int mlxsw_env_module_temp_event_enable(struct mlxsw_core *mlxsw_core,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mlxsw_env_mtwe_event_func(const struct mlxsw_reg_info *reg,
|
||||
char *mtwe_pl, void *priv)
|
||||
struct mlxsw_env_module_temp_warn_event {
|
||||
struct mlxsw_env *mlxsw_env;
|
||||
char mtwe_pl[MLXSW_REG_MTWE_LEN];
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
static void mlxsw_env_mtwe_event_work(struct work_struct *work)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = priv;
|
||||
struct mlxsw_env_module_temp_warn_event *event;
|
||||
struct mlxsw_env *mlxsw_env;
|
||||
int i, sensor_warning;
|
||||
bool is_overheat;
|
||||
|
||||
event = container_of(work, struct mlxsw_env_module_temp_warn_event,
|
||||
work);
|
||||
mlxsw_env = event->mlxsw_env;
|
||||
|
||||
for (i = 0; i < mlxsw_env->module_count; i++) {
|
||||
/* 64-127 of sensor_index are mapped to the port modules
|
||||
* sequentially (module 0 is mapped to sensor_index 64,
|
||||
* module 1 to sensor_index 65 and so on)
|
||||
*/
|
||||
sensor_warning =
|
||||
mlxsw_reg_mtwe_sensor_warning_get(mtwe_pl,
|
||||
mlxsw_reg_mtwe_sensor_warning_get(event->mtwe_pl,
|
||||
i + MLXSW_REG_MTMP_MODULE_INDEX_MIN);
|
||||
spin_lock(&mlxsw_env->module_info_lock);
|
||||
is_overheat =
|
||||
|
@ -524,10 +534,29 @@ static void mlxsw_env_mtwe_event_func(const struct mlxsw_reg_info *reg,
|
|||
spin_unlock(&mlxsw_env->module_info_lock);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(event);
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_env_mtwe_listener_func(const struct mlxsw_reg_info *reg, char *mtwe_pl,
|
||||
void *priv)
|
||||
{
|
||||
struct mlxsw_env_module_temp_warn_event *event;
|
||||
struct mlxsw_env *mlxsw_env = priv;
|
||||
|
||||
event = kmalloc(sizeof(*event), GFP_ATOMIC);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
event->mlxsw_env = mlxsw_env;
|
||||
memcpy(event->mtwe_pl, mtwe_pl, MLXSW_REG_MTWE_LEN);
|
||||
INIT_WORK(&event->work, mlxsw_env_mtwe_event_work);
|
||||
mlxsw_core_schedule_work(&event->work);
|
||||
}
|
||||
|
||||
static const struct mlxsw_listener mlxsw_env_temp_warn_listener =
|
||||
MLXSW_EVENTL(mlxsw_env_mtwe_event_func, MTWE, MTWE);
|
||||
MLXSW_EVENTL(mlxsw_env_mtwe_listener_func, MTWE, MTWE);
|
||||
|
||||
static int mlxsw_env_temp_warn_event_register(struct mlxsw_core *mlxsw_core)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче