gov_fair_share.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * fair_share.c - A simple weight based Thermal governor
  4. *
  5. * Copyright (C) 2012 Intel Corp
  6. * Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
  7. *
  8. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  9. *
  10. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  11. */
  12. #include <linux/thermal.h>
  13. #include "thermal_trace.h"
  14. #include "thermal_core.h"
  15. static int get_trip_level(struct thermal_zone_device *tz)
  16. {
  17. const struct thermal_trip_desc *level_td = NULL;
  18. const struct thermal_trip_desc *td;
  19. int trip_level = -1;
  20. for_each_trip_desc(tz, td) {
  21. if (td->threshold > tz->temperature)
  22. continue;
  23. trip_level++;
  24. if (!level_td || td->threshold > level_td->threshold)
  25. level_td = td;
  26. }
  27. /* Bail out if the temperature is not greater than any trips. */
  28. if (trip_level < 0)
  29. return 0;
  30. trace_thermal_zone_trip(tz, thermal_zone_trip_id(tz, &level_td->trip),
  31. level_td->trip.type);
  32. return trip_level;
  33. }
  34. /**
  35. * fair_share_throttle - throttles devices associated with the given zone
  36. * @tz: thermal_zone_device
  37. * @td: trip point descriptor
  38. * @trip_level: number of trips crossed by the zone temperature
  39. *
  40. * Throttling Logic: This uses three parameters to calculate the new
  41. * throttle state of the cooling devices associated with the given zone.
  42. *
  43. * Parameters used for Throttling:
  44. * P1. max_state: Maximum throttle state exposed by the cooling device.
  45. * P2. weight[i]/total_weight:
  46. * How 'effective' the 'i'th device is, in cooling the given zone.
  47. * P3. trip_level/max_no_of_trips:
  48. * This describes the extent to which the devices should be throttled.
  49. * We do not want to throttle too much when we trip a lower temperature,
  50. * whereas the throttling is at full swing if we trip critical levels.
  51. * new_state of cooling device = P3 * P2 * P1
  52. */
  53. static void fair_share_throttle(struct thermal_zone_device *tz,
  54. const struct thermal_trip_desc *td,
  55. int trip_level)
  56. {
  57. struct thermal_instance *instance;
  58. int total_weight = 0;
  59. int nr_instances = 0;
  60. list_for_each_entry(instance, &td->thermal_instances, trip_node) {
  61. total_weight += instance->weight;
  62. nr_instances++;
  63. }
  64. list_for_each_entry(instance, &td->thermal_instances, trip_node) {
  65. struct thermal_cooling_device *cdev = instance->cdev;
  66. u64 dividend;
  67. u32 divisor;
  68. dividend = trip_level;
  69. dividend *= cdev->max_state;
  70. divisor = tz->num_trips;
  71. if (total_weight) {
  72. dividend *= instance->weight;
  73. divisor *= total_weight;
  74. } else {
  75. divisor *= nr_instances;
  76. }
  77. instance->target = div_u64(dividend, divisor);
  78. mutex_lock(&cdev->lock);
  79. __thermal_cdev_update(cdev);
  80. mutex_unlock(&cdev->lock);
  81. }
  82. }
  83. static void fair_share_manage(struct thermal_zone_device *tz)
  84. {
  85. int trip_level = get_trip_level(tz);
  86. const struct thermal_trip_desc *td;
  87. lockdep_assert_held(&tz->lock);
  88. for_each_trip_desc(tz, td) {
  89. const struct thermal_trip *trip = &td->trip;
  90. if (trip->temperature == THERMAL_TEMP_INVALID ||
  91. trip->type == THERMAL_TRIP_CRITICAL ||
  92. trip->type == THERMAL_TRIP_HOT)
  93. continue;
  94. fair_share_throttle(tz, td, trip_level);
  95. }
  96. }
  97. static struct thermal_governor thermal_gov_fair_share = {
  98. .name = "fair_share",
  99. .manage = fair_share_manage,
  100. };
  101. THERMAL_GOVERNOR_DECLARE(thermal_gov_fair_share);