From ba82cdf5be78b46889dc0d1e3906e353489925ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= Date: Thu, 9 Jan 2020 01:42:35 +0100 Subject: [PATCH] tdehwlib: Fix parsing of CPU cores frequency information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + The current frequency is parsed from the scaling_cur_freq file If the current frequency is not found in /proc/cpuinfo, the attempt to read value from cpuinfo_cur_freq failed because only root can read this file. + The have_frequency flag is not set when parsing current frequency from sysfs Setting the have_frequency flag after parsing current frequency for the first core caused the current frequency not to be parsed for other cores. + Frequency characteristics are parsed for all cores The assumption that the frequency characteristics for all cores will be the same as the first core is no longer reliable. There are heterogeneous architectures - for example ARM big.LITTLE. Signed-off-by: Slávek Banko --- tdecore/tdehw/tdehardwaredevices.cpp | 148 +++++++++++++-------------- 1 file changed, 71 insertions(+), 77 deletions(-) diff --git a/tdecore/tdehw/tdehardwaredevices.cpp b/tdecore/tdehw/tdehardwaredevices.cpp index 2fbe293e5..7d222d6f7 100644 --- a/tdecore/tdehw/tdehardwaredevices.cpp +++ b/tdecore/tdehw/tdehardwaredevices.cpp @@ -656,8 +656,6 @@ void TDEHardwareDevices::processModifiedCPUs() { time1 = time2; #endif - TDECPUDevice* firstCPU = NULL; - // Read in other information from cpufreq, if available for (processorNumber=0; processorNumber(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber))); @@ -672,79 +670,62 @@ void TDEHardwareDevices::processModifiedCPUs() { TQStringList governorlist; if (cpufreq_dir.exists()) { TQString nodename; - if ((processorNumber == 0) || (!firstCPU)) { - // Remember the first CPU options so that we can reuse it later. - firstCPU = cdevice; - - nodename = cpufreq_dir.path(); - nodename.append("/scaling_governor"); - TQFile scalinggovernorfile(nodename); - if (scalinggovernorfile.open(IO_ReadOnly)) { - TQTextStream stream( &scalinggovernorfile ); - scalinggovernor = stream.readLine(); - scalinggovernorfile.close(); - } - nodename = cpufreq_dir.path(); - nodename.append("/scaling_driver"); - TQFile scalingdriverfile(nodename); - if (scalingdriverfile.open(IO_ReadOnly)) { - TQTextStream stream( &scalingdriverfile ); - scalingdriver = stream.readLine(); - scalingdriverfile.close(); - } - nodename = cpufreq_dir.path(); - nodename.append("/cpuinfo_min_freq"); - TQFile minfrequencyfile(nodename); - if (minfrequencyfile.open(IO_ReadOnly)) { - TQTextStream stream( &minfrequencyfile ); - minfrequency = stream.readLine().toDouble()/1000.0; - minfrequencyfile.close(); - } - nodename = cpufreq_dir.path(); - nodename.append("/cpuinfo_max_freq"); - TQFile maxfrequencyfile(nodename); - if (maxfrequencyfile.open(IO_ReadOnly)) { - TQTextStream stream( &maxfrequencyfile ); - maxfrequency = stream.readLine().toDouble()/1000.0; - maxfrequencyfile.close(); - } - nodename = cpufreq_dir.path(); - nodename.append("/cpuinfo_transition_latency"); - TQFile trlatencyfile(nodename); - if (trlatencyfile.open(IO_ReadOnly)) { - TQTextStream stream( &trlatencyfile ); - trlatency = stream.readLine().toDouble()/1000.0; - trlatencyfile.close(); - } - nodename = cpufreq_dir.path(); - nodename.append("/scaling_available_frequencies"); - TQFile availfreqsfile(nodename); - if (availfreqsfile.open(IO_ReadOnly)) { - TQTextStream stream( &availfreqsfile ); - frequencylist = TQStringList::split(" ", stream.readLine()); - availfreqsfile.close(); - } - nodename = cpufreq_dir.path(); - nodename.append("/scaling_available_governors"); - TQFile availgvrnsfile(nodename); - if (availgvrnsfile.open(IO_ReadOnly)) { - TQTextStream stream( &availgvrnsfile ); - governorlist = TQStringList::split(" ", stream.readLine()); - availgvrnsfile.close(); - } + nodename = cpufreq_dir.path(); + nodename.append("/scaling_governor"); + TQFile scalinggovernorfile(nodename); + if (scalinggovernorfile.open(IO_ReadOnly)) { + TQTextStream stream( &scalinggovernorfile ); + scalinggovernor = stream.readLine(); + scalinggovernorfile.close(); } - // Other CPU should have the same values as the first one. Simply copy them. - else { - scalinggovernor = firstCPU->governor(); - scalingdriver = firstCPU->scalingDriver(); - minfrequency = firstCPU->minFrequency(); - maxfrequency = firstCPU->maxFrequency(); - trlatency = firstCPU->transitionLatency(); - frequencylist = firstCPU->availableFrequencies(); - governorlist = firstCPU->availableGovernors(); + nodename = cpufreq_dir.path(); + nodename.append("/scaling_driver"); + TQFile scalingdriverfile(nodename); + if (scalingdriverfile.open(IO_ReadOnly)) { + TQTextStream stream( &scalingdriverfile ); + scalingdriver = stream.readLine(); + scalingdriverfile.close(); + } + nodename = cpufreq_dir.path(); + nodename.append("/cpuinfo_min_freq"); + TQFile minfrequencyfile(nodename); + if (minfrequencyfile.open(IO_ReadOnly)) { + TQTextStream stream( &minfrequencyfile ); + minfrequency = stream.readLine().toDouble()/1000.0; + minfrequencyfile.close(); + } + nodename = cpufreq_dir.path(); + nodename.append("/cpuinfo_max_freq"); + TQFile maxfrequencyfile(nodename); + if (maxfrequencyfile.open(IO_ReadOnly)) { + TQTextStream stream( &maxfrequencyfile ); + maxfrequency = stream.readLine().toDouble()/1000.0; + maxfrequencyfile.close(); + } + nodename = cpufreq_dir.path(); + nodename.append("/cpuinfo_transition_latency"); + TQFile trlatencyfile(nodename); + if (trlatencyfile.open(IO_ReadOnly)) { + TQTextStream stream( &trlatencyfile ); + trlatency = stream.readLine().toDouble()/1000.0; + trlatencyfile.close(); + } + nodename = cpufreq_dir.path(); + nodename.append("/scaling_available_frequencies"); + TQFile availfreqsfile(nodename); + if (availfreqsfile.open(IO_ReadOnly)) { + TQTextStream stream( &availfreqsfile ); + frequencylist = TQStringList::split(" ", stream.readLine()); + availfreqsfile.close(); + } + nodename = cpufreq_dir.path(); + nodename.append("/scaling_available_governors"); + TQFile availgvrnsfile(nodename); + if (availgvrnsfile.open(IO_ReadOnly)) { + TQTextStream stream( &availgvrnsfile ); + governorlist = TQStringList::split(" ", stream.readLine()); + availgvrnsfile.close(); } - - // The following data are different on each CPU nodename = cpufreq_dir.path(); nodename.append("/affected_cpus"); TQFile tiedcpusfile(nodename); @@ -756,16 +737,29 @@ void TDEHardwareDevices::processModifiedCPUs() { // We may already have the CPU Mhz information in '/proc/cpuinfo' if (!have_frequency) { + bool cpufreq_have_frequency = false; nodename = cpufreq_dir.path(); - nodename.append("/cpuinfo_cur_freq"); + nodename.append("/scaling_cur_freq"); TQFile cpufreqfile(nodename); if (cpufreqfile.open(IO_ReadOnly)) { + cpufreq_have_frequency = true; + } + else { + nodename = cpufreq_dir.path(); + nodename.append("/cpuinfo_cur_freq"); + cpufreqfile.setName(nodename); + if (cpufreqfile.open(IO_ReadOnly)) { + cpufreq_have_frequency = true; + } + } + if (cpufreq_have_frequency) { TQTextStream stream( &cpufreqfile ); - if (cdevice) { - cdevice->internalSetFrequency(stream.readLine().toDouble()/1000.0); + double cpuinfo_cur_freq = stream.readLine().toDouble()/1000.0; + if (cdevice && cdevice->frequency() != cpuinfo_cur_freq) { + modified = true; + cdevice->internalSetFrequency(cpuinfo_cur_freq); } cpufreqfile.close(); - have_frequency = true; } }