op-packages/luci-app-cpu-perf/root/usr/share/rpcd/ucode/luci.cpu-perf
github-actions[bot] 32600acc60 🌴 Sync 2026-03-05 23:51:42
2026-03-05 23:51:42 +08:00

182 lines
5.7 KiB
Plaintext

'use strict';
import { basename, lsdir, readfile, readlink, stat } from 'fs';
const sysCpuDir = '/sys/devices/system/cpu';
const sysFreqPolicyDir = sysCpuDir + '/cpufreq';
const sysOndemandDir = sysFreqPolicyDir + '/ondemand';
const sysConservativeDir = sysFreqPolicyDir + '/conservative';
const sysPcieAspmPolicyFile = '/sys/module/pcie_aspm/parameters/policy';
const sysEasFile = '/proc/sys/kernel/sched_energy_aware';
function readFile(path) {
let r = readfile(path);
return r && trim(r);
}
function parseMultiValue(s, number) {
if(!s) {
return null;
}
let t = [];
s = replace(s, /[\]\[]/g, '');
for(let i in split(s, /[[:space:]]+/)) {
push(t, number ? int(i) : i);
}
return t;
}
const methods = {
getCpuPerf: {
call: function() {
let cpuPerf = {};
let eas = {};
let pcieAspm = {};
let ondemand = {};
let conservative = {};
let freqPolicies = {};
let cpus = {};
if(stat(sysEasFile)?.type == 'file') {
let schedEnergyAware = readFile(sysEasFile);
if(schedEnergyAware) {
eas['schedEnergyAware'] = int(schedEnergyAware);
}
cpuPerf['eas'] = eas;
}
if(stat(sysPcieAspmPolicyFile)?.type == 'file') {
let availPolicies = readFile(sysPcieAspmPolicyFile);
if(availPolicies) {
pcieAspm['availPolicies'] = parseMultiValue(availPolicies);
}
let currentPolicy = match(availPolicies, /\[[a-z]+\]/);
pcieAspm['currentPolicy'] = type(currentPolicy) == 'array' ? trim(currentPolicy[0], '[]') : '';
cpuPerf['pcieAspm'] = pcieAspm;
}
if(stat(sysOndemandDir)?.type == 'directory') {
let upThreshold = readFile(sysOndemandDir + '/up_threshold');
let ignNiceLoad = readFile(sysOndemandDir + '/ignore_nice_load');
let smpDownFactor = readFile(sysOndemandDir + '/sampling_down_factor');
let powersaveBias = readFile(sysOndemandDir + '/powersave_bias');
if(upThreshold) {
ondemand['upThreshold'] = int(upThreshold);
}
if(ignNiceLoad) {
ondemand['ignNiceLoad'] = int(ignNiceLoad);
}
if(smpDownFactor) {
ondemand['smpDownFactor'] = int(smpDownFactor);
}
if(powersaveBias) {
ondemand['powersaveBias'] = int(powersaveBias);
}
cpuPerf['ondemand'] = ondemand;
}
if(stat(sysConservativeDir)?.type == 'directory') {
let freqStep = readFile(sysConservativeDir + '/freq_step');
let downThreshold = readFile(sysConservativeDir + '/down_threshold');
let smpDownFactor = readFile(sysConservativeDir + '/sampling_down_factor');
if(freqStep) {
conservative['freqStep'] = int(freqStep);
}
if(downThreshold) {
conservative['downThreshold'] = int(downThreshold);
}
if(smpDownFactor) {
conservative['smpDownFactor'] = int(smpDownFactor);
}
cpuPerf['conservative'] = conservative;
}
if(stat(sysFreqPolicyDir)?.type == 'directory') {
for(let item in lsdir(sysFreqPolicyDir)) {
if(match(item, /^policy[0-9]+$/)) {
let policyDirPath = sprintf('%s/%s', sysFreqPolicyDir, item);
if(stat(policyDirPath)?.type == 'directory') {
let m = match(item, /[0-9]+/);
let dNumber = m && m[0];
if(dNumber) {
let sCurFreq = readFile(policyDirPath + '/scaling_cur_freq');
let curFreq = readFile(policyDirPath + '/cpuinfo_cur_freq');
let sMinFreq = readFile(policyDirPath + '/scaling_min_freq');
let minFreq = readFile(policyDirPath + '/cpuinfo_min_freq');
let sMaxFreq = readFile(policyDirPath + '/scaling_max_freq');
let maxFreq = readFile(policyDirPath + '/cpuinfo_max_freq');
let governor = readFile(policyDirPath + '/scaling_governor');
let sAvailFreqs = readFile(policyDirPath + '/scaling_available_frequencies');
if(sAvailFreqs) {
sAvailFreqs = parseMultiValue(sAvailFreqs, true);
}
let sAvailGovernors = readFile(policyDirPath + '/scaling_available_governors');
if(sAvailGovernors) {
sAvailGovernors = parseMultiValue(sAvailGovernors);
}
let d = { number: int(dNumber) };
if(sCurFreq) {
d['sCurFreq'] = int(sCurFreq);
}
if(curFreq) {
d['curFreq'] = int(curFreq);
}
if(sMinFreq) {
d['sMinFreq'] = int(sMinFreq);
}
if(minFreq) {
d['minFreq'] = int(minFreq);
}
if(sMaxFreq) {
d['sMaxFreq'] = int(sMaxFreq);
}
if(maxFreq) {
d['maxFreq'] = int(maxFreq);
}
if(governor) {
d['governor'] = governor;
}
if(sAvailFreqs) {
d['sAvailFreqs'] = sAvailFreqs;
}
if(sAvailGovernors) {
d['sAvailGovernors'] = sAvailGovernors;
}
d['cpu'] = [];
freqPolicies[dNumber] = d;
}
}
}
}
cpuPerf['freqPolicies'] = freqPolicies;
}
if(stat(sysCpuDir)?.type == 'directory') {
for(let item in lsdir(sysCpuDir)) {
if(match(item, /^cpu[0-9]+$/)) {
let deviceDirPath = sprintf('%s/%s/cpufreq', sysCpuDir, item);
if(stat(deviceDirPath)?.type == 'directory') {
let m = match(item, /[0-9]+/);
let dNumber = m && m[0];
if(dNumber) {
let cpuFreqPath = readlink(deviceDirPath);
if(cpuFreqPath) {
let policy = basename(cpuFreqPath);
let m = match(policy, /[0-9]+/);
policy = m && m[0];
if(policy) {
push(freqPolicies[policy].cpu, int(dNumber));
cpus[dNumber] = {
number: int(dNumber),
policy: int(policy),
};
}
}
}
}
}
}
cpuPerf['cpus'] = cpus;
}
return cpuPerf;
},
},
};
return { 'luci.cpu-perf': methods };