thermal: sysfs: Simplifications of trip point attribute callbacks
v4 cover thermal: sysfs: Simplifications of trip point attribute callbacks
Hi,
This is the 4th iteration of
https://lore.kernel.org/linux-pm/5754079.DvuYhMxLoT@kreacher/
The difference between it and the 3rd iteration:
https://lore.kernel.org/linux-pm/12338384.O9o76ZdvQC@kreacher/
is the lack of trip ID validation checks in the _store and _show callback routines modified by it.
Please refer to the individual patch changelogs for details.
Thanks!
PATCH v4 1/2 thermal: sysfs: Rework the handling of trip point updates
From: Rafael J. Wysocki <[email protected]>
Both trip_point_temp_store() and trip_point_hyst_store() use thermal_zone_set_trip() to update a given trip point, but none of them actually needs to change more than one field in struct thermal_trip representing it. However, each of them effectively calls __thermal_zone_get_trip() twice in a row for the same trip index value, once directly and once via thermal_zone_set_trip(), which is not particularly efficient, and the way in which thermal_zone_set_trip() carries out the update is not particularly straightforward.
Moreover, input processing need not be done under the thermal zone lock in any of these functions.
Rework trip_point_temp_store() and trip_point_hyst_store() to address the above, move the part of thermal_zone_set_trip() that is still useful to a new function called thermal_zone_trip_updated() and drop the rest of it.
While at it, make trip_point_hyst_store() reject negative hysteresis values.
---
v3 -> v4: Don't check trip_id against boundaries in trip_point_temp_store() and
trip_point_hyst_store() (Daniel).
v2 -> v3: No changes
v1 -> v2: Still check device_is_registered() under the zone lock
--- drivers/thermal/thermal_core.h | 2 + drivers/thermal/thermal_sysfs.c | 52 +++++++++++++++++++++++++++------------- drivers/thermal/thermal_trip.c | 45 ++++++---------------------------- include/linux/thermal.h | 4 --- 4 files changed, 47 insertions(+), 56 deletions(-)
drivers/thermal/thermal_sysfs.c +36 -16
@@ -120,8 +120,13 @@ trip_point_temp_store(struct device *dev const char *buf, size_t count) {struct thermal_zone_device *tz =to_thermal_zone (dev); -struct thermal_trip trip; +struct thermal_trip *trip;int trip_id, ret; +int temp; + + ret =kstrtoint (buf,10 , &temp); +if (ret) +return -EINVAL ;if (sscanf (attr->attr.name,"trip_point_%d_temp" , &trip_id) !=1 )return -EINVAL ;
@@ -133,15 +138,20 @@ trip_point_temp_store(struct device *dev goto unlock; } - ret =__thermal_zone_get_trip (tz, trip_id, &trip); -if (ret) - goto unlock; + trip = &tz->trips[trip_id]; - ret =kstrtoint (buf,10 , &trip.temperature); -if (ret) - goto unlock; +if (temp != trip->temperature) { +if (tz->ops->set_trip_temp) { + ret = tz->ops->set_trip_temp (tz, trip_id, temp); +if (ret) + goto unlock; + } + + trip->temperature = temp; + +thermal_zone_trip_updated (tz, trip); + } - ret =thermal_zone_set_trip (tz, trip_id, &trip); unlock:mutex_unlock (&tz->lock);
@@ -179,8 +189,13 @@ trip_point_hyst_store(struct device *dev const char *buf, size_t count) {struct thermal_zone_device *tz =to_thermal_zone (dev); -struct thermal_trip trip; +struct thermal_trip *trip;int trip_id, ret; +int hyst; + + ret =kstrtoint (buf,10 , &hyst); +if (ret || hyst <0 ) +return -EINVAL ;if (sscanf (attr->attr.name,"trip_point_%d_hyst" , &trip_id) !=1 )return -EINVAL ;
@@ -192,15 +207,20 @@ trip_point_hyst_store(struct device *dev goto unlock; } - ret =__thermal_zone_get_trip (tz, trip_id, &trip); -if (ret) - goto unlock; + trip = &tz->trips[trip_id]; - ret =kstrtoint (buf,10 , &trip.hysteresis); -if (ret) - goto unlock; +if (hyst != trip->hysteresis) { +if (tz->ops->set_trip_hyst) { + ret = tz->ops->set_trip_hyst (tz, trip_id, hyst); +if (ret) + goto unlock; + } + + trip->hysteresis = hyst; + +thermal_zone_trip_updated (tz, trip); + } - ret =thermal_zone_set_trip (tz, trip_id, &trip); unlock:mutex_unlock (&tz->lock);
drivers/thermal/thermal_core.h +2 -0
@@ -124,6 +124,8 @@ int __thermal_zone_get_trip(struct therm struct thermal_trip *trip);int thermal_zone_trip_id (struct thermal_zone_device *tz,const struct thermal_trip *trip); +void thermal_zone_trip_updated (struct thermal_zone_device *tz, +const struct thermal_trip *trip);int __thermal_zone_get_temp (struct thermal_zone_device *tz,int *temp);/* sysfs I/F */
drivers/thermal/thermal_trip.c +9 -36
54 lines not on this page · raw message
include/linux/thermal.h +0 -4
@@ -282,10 +282,6 @@ int __thermal_zone_get_trip(struct therm struct thermal_trip *trip);int thermal_zone_get_trip (struct thermal_zone_device *tz,int trip_id,struct thermal_trip *trip); - -int thermal_zone_set_trip (struct thermal_zone_device *tz,int trip_id, -const struct thermal_trip *trip); -int for_each_thermal_trip (struct thermal_zone_device *tz,int (*cb)(struct thermal_trip *,void *),void *data);
Re: [PATCH v4 1/2] thermal: sysfs: Rework the handling of trip point updates
Quoted 19 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Both
trip_point_temp_store()andtrip_point_hyst_store()usethermal_zone_set_trip()to update a given trip point, but none of them actually needs to change more than one field in structthermal_triprepresenting it. However, each of them effectively calls__thermal_zone_get_trip()twice in a row for the same trip index value, once directly and once viathermal_zone_set_trip(), which is not particularly efficient, and the way in whichthermal_zone_set_trip()carries out the update is not particularly straightforward.Moreover, input processing need not be done under the thermal zone lock in any of these functions.
Rework
trip_point_temp_store()andtrip_point_hyst_store()to address the above, move the part ofthermal_zone_set_trip()that is still useful to a new function calledthermal_zone_trip_updated()and drop the rest of it.
Quoted 5 lines
While at it, make
trip_point_hyst_store()reject negative hysteresis values.Signed-off-by Rafael J. Wysocki <[email protected]>---
Signature · 5 lines
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog
PATCH v4 2/2 thermal: sysfs: Rework the reading of trip point attributes
In reply to Rafael J. WysockiFrom: Rafael J. Wysocki <[email protected]>
Rework the _show() callback functions for the trip point temperature, hysteresis and type attributes to avoid copying the values of struct thermal_trip fields that they do not use and make them carry out the same validation checks as the corresponding _store() callback functions.
No intentional functional impact.
---
v3 -> v4: Don't check trip_id against boundaries in the _show routines
for trip type, temperature and hysteresis (Daniel).
v2 -> v3: Drop a redundant 'ret' check at the end of trip_point_hyst_show.
v1 -> v2: Do not drop thermal zone locking from the _store() callback functions.
--- drivers/thermal/thermal_sysfs.c | 52 +++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 27 deletions(-)
drivers/thermal/thermal_sysfs.c +25 -27
@@ -83,25 +83,24 @@ trip_point_type_show(struct device *dev, char *buf) {struct thermal_zone_device *tz =to_thermal_zone (dev); -struct thermal_trip trip; -int trip_id, result; +enum thermal_trip_type type; +int trip_id;if (sscanf (attr->attr.name,"trip_point_%d_type" , &trip_id) !=1 )return -EINVAL ;mutex_lock (&tz->lock); -if (device_is_registered (dev)) - result =__thermal_zone_get_trip (tz, trip_id, &trip); -else - result = -ENODEV ; +if (!device_is_registered (dev)) { +mutex_unlock (&tz->lock); +return -ENODEV ; + } -mutex_unlock (&tz->lock); + type = tz->trips[trip_id].type; -if (result) -return result; +mutex_unlock (&tz->lock); -switch (trip.type) { +switch (type) {case THERMAL_TRIP_CRITICAL :return sprintf (buf,"critical\n" );case THERMAL_TRIP_HOT :
@@ -163,25 +162,23 @@ trip_point_temp_show(struct device *dev, char *buf) {struct thermal_zone_device *tz =to_thermal_zone (dev); -struct thermal_trip trip; -int trip_id, ret; +int trip_id, temp;if (sscanf (attr->attr.name,"trip_point_%d_temp" , &trip_id) !=1 )return -EINVAL ;mutex_lock (&tz->lock); -if (device_is_registered (dev)) - ret =__thermal_zone_get_trip (tz, trip_id, &trip); -else - ret = -ENODEV ; +if (!device_is_registered (dev)) { +mutex_unlock (&tz->lock); +return -ENODEV ; + } -mutex_unlock (&tz->lock); + temp = tz->trips[trip_id].temperature; -if (ret) -return ret; +mutex_unlock (&tz->lock); -return sprintf (buf,"%d\n" , trip.temperature); +return sprintf (buf,"%d\n" , temp); } static ssize_t
@@ -232,22 +229,23 @@ trip_point_hyst_show(struct device *dev, char *buf) {struct thermal_zone_device *tz =to_thermal_zone (dev); -struct thermal_trip trip; -int trip_id, ret; +int trip_id, hyst;if (sscanf (attr->attr.name,"trip_point_%d_hyst" , &trip_id) !=1 )return -EINVAL ;mutex_lock (&tz->lock); -if (device_is_registered (dev)) - ret =__thermal_zone_get_trip (tz, trip_id, &trip); -else - ret = -ENODEV ; +if (!device_is_registered (dev)) { +mutex_unlock (&tz->lock); +return -ENODEV ; + } + + hyst = tz->trips[trip_id].hysteresis;mutex_unlock (&tz->lock); -return ret ? ret :sprintf (buf,"%d\n" , trip.hysteresis); +return sprintf (buf,"%d\n" , hyst); } static ssize_t
Re: [PATCH v4 2/2] thermal: sysfs: Rework the reading of trip point attributes
Quoted 12 lines · Rafael J. Wysocki
From: Rafael J. Wysocki <[email protected]>
Rework the
_show()callback functions for the trip point temperature, hysteresis and type attributes to avoid copying the values of structthermal_tripfields that they do not use and make them carry out the same validation checks as the corresponding_store()callback functions.No intentional functional impact.
Signed-off-by Rafael J. Wysocki <[email protected]>---
Quoted 8 lines
v3 -> v4: Don't check
trip_idagainst boundaries in the_showroutines
for trip type, temperature and hysteresis (Daniel).v2 -> v3: Drop a redundant 'ret' check at the end of
trip_point_hyst_show.v1 -> v2: Do not drop thermal zone locking from the
_store()callback functions.---
Signature · 5 lines
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog