Skip to content

Commit 6f73862

Browse files
mellanoxbmcdavem330
authored andcommitted
mlxsw: core: Add the hottest thermal zone detection
When multiple sensors are mapped to the same cooling device, the cooling device should be set according the worst sensor from the sensors associated with this cooling device. Provide the hottest thermal zone detection and enforce cooling device to follow the temperature trends of the hottest zone only. Prevent competition for the cooling device control from others zones, by "stable trend" indication. A cooling device will not perform any actions associated with a zone with a "stable trend". When other thermal zone is detected as a hottest, a cooling device is to be switched to following temperature trends of new hottest zone. Thermal zone score is represented by 32 bits unsigned integer and calculated according to the next formula: For T < TZ<t><i>, where t from {normal trip = 0, high trip = 1, hot trip = 2, critical = 3}: TZ<i> score = (T + (TZ<t><i> - T) / 2) / (TZ<t><i> - T) * 256 ** j; Highest thermal zone score s is set as MAX(TZ<i>score); Following this formula, if TZ<i> is in trip point higher than TZ<k>, the higher score is to be always assigned to TZ<i>. For two thermal zones located at the same kind of trip point, the higher score will be assigned to the zone which is closer to the next trip point. Thus, the highest score will always be assigned objectively to the hottest thermal zone. All the thermal zones initially are to be configured with mode "enabled" with the "step_wise" governor. Signed-off-by: Vadim Pasternak <vadimp@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent f14f4e6 commit 6f73862

File tree

1 file changed

+62
-13
lines changed

1 file changed

+62
-13
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_thermal.c

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */
2424
#define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2)
2525
#define MLXSW_THERMAL_ZONE_MAX_NAME 16
26+
#define MLXSW_THERMAL_TEMP_SCORE_MAX GENMASK(31, 0)
2627
#define MLXSW_THERMAL_MAX_STATE 10
2728
#define MLXSW_THERMAL_MAX_DUTY 255
2829
/* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values
@@ -113,6 +114,8 @@ struct mlxsw_thermal {
113114
struct mlxsw_thermal_module *tz_module_arr;
114115
struct mlxsw_thermal_module *tz_gearbox_arr;
115116
u8 tz_gearbox_num;
117+
unsigned int tz_highest_score;
118+
struct thermal_zone_device *tz_highest_dev;
116119
};
117120

118121
static inline u8 mlxsw_state_to_duty(int state)
@@ -197,6 +200,34 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
197200
return 0;
198201
}
199202

203+
static void mlxsw_thermal_tz_score_update(struct mlxsw_thermal *thermal,
204+
struct thermal_zone_device *tzdev,
205+
struct mlxsw_thermal_trip *trips,
206+
int temp)
207+
{
208+
struct mlxsw_thermal_trip *trip = trips;
209+
unsigned int score, delta, i, shift = 1;
210+
211+
/* Calculate thermal zone score, if temperature is above the critical
212+
* threshold score is set to MLXSW_THERMAL_TEMP_SCORE_MAX.
213+
*/
214+
score = MLXSW_THERMAL_TEMP_SCORE_MAX;
215+
for (i = MLXSW_THERMAL_TEMP_TRIP_NORM; i < MLXSW_THERMAL_NUM_TRIPS;
216+
i++, trip++) {
217+
if (temp < trip->temp) {
218+
delta = DIV_ROUND_CLOSEST(temp, trip->temp - temp);
219+
score = delta * shift;
220+
break;
221+
}
222+
shift *= 256;
223+
}
224+
225+
if (score > thermal->tz_highest_score) {
226+
thermal->tz_highest_score = score;
227+
thermal->tz_highest_dev = tzdev;
228+
}
229+
}
230+
200231
static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
201232
struct thermal_cooling_device *cdev)
202233
{
@@ -292,6 +323,9 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
292323
return err;
293324
}
294325
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
326+
if (temp > 0)
327+
mlxsw_thermal_tz_score_update(thermal, tzdev, thermal->trips,
328+
temp);
295329

296330
*p_temp = (int) temp;
297331
return 0;
@@ -353,6 +387,22 @@ static int mlxsw_thermal_set_trip_hyst(struct thermal_zone_device *tzdev,
353387
return 0;
354388
}
355389

390+
static int mlxsw_thermal_trend_get(struct thermal_zone_device *tzdev,
391+
int trip, enum thermal_trend *trend)
392+
{
393+
struct mlxsw_thermal_module *tz = tzdev->devdata;
394+
struct mlxsw_thermal *thermal = tz->parent;
395+
396+
if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
397+
return -EINVAL;
398+
399+
if (tzdev == thermal->tz_highest_dev)
400+
return 1;
401+
402+
*trend = THERMAL_TREND_STABLE;
403+
return 0;
404+
}
405+
356406
static struct thermal_zone_device_ops mlxsw_thermal_ops = {
357407
.bind = mlxsw_thermal_bind,
358408
.unbind = mlxsw_thermal_unbind,
@@ -364,6 +414,7 @@ static struct thermal_zone_device_ops mlxsw_thermal_ops = {
364414
.set_trip_temp = mlxsw_thermal_set_trip_temp,
365415
.get_trip_hyst = mlxsw_thermal_get_trip_hyst,
366416
.set_trip_hyst = mlxsw_thermal_set_trip_hyst,
417+
.get_trend = mlxsw_thermal_trend_get,
367418
};
368419

369420
static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
@@ -474,7 +525,9 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
474525
return 0;
475526

476527
/* Update trip points. */
477-
mlxsw_thermal_module_trips_update(dev, thermal->core, tz);
528+
err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz);
529+
if (!err)
530+
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
478531

479532
return 0;
480533
}
@@ -539,10 +592,6 @@ mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip,
539592
return 0;
540593
}
541594

542-
static struct thermal_zone_params mlxsw_thermal_module_params = {
543-
.governor_name = "user_space",
544-
};
545-
546595
static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
547596
.bind = mlxsw_thermal_module_bind,
548597
.unbind = mlxsw_thermal_module_unbind,
@@ -554,6 +603,7 @@ static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
554603
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
555604
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
556605
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
606+
.get_trend = mlxsw_thermal_trend_get,
557607
};
558608

559609
static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
@@ -574,6 +624,8 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
574624
return err;
575625

576626
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
627+
if (temp > 0)
628+
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
577629

578630
*p_temp = (int) temp;
579631
return 0;
@@ -590,10 +642,7 @@ static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
590642
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
591643
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
592644
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
593-
};
594-
595-
static struct thermal_zone_params mlxsw_thermal_gearbox_params = {
596-
.governor_name = "user_space",
645+
.get_trend = mlxsw_thermal_trend_get,
597646
};
598647

599648
static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
@@ -709,13 +758,13 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
709758
MLXSW_THERMAL_TRIP_MASK,
710759
module_tz,
711760
&mlxsw_thermal_module_ops,
712-
&mlxsw_thermal_module_params,
713-
0, 0);
761+
NULL, 0, 0);
714762
if (IS_ERR(module_tz->tzdev)) {
715763
err = PTR_ERR(module_tz->tzdev);
716764
return err;
717765
}
718766

767+
module_tz->mode = THERMAL_DEVICE_ENABLED;
719768
return 0;
720769
}
721770

@@ -833,11 +882,11 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
833882
MLXSW_THERMAL_TRIP_MASK,
834883
gearbox_tz,
835884
&mlxsw_thermal_gearbox_ops,
836-
&mlxsw_thermal_gearbox_params,
837-
0, 0);
885+
NULL, 0, 0);
838886
if (IS_ERR(gearbox_tz->tzdev))
839887
return PTR_ERR(gearbox_tz->tzdev);
840888

889+
gearbox_tz->mode = THERMAL_DEVICE_ENABLED;
841890
return 0;
842891
}
843892

0 commit comments

Comments
 (0)