From ce1410a51a624a91816fcc8c232c8a4d60b09638 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Wed, 8 Feb 2012 23:59:59 -0600 Subject: [PATCH] top: fixup logic for Nehalem cpu 'idle' threshold Due to a poorly constructed temporary fprintf used during development, an earlier commit went a little too far in its computations. The net result was the code looked nice but actually accomplished nothing. It is the /proc/stat line 1 (summary line) whose tics must be used in establishing the threshold boundary. And that calculation need be performed just once per frame. This commit ensures one threshold calculation per delay interval no matter how many cpus are ultimately displayed. It also corrects scalability by factoring in the total number of online processors. Reference: commit 9e7dd43ab7b2e68177cefd49b3c07311ea79bc1a --- top/top.c | 14 ++++++++++---- top/top.h | 8 +++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/top/top.c b/top/top.c index 2105076e..d0b40acc 100644 --- a/top/top.c +++ b/top/top.c @@ -1826,6 +1826,12 @@ static CPU_t *cpus_refresh (CPU_t *cpus) { cpus[Cpu_faux_tot].cur.tot = cpus[Cpu_faux_tot].cur.u + cpus[Cpu_faux_tot].cur.s + cpus[Cpu_faux_tot].cur.n + cpus[Cpu_faux_tot].cur.i + cpus[Cpu_faux_tot].cur.w + cpus[Cpu_faux_tot].cur.x + cpus[Cpu_faux_tot].cur.y + cpus[Cpu_faux_tot].cur.z; + /* if a Nehalem type cpu has been turned off completely, and thus registers + very few total tics, we'll force it to be treated as idle when that total + falls below a % of those expected -- other cpus will register their full + number of expected tics as 'idle' and thus won't be effected */ + cpus[Cpu_faux_tot].edge = + ((cpus[Cpu_faux_tot].cur.tot - cpus[Cpu_faux_tot].sav.tot) / smp_num_cpus) / (100 / TICS_EDGE); // now value each separate cpu's tics, maybe for (i = 0; i < Cpu_faux_tot && i < Screen_rows; i++) { @@ -1844,9 +1850,9 @@ static CPU_t *cpus_refresh (CPU_t *cpus) { memmove(&cpus[i], &cpus[Cpu_faux_tot], sizeof(CPU_t)); break; // tolerate cpus taken offline } - cpus[i].cur.tot = cpus[i].cur.u + cpus[i].cur.s - + cpus[i].cur.n + cpus[i].cur.i + cpus[i].cur.w - + cpus[i].cur.x + cpus[i].cur.y + cpus[i].cur.z; + cpus[i].edge = cpus[Cpu_faux_tot].edge; + // this is for symmetry only, it's not currently required + cpus[i].cur.tot = cpus[Cpu_faux_tot].cur.tot; #ifdef PRETEND4CPUS cpus[i].id = i; #endif @@ -3338,7 +3344,7 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) { #ifdef CPU_ZEROTICS if (1 > tot_frme) tot_frme = 1; #else - if (tot_frme < (cpu->cur.tot - cpu->sav.tot) / 10) + if (tot_frme < cpu->edge) tot_frme = u_frme = s_frme = n_frme = i_frme = w_frme = x_frme = y_frme = z_frme = 0; if (1 > tot_frme) i_frme = tot_frme = 1; #endif diff --git a/top/top.h b/top/top.h index fda84412..e8606878 100644 --- a/top/top.h +++ b/top/top.h @@ -129,6 +129,11 @@ -- used at startup and for task/thread mode transitions */ #define PROC_XTRA -1 + /* This is the % used in establishing the tics threshold below + which a cpu is treated as 'idle' rather than displaying + misleading state percentages */ +#define TICS_EDGE 20 + /* ##### Enum's and Typedef's ############################################ */ @@ -214,12 +219,13 @@ typedef struct CT_t { 2.6.0 kernel: x == hi (hardware irq time), y == si (software irq time) 2.6.11 kernel: z == st (virtual steal time) */ TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat - SIC_t tot; // total of above + SIC_t tot; // total from /proc/stat line 1 } CT_t; typedef struct CPU_t { CT_t cur; // current frame's cpu tics CT_t sav; // prior frame's cpu tics + SIC_t edge; // tics adjustment threshold boundary int id; // the cpu id number (0 - nn) } CPU_t; -- 2.40.0