当前位置: 首页 > news >正文

Linux内核Thermal框架详解十三、Thermal Governor(3)

接前一篇文章Linux内核Thermal框架详解十二、Thermal Governor(2)

二、具体温控策略

上一篇文章介绍并详细分析了bang_bang governor的源码。本文介绍第2种温控策略:fair_share。

2. fair_share

fair_share governor总的策略是频率档位⽐较多的cooling device优先降频。

fair_share governor的代码在drivers/thermal/gov_fair_share.c中,也很简短,一共才124行,有效代码不到100行。如下所示:

#include <linux/thermal.h>
#include <trace/events/thermal.h>#include "thermal_core.h"/*** get_trip_level: - obtains the current trip level for a zone* @tz:		thermal zone device*/
static int get_trip_level(struct thermal_zone_device *tz)
{int count = 0;int trip_temp;enum thermal_trip_type trip_type;if (tz->trips == 0 || !tz->ops->get_trip_temp)return 0;for (count = 0; count < tz->trips; count++) {tz->ops->get_trip_temp(tz, count, &trip_temp);if (tz->temperature < trip_temp)break;}/** count > 0 only if temperature is greater than first trip* point, in which case, trip_point = count - 1*/if (count > 0) {tz->ops->get_trip_type(tz, count - 1, &trip_type);trace_thermal_zone_trip(tz, count - 1, trip_type);}return count;
}static long get_target_state(struct thermal_zone_device *tz,struct thermal_cooling_device *cdev, int percentage, int level)
{unsigned long max_state;cdev->ops->get_max_state(cdev, &max_state);return (long)(percentage * level * max_state) / (100 * tz->trips);
}/*** fair_share_throttle - throttles devices associated with the given zone* @tz: thermal_zone_device* @trip: trip point index** Throttling Logic: This uses three parameters to calculate the new* throttle state of the cooling devices associated with the given zone.** Parameters used for Throttling:* P1. max_state: Maximum throttle state exposed by the cooling device.* P2. percentage[i]/100:*	How 'effective' the 'i'th device is, in cooling the given zone.* P3. cur_trip_level/max_no_of_trips:*	This describes the extent to which the devices should be throttled.*	We do not want to throttle too much when we trip a lower temperature,*	whereas the throttling is at full swing if we trip critical levels.*	(Heavily assumes the trip points are in ascending order)* new_state of cooling device = P3 * P2 * P1*/
static int fair_share_throttle(struct thermal_zone_device *tz, int trip)
{struct thermal_instance *instance;int total_weight = 0;int total_instance = 0;int cur_trip_level = get_trip_level(tz);mutex_lock(&tz->lock);list_for_each_entry(instance, &tz->thermal_instances, tz_node) {if (instance->trip != trip)continue;total_weight += instance->weight;total_instance++;}list_for_each_entry(instance, &tz->thermal_instances, tz_node) {int percentage;struct thermal_cooling_device *cdev = instance->cdev;if (instance->trip != trip)continue;if (!total_weight)percentage = 100 / total_instance;elsepercentage = (instance->weight * 100) / total_weight;instance->target = get_target_state(tz, cdev, percentage,cur_trip_level);mutex_lock(&cdev->lock);__thermal_cdev_update(cdev);mutex_unlock(&cdev->lock);}mutex_unlock(&tz->lock);return 0;
}static struct thermal_governor thermal_gov_fair_share = {.name		= "fair_share",.throttle	= fair_share_throttle,
};
THERMAL_GOVERNOR_DECLARE(thermal_gov_fair_share);

同样是麻雀虽小,五脏俱全。别看代码行数比较少,但是背后的机制却并不简单。一段一段来进行分析。

(1)THERMAL_GOVERNOR_DECLARE相关代码

先来看THERMAL_GOVERNOR_DECLARE。它是一个宏定义,在drivers/thermal/thermal_core.h中,代码如下:

/* Init section thermal table */
extern struct thermal_governor *__governor_thermal_table[];
extern struct thermal_governor *__governor_thermal_table_end[];#define THERMAL_TABLE_ENTRY(table, name)			\static typeof(name) *__thermal_table_entry_##name	\__used __section("__" #table "_thermal_table") = &name#define THERMAL_GOVERNOR_DECLARE(name)	THERMAL_TABLE_ENTRY(governor, name)

实际上这段代码在前文Linux内核Thermal框架详解四、Thermal Core(3)中已经进行了详细分析,这里就不再赘述了。不过为了便于理解和加深印象,将fair_share governor展开后的代码再次列出:

static struct thermal_governor thermal_gov_fair_share = {.name		= "fair_share",.throttle	= fair_share_throttle,
};static struct thermal_governor *__thermal_table_entry_thermal_gov_fair_share    \__used __section("__governor_thermal_table") = &thermal_gov_fair_share

Thermal Governor都是通过THERMAL_GOVERNOR_DECLARE定义到了__governor_thermal_table这段空间内。然后在thermal core初始化时通过调用thermal_register_governors来注册到thermal_governor_list链表中。再之后通过经由“thermal_init->thermal_register_governors-> thermal_set_governor”路径和thermal zone device关联上。

(2)handle_non_critical_trips

struct thermal_governor中有一个成员throttle,其是一个函数指针:

int (*throttle)(struct thermal_zone_device *tz, int trip);

对于对象thermal_gov_fair_share来说,指向了fair_share_throttle函数。在解析fair_share_throttle函数之前,有一个问题必须弄清楚:这个函数是何时被调用的?

是在drivers/thermal/thermal_core.c的handle_non_critical_trips函数中,代码如下:

static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip)
{tz->governor ? tz->governor->throttle(tz, trip) :def_governor->throttle(tz, trip);
}

那么又是哪里调用的handle_non_critical_trips?是在drivers/thermal/thermal_core.c的handle_thermal_trip函数中,代码如下:

static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
{enum thermal_trip_type type;int trip_temp, hyst = 0;/* Ignore disabled trip points */if (test_bit(trip, &tz->trips_disabled))return;tz->ops->get_trip_temp(tz, trip, &trip_temp);tz->ops->get_trip_type(tz, trip, &type);if (tz->ops->get_trip_hyst)tz->ops->get_trip_hyst(tz, trip, &hyst);if (tz->last_temperature != THERMAL_TEMP_INVALID) {if (tz->last_temperature < trip_temp &&tz->temperature >= trip_temp)thermal_notify_tz_trip_up(tz->id, trip,tz->temperature);if (tz->last_temperature >= trip_temp &&tz->temperature < (trip_temp - hyst))thermal_notify_tz_trip_down(tz->id, trip,tz->temperature);}if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)handle_critical_trips(tz, trip, type);elsehandle_non_critical_trips(tz, trip);/** Alright, we handled this trip successfully.* So, start monitoring again.*/monitor_thermal_zone(tz);
}

对于handle_thermal_trip函数的详细分析有专门的文章章节,由于本篇文章专注于fair_share governor,故在此不深入展开。

(3)fair_share_throttle

再贴一下此函数代码:

/*** fair_share_throttle - throttles devices associated with the given zone* @tz: thermal_zone_device* @trip: trip point index** Throttling Logic: This uses three parameters to calculate the new* throttle state of the cooling devices associated with the given zone.** Parameters used for Throttling:* P1. max_state: Maximum throttle state exposed by the cooling device.* P2. percentage[i]/100:*	How 'effective' the 'i'th device is, in cooling the given zone.* P3. cur_trip_level/max_no_of_trips:*	This describes the extent to which the devices should be throttled.*	We do not want to throttle too much when we trip a lower temperature,*	whereas the throttling is at full swing if we trip critical levels.*	(Heavily assumes the trip points are in ascending order)* new_state of cooling device = P3 * P2 * P1*/
static int fair_share_throttle(struct thermal_zone_device *tz, int trip)
{struct thermal_instance *instance;int total_weight = 0;int total_instance = 0;int cur_trip_level = get_trip_level(tz);mutex_lock(&tz->lock);list_for_each_entry(instance, &tz->thermal_instances, tz_node) {if (instance->trip != trip)continue;total_weight += instance->weight;total_instance++;}list_for_each_entry(instance, &tz->thermal_instances, tz_node) {int percentage;struct thermal_cooling_device *cdev = instance->cdev;if (instance->trip != trip)continue;if (!total_weight)percentage = 100 / total_instance;elsepercentage = (instance->weight * 100) / total_weight;instance->target = get_target_state(tz, cdev, percentage,cur_trip_level);mutex_lock(&cdev->lock);__thermal_cdev_update(cdev);mutex_unlock(&cdev->lock);}mutex_unlock(&tz->lock);return 0;
}

函数注释已经将函数功能说得很清楚了:对与给定thermal zone关联的设备进行节流。调节逻辑如下:

使用3个参数计算与给定thermal zone相关联的冷却设备的最新throttle state。

用于节流的3个参数(注意不是函数的参数):

  • 参数1. max_state

冷却设备暴露的最大throttle state。

  • 参数2. percentage[i]/100

第i个设备在冷却给定区域方面的”有效性”。

  • 参数3. cur_trip_level/max_no_of_trips

这个参数描述设备应被节流的限度。当到达较低的温度时,不需要节流太多;反之如果在临界水平,节流就处于全开状态。在很大程度上假设跳闸点按升序排列。

new_state of cooling device = P3 * P2 * P1

代码的大致流程如下:

1)得到指定thermal zone的trip level

通过get_trip_level(tz)得到指定thermal zone的trip level。

get_trip_level函数在同文件(drivers/thermal/gov_fair_share.c)中实现,代码如下:

/*** get_trip_level: - obtains the current trip level for a zone* @tz:		thermal zone device*/
static int get_trip_level(struct thermal_zone_device *tz)
{int count = 0;int trip_temp;enum thermal_trip_type trip_type;if (tz->trips == 0 || !tz->ops->get_trip_temp)return 0;for (count = 0; count < tz->trips; count++) {tz->ops->get_trip_temp(tz, count, &trip_temp);if (tz->temperature < trip_temp)break;}/** count > 0 only if temperature is greater than first trip* point, in which case, trip_point = count - 1*/if (count > 0) {tz->ops->get_trip_type(tz, count - 1, &trip_type);trace_thermal_zone_trip(tz, count - 1, trip_type);}return count;
}

依次遍历各个触发点(trips),并得到相应触发点的温度。如果给定thermal zone的温度小于某一触发点的温度,则跳出循环。

未完待续……

相关文章:

Linux内核Thermal框架详解十三、Thermal Governor(3)

接前一篇文章Linux内核Thermal框架详解十二、Thermal Governor&#xff08;2&#xff09; 二、具体温控策略 上一篇文章介绍并详细分析了bang_bang governor的源码。本文介绍第2种温控策略&#xff1a;fair_share。 2. fair_share fair_share governor总的策略是频率档位⽐较…...

TikTok品牌出海创世纪(二)

目录 1.推荐算法打造王者品牌 2.品牌聚焦海外Z群体 3.持续扩展应用场景 加速品牌全球化传播 品牌聚焦海外Z群体 “这个地球上&#xff0c;三分之二的人都在用Facebook“&#xff0c;这是对Facebook曾经统治地位最直观的描述。 但如今&#xff0c;这家全球社交媒体巨头的光环正…...

iOS中SDK开发 -- cocoapods库创建

在iOS项目中&#xff0c;经常使用cocoadpods来进行依赖管理以及三方库引入等。引入的三方库一般会有几种形式&#xff1a;一、在Pods目录下可以直接看到源代码的开源库&#xff0c;如AFNetworking&#xff0c;Masonry等常见开源库。二、在Pods目录下拉取的项目文件只能看到对应…...

2023年了,还是没学会内卷....

先做个自我介绍&#xff1a;我&#xff0c;普本&#xff0c;通信工程专业&#xff0c;现在飞猪干软件测试&#xff0c;工作时长两年半。 回望疫情纪元&#xff0c;正好是实习 毕业这三年。要说倒霉也是真倒霉&#xff0c;互联网浪潮第三波尾巴也没抓住&#xff0c;狗屁造富神…...

chatGPT爆火,什么时候中国能有自己的“ChatGPT“

目录 引言 一、ChatGPT爆火 二、中国何时能有自己的"ChatGPT" 三、为什么openai可以做出chatGPT? 四、结论 引言 随着人工智能技术的不断发展&#xff0c;自然语言处理技术也逐渐成为了研究的热点之一。其中&#xff0c;ChatGPT作为一项领先的自然语言处理技术…...

【Matlab算法】粒子群算法求解一维非线性函数问题(附MATLAB代码)

MATLAB求解一维非线性函数问题前言正文函数实现&#xff08;可视化处理&#xff09;可视化结果前言 一维非线性函数是指函数的自变量和因变量都是一维实数&#xff0c;而且函数的形式是非线性的&#xff0c;也就是不符合线性函数的形式。在一维非线性函数中&#xff0c;自变量…...

2023 最新发布超全的 Java 面试八股文,整整 1000道面试题,太全了

作为一名优秀的程序员&#xff0c;技术面试都是不可避免的一个环节&#xff0c;一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 2023 年的互联网行业竞争越来越严峻&#xff0c;面试也是越来越难&#xff0c;很多粉丝朋友私信希望我出一篇面试专题或…...

产品经理面经|当面试官问你还有什么问题?

相信很多产品经理在跳槽面试的时候&#xff0c;在面试尾声都会遇到这样的环节&#xff0c;面试官会问你有什么问题要问的&#xff0c;一般来说大家都能随时随地甩出几个问题来化解&#xff0c;但其实在这个环节对于应聘者来说也是一个很好的机会来展现自己的能力&#xff0c;甚…...

单链表的基本操作

目录 一.链表的基本概念和结构 二.链表的分类 三.单链表的基本操作 1.创建一个节点 2.打印 3.尾插 4.头插 5.尾删 6.头删 7.查找 8.指定位置插入 9.指定位置删除 10.销毁 一.链表的基本概念和结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结…...

【微信小程序-原生开发】系列教程目录(已完结)

01-注册登录账号&#xff0c;获取 AppID、下载安装开发工具、创建项目、上传体验 https://sunshinehu.blog.csdn.net/article/details/128663679 02-添加全局页面配置、页面、底部导航 https://sunshinehu.blog.csdn.net/article/details/128705866 03-自定义底部导航&#x…...

JavaEE--Thread 类的基本用法(不看你会后悔的嘿嘿)

Thread类是JVM用来管理线程的一个类,换句话说,每个线程都唯一对应着一个Thread对象. 因此,认识和掌握Thread类弥足重要. 本文将从 线程创建线程中断线程等待线程休眠获取线程实例 等方面来进行具体说明. 1)线程创建 方法1:通过创建Thread类的子类并重写run () 方法 class M…...

MySQL数据库基本使用(二)-------数据库及表的增删改查及字符集修改

1.MySQL数据库的使用演示 1.1创建自己的数据库 命令格式如下&#xff08;创建的数据库名称不能与已经存在的数据库重名&#xff09;&#xff1a; mysql> create database 数据库名;例如&#xff1a; mysql> create database atguigudb; #创建atguigudb数据库&#xf…...

互联网摸鱼日报(2023-03-17)

互联网摸鱼日报&#xff08;2023-03-17&#xff09; InfoQ 热门话题 开源新生代的成长之路&#xff1a;从校园到开源&#xff0c;需要迈过哪些挑战&#xff1f; 从 Clickhouse 到 Apache Doris&#xff0c;慧策电商 SaaS 高并发数据服务的改造实践 刚刚&#xff0c;百度文心…...

【前后端】低代码平台Jeecg-Boot 3.2宝塔云服务器部署流程

1 后端 部署流程 修改配置文件 更改数据库、redis的配置。 在system子模块中的target文件夹下生成 jar 包jeecg-boot-module-system-3.2.0.jar。 复制到云服务器 生成数据库 在这里插入图片描述 使用命令运行后端程序 java -jar ./jeecg-boot-module-system-3.2.0.jar宝…...

leetcode todolist

数组 数组的改变、移动 453. 最小移动次数使数组元素相等 665. 非递减数列 283. 移动零 数组的旋转 189. 旋转数组 396. 旋转函数 统计数组中的元素 645. 错误的集合 697. 数组的度 448. 找到所有数组中消失的数字 442. 数组中重复的数据 41. 缺失的第一个正数 数…...

改进YOLO系列 | CVPR2023最新 PConv | 提供 YOLOv5 / YOLOv7 / YOLOv7-tiny 模型 YAML 文件

DWConv是Conv的一种流行变体,已被广泛用作许多神经网络的关键构建块。对于输入 I ∈ R c h w I \in R^{c \times h \times w} I∈...

像ChatGPT玩转Excel数据

1.引言 最近ChatGPT的出现&#xff0c;把人工智能又带起了一波浪潮。机器人能否替代人类又成了最近热门的话题。 今天我们推荐的一个玩法和ChatGPT有点不一样。我们的课题是“让用户可以使用自然语言从Excel查询到自己想要的数据”。 要让自然语言可以从Excel中查数据&#…...

云原生之docker容器监控详解(cAdvisor、node exporter、prometheus)

docker容器监控一、前言二、cAdvisor2.1、安装cAdvisor2.2、使用Prometheus监控cAdvisor2.3、cAdvisor暴露的Prometheus指标三、Node Exporter3.1、安装Node Exporter3.2、指标四、Prometheus4.1、安装4.2、规则配置4.3、报警管理器五、grafana一、前言 cAdvisor源码 node exp…...

<Linux>进程概念

文章目录一、什么是进程1.进程概念2.进程描述 – PCB3.task_struct内容分类二、进程的基本操作1.查看进程2.结束进程3.通过系统调用获取进程标示符4.通过系统调用创建子进程(fork)三、进程状态1.普遍的操作系统状态2.Linux操作系统状态四、两种特殊的进程1.僵尸进程2.孤儿进程五…...

数据结构——顺序表

文章目录&#x1f428;0. 前言&#x1f388;1. 顺序表的概念及定义&#x1fa81;2. 接口的声明&#x1fa84;3. 接口的实现&#x1f345;3.1 为何使用断言&#xff1f;&#x1f352;3.2 初始化与销毁&#x1f353;3.3 尾插与尾删&#x1f349;3.4 头插与头删&#x1f379;3.5 指…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...

路由基础-路由表

本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中&#xff0c;往往存在多个不同的IP网段&#xff0c;数据在不同的IP网段之间交互是需要借助三层设备的&#xff0c;这些设备具备路由能力&#xff0c;能够实现数据的跨网段转发。 路由是数据通信网络中最基…...