Skip to content

Commit

Permalink
mlxsw: core_thermal: Fix fan speed in maximum cooling state
Browse files Browse the repository at this point in the history
[ Upstream commit 6d206b1 ]

The cooling levels array is supposed to prevent the system fans from
being configured below a 20% duty cycle as otherwise some of them get
stuck at 0 RPM.

Due to an off-by-one error, the last element in the array was not
initialized, causing it to be set to zero, which in turn lead to fans
being configured with a 0% duty cycle in maximum cooling state.

Since commit 332fdf9 ("mlxsw: thermal: Fix out-of-bounds memory
accesses") the contents of the array are static. Therefore, instead of
fixing the initialization of the array, simply remove it and adjust
thermal_cooling_device_ops::set_cur_state() so that the configured duty
cycle is never set below 20%.

Before:

 # cat /sys/class/thermal/thermal_zone0/cdev0/type
 mlxsw_fan
 # echo 10 > /sys/class/thermal/thermal_zone0/cdev0/cur_state
 # cat /sys/class/hwmon/hwmon0/name
 mlxsw
 # cat /sys/class/hwmon/hwmon0/pwm1
 0

After:

 # cat /sys/class/thermal/thermal_zone0/cdev0/type
 mlxsw_fan
 # echo 10 > /sys/class/thermal/thermal_zone0/cdev0/cur_state
 # cat /sys/class/hwmon/hwmon0/name
 mlxsw
 # cat /sys/class/hwmon/hwmon0/pwm1
 255

This bug was uncovered when the thermal subsystem repeatedly tried to
configure the cooling devices to their maximum state due to another
issue [1]. This resulted in the fans being stuck at 0 RPM, which
eventually lead to the system undergoing thermal shutdown.

[1] https://lore.kernel.org/netdev/ZA3CFNhU4AbtsP4G@shredder/

Fixes: a421ce0 ("mlxsw: core: Extend cooling device with cooling levels")
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Vadim Pasternak <vadimp@nvidia.com>
Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
idosch authored and gregkh committed Mar 30, 2023
1 parent d679037 commit 1586ae5
Showing 1 changed file with 1 addition and 6 deletions.
7 changes: 1 addition & 6 deletions drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
Expand Up @@ -105,7 +105,6 @@ struct mlxsw_thermal {
struct thermal_zone_device *tzdev;
int polling_delay;
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
struct thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
struct mlxsw_cooling_states cooling_states[MLXSW_THERMAL_NUM_TRIPS];
struct mlxsw_thermal_area line_cards[];
Expand Down Expand Up @@ -468,7 +467,7 @@ static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
return idx;

/* Normalize the state to the valid speed range. */
state = thermal->cooling_levels[state];
state = max_t(unsigned long, MLXSW_THERMAL_MIN_STATE, state);
mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
if (err) {
Expand Down Expand Up @@ -859,10 +858,6 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
}
}

/* Initialize cooling levels per PWM state. */
for (i = 0; i < MLXSW_THERMAL_MAX_STATE; i++)
thermal->cooling_levels[i] = max(MLXSW_THERMAL_MIN_STATE, i);

thermal->polling_delay = bus_info->low_frequency ?
MLXSW_THERMAL_SLOW_POLL_INT :
MLXSW_THERMAL_POLL_INT;
Expand Down

0 comments on commit 1586ae5

Please sign in to comment.