1. 02 Jan, 2024 15 commits
  2. 21 Dec, 2023 1 commit
  3. 15 Dec, 2023 1 commit
    • Rafael J. Wysocki's avatar
      thermal: core: Fix NULL pointer dereference in zone registration error path · 04e6ccfc
      Rafael J. Wysocki authored
      If device_register() in thermal_zone_device_register_with_trips()
      returns an error, the tz variable is set to NULL and subsequently
      dereferenced in kfree(tz->tzp).
      
      Commit adc8749b ("thermal/drivers/core: Use put_device() if
      device_register() fails") added the tz = NULL assignment in question to
      avoid a possible double-free after dropping the reference to the zone
      device.  However, after commit 4649620d ("thermal: core: Make
      thermal_zone_device_unregister() return after freeing the zone"), that
      assignment has become redundant, because dropping the reference to the
      zone device does not cause the zone object to be freed any more.
      
      Drop it to address the NULL pointer dereference.
      
      Fixes: 3d439b1a ("thermal/core: Alloc-copy-free the thermal zone parameters structure")
      Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: default avatarLukasz Luba <lukasz.luba@arm.com>
      04e6ccfc
  4. 13 Dec, 2023 6 commits
  5. 12 Dec, 2023 2 commits
    • Rafael J. Wysocki's avatar
      thermal: core: Rework thermal zone availability check · b38aa87f
      Rafael J. Wysocki authored
      In order to avoid running __thermal_zone_device_update() for thermal
      zones going away, the thermal zone lock is held around device_del()
      in thermal_zone_device_unregister() and thermal_zone_device_update()
      passes the given thermal zone device to device_is_registered().
      This allows thermal_zone_device_update() to skip the
      __thermal_zone_device_update() if device_del() has already run for
      the thermal zone at hand.
      
      However, instead of looking at driver core internals, the thermal
      subsystem may as well rely on its own data structures for this
      purpose.  Namely, if the thermal zone is not present in
      thermal_tz_list, it can be regarded as unavailable, which in fact is
      already the case in thermal_zone_device_unregister().  Accordingly,
      the device_is_registered() check in thermal_zone_device_update() can
      be replaced with checking whether or not the node list_head in struct
      thermal_zone_device is empty, in which case it is not there in
      thermal_tz_list.
      
      To make this work, though, it is necessary to initialize tz->node
      in thermal_zone_device_register_with_trips() before registering the
      thermal zone device and it needs to be added to thermal_tz_list and
      deleted from it under its zone lock.
      
      After the above modifications, the zone lock does not need to be
      held around device_del() in thermal_zone_device_unregister() any more.
      Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-and-tested-by: default avatarLukasz Luba <lukasz.luba@arm.com>
      Acked-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
      b38aa87f
    • Rafael J. Wysocki's avatar
      thermal: Drop redundant and confusing device_is_registered() checks · c3ffdfff
      Rafael J. Wysocki authored
      Multiple places in the thermal subsystem (most importantly, sysfs
      attribute callback functions) check if the given thermal zone device is
      still registered in order to return early in case the device_del() in
      thermal_zone_device_unregister() has run already.
      
      However, after thermal_zone_device_unregister() has been made wait for
      all of the zone-related activity to complete before returning, it is
      not necessary to do that any more, because all of the code holding a
      reference to the thermal zone device object will be waited for even if
      it does not do anything special to enforce this.
      
      Accordingly, drop all of the device_is_registered() checks that are now
      redundant and get rid of the zone locking that is not necessary any more
      after dropping them.
      Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-and-tested-by: default avatarLukasz Luba <lukasz.luba@arm.com>
      Acked-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
      c3ffdfff
  6. 11 Dec, 2023 1 commit
  7. 06 Dec, 2023 2 commits
    • Rafael J. Wysocki's avatar
      thermal: sysfs: Rework the reading of trip point attributes · 18dfb0e4
      Rafael J. Wysocki authored
      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.
      Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
      18dfb0e4
    • Rafael J. Wysocki's avatar
      thermal: sysfs: Rework the handling of trip point updates · be0a3600
      Rafael J. Wysocki authored
      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.
      Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Reviewed-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
      be0a3600
  8. 30 Nov, 2023 1 commit
  9. 28 Nov, 2023 7 commits
  10. 20 Nov, 2023 1 commit
    • Rafael J. Wysocki's avatar
      thermal: core: Add trip thresholds for trip crossing detection · 44844db9
      Rafael J. Wysocki authored
      The trip crossing detection in handle_thermal_trip() does not work
      correctly in the cases when a trip point is crossed on the way up and
      then the zone temperature stays above its low temperature (that is, its
      temperature decreased by its hysteresis).  The trip temperature may
      be passed by the zone temperature subsequently in that case, even
      multiple times, but that does not count as the trip crossing as long as
      the zone temperature does not fall below the trip's low temperature or,
      in other words, until the trip is crossed on the way down.
      
      |-----------low--------high------------|
                   |<--------->|
                   |    hyst   |
                   |           |
                   |          -|--> crossed on the way up
                   |
               <---|-- crossed on the way down
      
      However, handle_thermal_trip() will invoke thermal_notify_tz_trip_up()
      every time the trip temperature is passed by the zone temperature on
      the way up regardless of whether or not the trip has been crossed on
      the way down yet.  Moreover, it will not call thermal_notify_tz_trip_down()
      if the last zone temperature was between the trip's temperature and its
      low temperature, so some "trip crossed on the way down" events may not
      be reported.
      
      To address this issue, introduce trip thresholds equal to either the
      temperature of the given trip, or its low temperature, such that if
      the trip's threshold is passed by the zone temperature on the way up,
      its value will be set to the trip's low temperature and
      thermal_notify_tz_trip_up() will be called, and if the trip's threshold
      is passed by the zone temperature on the way down, its value will be set
      to the trip's temperature (high) and thermal_notify_tz_trip_down() will
      be called.  Accordingly, if the threshold is passed on the way up, it
      cannot be passed on the way up again until its passed on the way down
      and if it is passed on the way down, it cannot be passed on the way down
      again until it is passed on the way up which guarantees correct
      triggering of trip crossing notifications.
      
      If the last temperature of the zone is invalid, the trip's threshold
      will be set depending of the zone's current temperature: If that
      temperature is above the trip's temperature, its threshold will be
      set to its low temperature or otherwise its threshold will be set to
      its (high) temperature.  Because the zone temperature is initially
      set to invalid and tz->last_temperature is only updated by
      update_temperature(), this is sufficient to set the correct initial
      threshold values for all trips.
      
      Link: https://lore.kernel.org/all/20220718145038.1114379-4-daniel.lezcano@linaro.orgSigned-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
      44844db9
  11. 19 Nov, 2023 3 commits