本文部分内容参考
万字长文 | Thermal框架源码剖析,
Linux Thermal机制源码分析之框架概述_不捡风筝的玖伍贰柒的博客-CSDN博客,
特此致谢!
Thermal Governor即温控算法,笔者更习惯称之为温控策略。其实在讲解Thermal Core的时候已经涉及了一部分内容,这里再专门从Governor的角度对其作出更为详尽的解析,并对各种具体的温控算法进行一一讲解。
首先再次列出governor结构的定义,在include/linux/thermal.h中,代码如下:
/*** struct thermal_governor - structure that holds thermal governor information* @name: name of the governor* @bind_to_tz: callback called when binding to a thermal zone. If it* returns 0, the governor is bound to the thermal zone,* otherwise it fails.* @unbind_from_tz: callback called when a governor is unbound from a* thermal zone.* @throttle: callback called for every trip point even if temperature is* below the trip point temperature* @governor_list: node in thermal_governor_list (in thermal_core.c)*/
struct thermal_governor {char name[THERMAL_NAME_LENGTH];int (*bind_to_tz)(struct thermal_zone_device *tz);void (*unbind_from_tz)(struct thermal_zone_device *tz);int (*throttle)(struct thermal_zone_device *tz, int trip);struct list_head governor_list;
};
目前Linux内核有5种governor(温度控制策略,温控策略):
(1)power_allocator
引⼊PID(⽐例-积分-微分)控制,根据当前温度,动态给各cooling device分配power,并将power 转换为频率,从而达到根据温度限制频率的效果。
(2)step_wise
根据当前温度,cooling device逐级降频。
(3)fair_share
频率档位⽐较多的cooling device优先降频。
(4)bang_bang
两点温度调节,可用于cooling device有风扇的场景。
(5)user_space
用户空间控制。
目前可配置默认的Thermal Governor策略,即默认的Thermal Governor可以进入menuconfig中进行选择。默认Thermal Governor对应DEFAULT_THERMAL_GOVERNOR宏定义,其在drivers/thermal/thermal_core.h中,代码如下:
/* Default Thermal Governor */
#if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
#define DEFAULT_THERMAL_GOVERNOR "step_wise"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE)
#define DEFAULT_THERMAL_GOVERNOR "fair_share"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
#define DEFAULT_THERMAL_GOVERNOR "user_space"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
#define DEFAULT_THERMAL_GOVERNOR "power_allocator"
#endif
Kconfig中的Thermal Governor相关配置,在drivers/thermal/Kconfig中,代码如下:
choiceprompt "Default Thermal governor"default THERMAL_DEFAULT_GOV_STEP_WISEhelpThis option sets which thermal governor shall be loaded atstartup. If in doubt, select 'step_wise'.config THERMAL_DEFAULT_GOV_STEP_WISEbool "step_wise"select THERMAL_GOV_STEP_WISEhelpUse the step_wise governor as default. This throttles thedevices one step at a time.config THERMAL_DEFAULT_GOV_FAIR_SHAREbool "fair_share"select THERMAL_GOV_FAIR_SHAREhelpUse the fair_share governor as default. This throttles thedevices based on their 'contribution' to a zone. Thecontribution should be provided through platform data.config THERMAL_DEFAULT_GOV_USER_SPACEbool "user_space"select THERMAL_GOV_USER_SPACEhelpThe Userspace governor allows to get trip point crossednotification from the kernel via uevents. It is recommendedto use the netlink interface instead which gives richerinformation about the thermal framework events.config THERMAL_DEFAULT_GOV_POWER_ALLOCATORbool "power_allocator"depends on THERMAL_GOV_POWER_ALLOCATORhelpSelect this if you want to control temperature based onsystem and device power allocation. This governor can onlyoperate on cooling devices that implement the power API.endchoiceconfig THERMAL_GOV_FAIR_SHAREbool "Fair-share thermal governor"helpEnable this to manage platform thermals using fair-share governor.config THERMAL_GOV_STEP_WISEbool "Step_wise thermal governor"helpEnable this to manage platform thermals using a simple lineargovernor.config THERMAL_GOV_BANG_BANGbool "Bang Bang thermal governor"default nhelpEnable this to manage platform thermals using bang bang governor.Say 'Y' here if you want to use two point temperature regulationused for fans without throttling. Some fan drivers depend on thisgovernor to be enabled (e.g. acerhdf).config THERMAL_GOV_USER_SPACEbool "User_space thermal governor"helpEnable this to let the user space manage the platform thermals.config THERMAL_GOV_POWER_ALLOCATORbool "Power allocator thermal governor"depends on ENERGY_MODELhelpEnable this to manage platform thermals by dynamicallyallocating and limiting power to devices.
可见,默认的温控策略是step_wise。
实际上光指定了DEFAULT_THERMAL_GOVERNOR还不够,还需要相应的代码配合使其实际生效才可以,这段相关代码其实之前已经列出过,是在drivers/thermal/thermal_core.c中的thermal_register_governors函数调用的thermal_register_governor函数,代码如下:
int thermal_register_governor(struct thermal_governor *governor)
{int err;const char *name;struct thermal_zone_device *pos;if (!governor)return -EINVAL;mutex_lock(&thermal_governor_lock);err = -EBUSY;if (!__find_governor(governor->name)) {bool match_default;err = 0;list_add(&governor->governor_list, &thermal_governor_list);match_default = !strncmp(governor->name,DEFAULT_THERMAL_GOVERNOR,THERMAL_NAME_LENGTH);if (!def_governor && match_default)def_governor = governor;}mutex_lock(&thermal_list_lock);list_for_each_entry(pos, &thermal_tz_list, node) {/** only thermal zones with specified tz->tzp->governor_name* may run with tz->govenor unset*/if (pos->governor)continue;name = pos->tzp->governor_name;if (!strncasecmp(name, governor->name, THERMAL_NAME_LENGTH)) {int ret;ret = thermal_set_governor(pos, governor);if (ret)dev_err(&pos->device,"Failed to set governor %s for thermal zone %s: %d\n",governor->name, pos->type, ret);}}mutex_unlock(&thermal_list_lock);mutex_unlock(&thermal_governor_lock);return err;
}
其中match_default的这一段代码:
match_default = !strncmp(governor->name,DEFAULT_THERMAL_GOVERNOR,THERMAL_NAME_LENGTH);if (!def_governor && match_default)def_governor = governor;
就完成了默认管理策略(def_governor)的设置。
从下篇文章开始,将分别对5种策略中的每一种进行详细介绍和解析。