[Power/Heat] 20.9版本的电源管理是怎么回事,性能模式的代码写的什么鬼!??
Tofloor
poster avatar
DebuggerX
deepin
2023-04-28 22:06
Author

起因

我给自己写了个在手机上监控系统性能的app,可以随时方便地看到电脑当前的各种信息,界面长这样的:

image.png

图中处理器的指示器,以及中间每个核心的指示器,内部的圆环表示当前CPU/核心的工作频率,外圈表示利用率,这样我就可以在工作时,尤其是编译代码的时候,清楚知道CPU有没有拖后腿。

然后上周更新了20.9之后,发现在使用我一直使用的平衡性能模式下,性能监控显示的却是下面的样子:

image.png

可以看到,虽然是在空载状态,每个核心明明占用率都极低,却都运行在最高频率,这显然是不正常的。

于是在使用如下代码监控了cpu的性能模式:

watch -n 1 'cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'

然后在控制中心的电源管理中,来回切换性能模式,结果发现果然当选择的是 平衡模式时,CPU实际运行的确实 性能模式(performance)

但是上周和本周前两天在优先解决另外一个更影响我使用的问题:[经验分享] 分享让用户可以自己强制指定系统缩放的方法,所以只能先搁置,直到昨天终于有空开始调查原因。

调查

我首先是去Github看了https://github.com/linuxdeepin/dde-daemon/tree/master/system/power1相关的代码,看了半天虽然感觉有些地方的逻辑也有点奇怪,但是没发现明显会导致我现在这种情况的代码。

然后又看了 /var/log/daemon.log 里的日志,发现4月17(没更新前)的日志是这样的:

2023-04-17 20:12:01 debuggerx-e5 daemon/system/power[1178]:  power_key_edit.go:110:  getDsgData key :  BalanceCpuGovernor  , value :  ondemand
2023-04-17 20:12:01 debuggerx-e5 daemon/system/power[1178]:  manager.go:353:  init end. getSupportGovernors :  [conservative ondemand userspace powersave performance schedutil]  , m.balanceScalingGovernor :  ondemand

而4月18(更新后)的日志就变成了这样:

2023-04-18 09:22:14 debuggerx-e5 dde-system-daemon[1166]:   manager.go:386:  init end. m.balanceScalingGovernor :  performance
2023-04-18 09:22:14 debuggerx-e5 daemon/system/power[1166]:  manager.go:386:  init end. m.balanceScalingGovernor :  performance
2023-04-18 09:22:14 debuggerx-e5 dde-system-daemon[1166]:   manager.go:616: [doSetMode] Set Governor, balanceScalingGovernor :  performance
2023-04-18 09:22:14 debuggerx-e5 dde-system-daemon[1166]:   cpu_handler.go:322:  SetGovernor governor :  performance
2023-04-18 09:22:14 debuggerx-e5 daemon/system/power[1166]:  manager.go:616: [doSetMode] Set Governor, balanceScalingGovernor :  performance
2023-04-18 09:22:14 debuggerx-e5 daemon/system/power[1166]:  cpu_handler.go:322:  SetGovernor governor :  performance

然后根据日志里的代码行号去看源码,发现居然完全找不到对应的代码???

通过 dpkg -l | grep dde-daemon查询系统的 dde-daemon版本是 5.14.137 ,但是Github上没有这个版本,于是看的是最接近的5.14.129版本

于是只能把 /etc/apt/sources.listdeb-src的注释放开,然后用 apt source dde-daemon才下载到了正确的源码……

分析

拿到源码,直接根据上面的日志里给到的代码行号看,结果就看到了如下代码:

612 func (m *Manager) doSetMode(mode string) error { 
613         var err error 
614         switch mode { 
615         case "balance": 
616                 logger.Info("[doSetMode] Set Governor, balanceScalingGovernor : ", m.balanceScalingGovernor) 
617  
618                 m.setPropPowerSavingModeEnabled(false) 
619  
620                 err = m.doSetCpuGovernor(m.balanceScalingGovernor) 
621                 if err != nil { 
622                         logger.Warning(err) 
623                 }

可以看到设置为平衡模式时,实际是使用 m.balanceScalingGovernor这个变量的值来设置的,所以再看这个变量是怎么来的:

32 const ( 
 33         configManagerId                   = "org.desktopspec.ConfigManager" 
 34         _configHwSystem                   = "/usr/share/uos-hw-config" 
 35         configDefaultGovFilePattern       = `config-[0-9\.]+-.*-desktop` 
 36         configDefaultGovContentDDEPattern = `CONFIG_CPU_FREQ_DEFAULT_GOV_DDE_(\w+)` 
 37         configDefaultGovContentPattern    = `CONFIG_CPU_FREQ_DEFAULT_GOV_(\w+)` 
 38 )

…………

319 func (m *Manager) refreshSystemPowerPerformance() { // 获取系统支持的性能模式 
    …………
338         re := regexp.MustCompile(configDefaultGovFilePattern) 
339         if result, err := utils.FindFileInDirRegexp("/boot/", re); err != nil { 
340                 logger.Warning(err) 
341         } else if len(result) > 0 { 
342                 re = regexp.MustCompile(configDefaultGovContentDDEPattern) 
343                 _, matches, err := utils.FindContentInFileRegexp(result[0], re) 
344                 if err != nil { 
345                         logger.Warning(err) 
346                         re = regexp.MustCompile(configDefaultGovContentPattern) 
347                         _, matches, err = utils.FindContentInFileRegexp(result[0], re) 
348                         if err != nil { 
349                                 logger.Warning(err) 
350                         } 
351                 } 
352                 if len(matches) > 1 { 
353                         m.balanceScalingGovernor = strings.ToLower(matches[1]) 
354                 } 
355         } 
356  
357         if m.balanceScalingGovernor == "" { 
358                 logger.Warning("can't find balance scaling governor use ondemand") 
359                 m.balanceScalingGovernor = "ondemand" 
360         }

说明下这段代码:

  1. 首先去 /boot/ 目录下去找config文件,这个文件是系统内核编译时的配置,取找到的第一个进项下一步,找不到的话将平衡模式的调度器设置为 ondemand
  2. 在config文件中找以 CONFIG_CPU_FREQ_DEFAULT_GOV_DDE_ 开头的行,并把第一个找到的项目的后面的内容转小写设置为平衡模式的调度器,如果没找到进行下一步
  3. 在config文件中找以 CONFIG_CPU_FREQ_DEFAULT_GOV_ 开头的行,并把第一个找到的项目的后面的内容转小写设置为平衡模式的调度器找不到的话将平衡模式的调度器设置为 ondemand

而看下我当前的config文件的内容,没有任何以 CONFIG_CPU_FREQ_DEFAULT_GOV_DDE_ 开头的行,以 CONFIG_CPU_FREQ_DEFAULT_GOV_ 开头的行则是下面的样子:

CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set

所以在根据上面的代码和分析,m.balanceScalingGovernor这个变量就会被设置为performance。。。
我试了下,只要把上面内容里的第一行和第二行换下位置,甚至不用放开注释,也不用修改成CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y,重启后我的平衡模式就可以正常设置成schedutil了!

质疑

虽然本人水平不高,对Linux系统以及开发顶多算一知半解,但是上面的这个代码是在是难以理解难以接受。

  1. 怎么会想到用config文件来判断呢?要知道用户可能会安装多个版本的内核,boot目录下就会存在多个config文件,粗暴地取第一个找到的文件显然会导致不确定的结果,更不要说这个文件本身也是可以随意修改的
  2. 除去往内核选项里随意加CONFIG_CPU_FREQ_DEFAULT_GOV_DDE_XXX这样的选项是不是符合规范,单纯用正则匹配到的行来设置变量是不是有点过于不专业了?就像我的改法,只要把未解开设置也未设置值的选项移动到上面的位置,就可以影响代码的执行结果,实在是有点扯了吧?
  3. 为什么已经发布的版本,却在Github上找不到对应的源代码,那这还算是“开源项目”吗?要不是知道可以用 apt source 下载源码,我不知道还要自己瞎琢磨吓找多久;不光是这个版本的 dde-daemon,我之前找屏幕分辨率的问题时就发现了Github上找不到正确版本的startdde(系统版本5.9.70,开源版本则是5.9.64);另外还有上面代码里的utils.FindContentInFileRegexp方法,看上去来自https://github.com/linuxdeepin/go-lib/tree/master/utils,实际去找却根本找不到这个方法,也就是说下载到的这份代码在我机器上根本就编译不了,要不是这个问题还算简单,看代码猜猜逻辑就够了,否则不知道要花多少时间精力才能解决。

希望有知情的同学可以解释一下这是什么情况,上面的那些代码该不会还要进入到v23吧?

我用deepin已经差不多10年了,可以说感情很深很深了,但是如果之后还总是出现这样的问题,可能我也不得不放弃了吧……

Reply Favorite View the author
All Replies
2 / 2
To page
青稚
deepin
2023-04-28 23:47
#21

官方看到会有所动作的。like

Reply View the author
longlong
deepin
Developer
2023-04-28 23:52
#22
fslong

感谢楼主,在楼主的启发下,我的v23改成了intel_cpufreq,真是舒服。

另外,关闭intel_pstate之后,默认会启用ondermand的调度,这个目前测试比较平衡舒服。

但如果你在控制中心动了电源管理,切换到平衡或者高性能,调度又会变成performance,立马开始发烫了,重启才会好。

只关闭intel_pstate:

image.png

切换到平衡模式:

image.png

切换到高性能模式:

image.png

这个问题我们已经注意到,在23版本中我们会提供一个用户自己管理电源策略的功能,由用户修改电源策略,dde并不介入

Reply View the author
jiutian123
deepin
2023-04-29 22:54
#23
longlong

这个问题我们已经注意到,在23版本中我们会提供一个用户自己管理电源策略的功能,由用户修改电源策略,dde并不介入

like

加油

Reply View the author
catubibu
deepin
2023-05-18 05:42
#24

开卷有益,来论坛每天发现一两个坑,填坑不亦乐乎。今天把平衡改成节能了,5600g从3.9G降到1.4G左右了。

感谢楼主和各楼

Reply View the author
乐阿兰那
deepin
2023-06-06 21:11
#25

@DebuggerX 大佬,您写的这个性能监控APP,我看着很欢喜,求下载地址。

另外,能写一个Win11 x64的吗??

谢谢

Reply View the author
DebuggerX
deepin
2023-06-08 22:23
#26
乐阿兰那

@DebuggerX 大佬,您写的这个性能监控APP,我看着很欢喜,求下载地址。

另外,能写一个Win11 x64的吗??

谢谢

由于APP使用前需要向系统安装服务程序,这个安装流程的自动化我还没想清楚怎么弄,所以暂时不好放出来。Windows按理说不难支持,但是我不用Windows很久了,也没动力做,除非后面有很多人需要,否则短期应该不会支持。

估计一个月内能放出来吧。

Reply View the author
把一切操作变成GUI
deepin
Backbone of ecological co-construction group
2023-07-10 10:05
#27
乐阿兰那

@DebuggerX 大佬,您写的这个性能监控APP,我看着很欢喜,求下载地址。

另外,能写一个Win11 x64的吗??

谢谢

我也想要这个app😂

Reply View the author
DebuggerX
deepin
2023-07-12 17:55
#28
把一切操作变成GUI

我也想要这个app😂

自动化安装脚本快整好了,我再自测完善完善就可以放出来了

Reply View the author
2 / 2
To page