mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-24 21:05:40 +02:00
module/cpu: don’t use core ID from /proc/stat as array index
/proc/stat lists CPU usage, in the form: cpu ... cpu0 ... cpu1 ... ... cpuN ... where the first line is a summary line. We’ve been using the CPU numbers from /proc/stat to index into our internal stats array. This doesn’t work on systems where the core IDs aren’t consecutive. Examples of such systems are SMT systems with SMT disabled. Here, /proc/stat may look like this instead: cpu ... cpu0 ... cpu2 ... cpu4 ... ... With this patch, we ignore the CPU ID from /proc/stat. Instead, we use a simple counter that is incremented for each (valid) cpu line found in /proc/stat. To protect against corrupt /proc/stat content, stop parsing /proc/stat if the number of parsed CPU lines exceed what we consider to the be total number of CPUs in the system. Closes #172
This commit is contained in:
parent
fce2787bdf
commit
62ca06eccb
1 changed files with 26 additions and 18 deletions
|
@ -64,22 +64,27 @@ get_cpu_nb_cores()
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_proc_stat_line(const char *line, int32_t *core, uint32_t *user, uint32_t *nice, uint32_t *system, uint32_t *idle,
|
parse_proc_stat_line(const char *line, uint32_t *user, uint32_t *nice, uint32_t *system, uint32_t *idle,
|
||||||
uint32_t *iowait, uint32_t *irq, uint32_t *softirq, uint32_t *steal, uint32_t *guest,
|
uint32_t *iowait, uint32_t *irq, uint32_t *softirq, uint32_t *steal, uint32_t *guest,
|
||||||
uint32_t *guestnice)
|
uint32_t *guestnice)
|
||||||
{
|
{
|
||||||
|
int32_t core_id;
|
||||||
if (line[sizeof("cpu") - 1] == ' ') {
|
if (line[sizeof("cpu") - 1] == ' ') {
|
||||||
int read = sscanf(line,
|
int read = sscanf(
|
||||||
"cpu %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
line,
|
||||||
" %" SCNu32 " %" SCNu32 " %" SCNu32,
|
"cpu %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||||
user, nice, system, idle, iowait, irq, softirq, steal, guest, guestnice);
|
" %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32,
|
||||||
*core = -1;
|
user, nice, system, idle, iowait, irq, softirq, steal, guest,
|
||||||
|
guestnice);
|
||||||
return read == 10;
|
return read == 10;
|
||||||
} else {
|
} else {
|
||||||
int read = sscanf(line,
|
int read = sscanf(
|
||||||
"cpu%" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
line,
|
||||||
" %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32,
|
"cpu%" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||||
core, user, nice, system, idle, iowait, irq, softirq, steal, guest, guestnice);
|
" %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||||
|
" %" SCNu32,
|
||||||
|
&core_id, user, nice, system, idle, iowait, irq, softirq, steal,
|
||||||
|
guest, guestnice);
|
||||||
return read == 11;
|
return read == 11;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,20 +130,23 @@ refresh_cpu_stats(struct cpu_stats *cpu_stats)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((read = getline(&line, &len, fp)) != -1) {
|
while ((read = getline(&line, &len, fp)) != -1 && core <= nb_cores) {
|
||||||
if (strncmp(line, "cpu", sizeof("cpu") - 1) == 0) {
|
if (strncmp(line, "cpu", sizeof("cpu") - 1) == 0) {
|
||||||
if (!parse_proc_stat_line(line, &core, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal,
|
if (!parse_proc_stat_line(
|
||||||
&guest, &guestnice)
|
line, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal,
|
||||||
|| core < -1 || core >= (int32_t)nb_cores) {
|
&guest, &guestnice))
|
||||||
|
{
|
||||||
LOG_ERR("unable to parse /proc/stat line");
|
LOG_ERR("unable to parse /proc/stat line");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_stats->prev_cores_idle[core + 1] = cpu_stats->cur_cores_idle[core + 1];
|
cpu_stats->prev_cores_idle[core] = cpu_stats->cur_cores_idle[core];
|
||||||
cpu_stats->prev_cores_nidle[core + 1] = cpu_stats->cur_cores_nidle[core + 1];
|
cpu_stats->prev_cores_nidle[core] = cpu_stats->cur_cores_nidle[core];
|
||||||
|
|
||||||
cpu_stats->cur_cores_idle[core + 1] = idle + iowait;
|
cpu_stats->cur_cores_idle[core] = idle + iowait;
|
||||||
cpu_stats->cur_cores_nidle[core + 1] = user + nice + system + irq + softirq + steal;
|
cpu_stats->cur_cores_nidle[core] = user + nice + system + irq + softirq + steal;
|
||||||
|
|
||||||
|
core++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
|
|
Loading…
Add table
Reference in a new issue