From: Sebastien GODARD Date: Sat, 20 Nov 2021 15:06:07 +0000 (+0100) Subject: mpstat: Fix values displayed when an offline CPU goes back online X-Git-Tag: v12.5.5~4^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f9bcdb377579f8415d868395f37431d92da047d6;p=sysstat mpstat: Fix values displayed when an offline CPU goes back online Try to avoid values jumping from zero when an offline CPU goes back online. Signed-off-by: Sebastien GODARD --- diff --git a/mpstat.c b/mpstat.c index 2ad621b..727a7ea 100644 --- a/mpstat.c +++ b/mpstat.c @@ -271,6 +271,39 @@ void sfree_mp_struct(void) free(cpu2node); } +/* + *************************************************************************** + * Set interrupt values for current sample to those of previous sample. + * + * IN: + * @st_ic Array for per-CPU interrupts statistics. + * @c Fist CPU to process. + * @last Last CPU to process. + * @ic_nr Number of interrupts (hard or soft) per CPU. + * @curr Position in array where current statistics will be saved. + ************************************************************************** + */ +void fwd_irq_values(struct stats_irqcpu *st_ic[], unsigned int c, + unsigned int last, int ic_nr, int curr) +{ + struct stats_irq *st_irq_i, *st_irq_j; + struct stats_irqcpu *p, *q; + int j; + + while (c < last) { + st_irq_i = st_irq[curr] + c + 1; + st_irq_j = st_irq[!curr] + c + 1; + st_irq_i->irq_nr = st_irq_j->irq_nr; + + for (j = 0; j < ic_nr; j++) { + p = st_ic[curr] + c * ic_nr + j; + q = st_ic[!curr] + c * ic_nr + j; + p->interrupt = q->interrupt; + } + c++; + } +} + /* *************************************************************************** * Get node placement (which node each CPU belongs to, and total number of @@ -1779,16 +1812,10 @@ void read_interrupts_stat(char *file, struct stats_irqcpu *st_ic[], int ic_nr, i struct stats_irqcpu *p; char *line = NULL, *li; unsigned long irq = 0; - unsigned int cpu; + unsigned int cpu, c = 0; int cpu_index[cpu_nr], index = 0, len; char *cp, *next; - /* Reset total number of interrupts received by each CPU */ - for (cpu = 0; cpu < cpu_nr; cpu++) { - st_irq_i = st_irq[curr] + cpu + 1; - st_irq_i->irq_nr = 0; - } - if ((fp = fopen(file, "r")) != NULL) { SREALLOC(line, char, INTERRUPTS_LINE + 11 * cpu_nr); @@ -1801,12 +1828,29 @@ void read_interrupts_stat(char *file, struct stats_irqcpu *st_ic[], int ic_nr, i while (((cp = strstr(next, "CPU")) != NULL) && (index < cpu_nr)) { cpu = strtol(cp + 3, &next, 10); cpu_index[index++] = cpu; + + /* + * Reset total number of interrupts received by a CPU + * only for online CPU. Only needed for st_irq structures. + */ + st_irq_i = st_irq[curr] + cpu + 1; + st_irq_i->irq_nr = 0; + + /* + * For offline CPU, pick up previous values so that when the + * CPU goes back online, values won't jump from zero. + */ + fwd_irq_values(st_ic, c, cpu, ic_nr, curr); + c = cpu + 1; } if (index) /* Header line found */ break; } + /* Process possible offline CPU at the end of the list */ + fwd_irq_values(st_ic, c, cpu_nr, ic_nr, curr); + /* Parse each line of interrupts statistics data */ while ((fgets(line, INTERRUPTS_LINE + 11 * cpu_nr, fp) != NULL) && (irq < ic_nr)) {