diff --git a/NEWS b/NEWS index b3cd29a4..4f2b0bcc 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ w: stale utmp entries snuck in via uninitialized var -- thanks Robert A Basch pgrep/pkill: fix some realloc-related crashes #353894 pgrep/pkill: g is criteria (PLD Linux, patch found in locked filing cabinet) sysctl: use - for stdin (PLD Linux: beware of the leopard) +top: show CPU time stolen from a virtual machine procps-3.2.5 --> procps-3.2.6 diff --git a/proc/sysinfo.c b/proc/sysinfo.c index 095bb68e..9a8f843f 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -238,11 +238,11 @@ static void init_libproc(void){ #define NAN (-0.0) #endif #define JT unsigned long long -void seven_cpu_numbers(double *restrict uret, double *restrict nret, double *restrict sret, double *restrict iret, double *restrict wret, double *restrict xret, double *restrict yret){ - double tmp_u, tmp_n, tmp_s, tmp_i, tmp_w, tmp_x, tmp_y; +void eight_cpu_numbers(double *restrict uret, double *restrict nret, double *restrict sret, double *restrict iret, double *restrict wret, double *restrict xret, double *restrict yret, double *restrict zret){ + double tmp_u, tmp_n, tmp_s, tmp_i, tmp_w, tmp_x, tmp_y, tmp_z; double scale; /* scale values to % */ - static JT old_u, old_n, old_s, old_i, old_w, old_x, old_y; - JT new_u, new_n, new_s, new_i, new_w, new_x, new_y; + static JT old_u, old_n, old_s, old_i, old_w, old_x, old_y, old_z; + JT new_u, new_n, new_s, new_i, new_w, new_x, new_y, new_z; JT ticks_past; /* avoid div-by-0 by not calling too often :-( */ tmp_w = 0.0; @@ -251,10 +251,12 @@ void seven_cpu_numbers(double *restrict uret, double *restrict nret, double *res new_x = 0; tmp_y = 0.0; new_y = 0; + tmp_z = 0.0; + new_z = 0; FILE_TO_BUF(STAT_FILE,stat_fd); - sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &new_u, &new_n, &new_s, &new_i, &new_w, &new_x, &new_y); - ticks_past = (new_u+new_n+new_s+new_i+new_w+new_x+new_y)-(old_u+old_n+old_s+old_i+old_w+old_x+old_y); + sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &new_u, &new_n, &new_s, &new_i, &new_w, &new_x, &new_y, &new_z); + ticks_past = (new_u+new_n+new_s+new_i+new_w+new_x+new_y+new_z)-(old_u+old_n+old_s+old_i+old_w+old_x+old_y+old_z); if(ticks_past){ scale = 100.0 / (double)ticks_past; tmp_u = ( (double)new_u - (double)old_u ) * scale; @@ -264,6 +266,7 @@ void seven_cpu_numbers(double *restrict uret, double *restrict nret, double *res tmp_w = ( (double)new_w - (double)old_w ) * scale; tmp_x = ( (double)new_x - (double)old_x ) * scale; tmp_y = ( (double)new_y - (double)old_y ) * scale; + tmp_z = ( (double)new_z - (double)old_z ) * scale; }else{ tmp_u = NAN; tmp_n = NAN; @@ -272,21 +275,24 @@ void seven_cpu_numbers(double *restrict uret, double *restrict nret, double *res tmp_w = NAN; tmp_x = NAN; tmp_y = NAN; + tmp_z = NAN; } SET_IF_DESIRED(uret, tmp_u); SET_IF_DESIRED(nret, tmp_n); SET_IF_DESIRED(sret, tmp_s); SET_IF_DESIRED(iret, tmp_i); SET_IF_DESIRED(wret, tmp_w); - SET_IF_DESIRED(iret, tmp_x); - SET_IF_DESIRED(wret, tmp_y); + SET_IF_DESIRED(xret, tmp_x); + SET_IF_DESIRED(yret, tmp_y); + SET_IF_DESIRED(zret, tmp_z); old_u=new_u; old_n=new_n; old_s=new_s; old_i=new_i; old_w=new_w; - old_i=new_x; - old_w=new_y; + old_x=new_x; + old_y=new_y; + old_z=new_z; } #undef JT #endif @@ -361,7 +367,7 @@ static void getrunners(unsigned int *restrict running, unsigned int *restrict bl /***********************************************************************/ -void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, +void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, jiff *restrict czzz, unsigned long *restrict pin, unsigned long *restrict pout, unsigned long *restrict s_in, unsigned long *restrict sout, unsigned *restrict intr, unsigned *restrict ctxt, unsigned int *restrict running, unsigned int *restrict blocked, @@ -384,9 +390,10 @@ void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *ciow = 0; /* not separated out until the 2.5.41 kernel */ *cxxx = 0; /* not separated out until the 2.6.0-test4 kernel */ *cyyy = 0; /* not separated out until the 2.6.0-test4 kernel */ + *czzz = 0; /* not separated out until the 2.6.11 kernel */ b = strstr(buff, "cpu "); - if(b) sscanf(b, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", cuse, cice, csys, cide, ciow, cxxx, cyyy); + if(b) sscanf(b, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", cuse, cice, csys, cide, ciow, cxxx, cyyy, czzz); b = strstr(buff, "page "); if(b) sscanf(b, "page %lu %lu", pin, pout); diff --git a/proc/sysinfo.h b/proc/sysinfo.h index ceff5eef..e30a38b9 100644 --- a/proc/sysinfo.h +++ b/proc/sysinfo.h @@ -12,7 +12,7 @@ extern int have_privs; /* boolean, true if setuid or similar */ #if 0 #define JT double -extern void seven_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret, JT *wret, JT *xret, JT *yret); +extern void eight_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret, JT *wret, JT *xret, JT *yret, JT *zret); #undef JT #endif @@ -56,7 +56,7 @@ extern unsigned long kb_pagetables; #define BUFFSIZE (64*1024) typedef unsigned long long jiff; -extern void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, +extern void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, jiff *restrict czzz, unsigned long *restrict pin, unsigned long *restrict pout, unsigned long *restrict s_in, unsigned long *restrict sout, unsigned *restrict intr, unsigned *restrict ctxt, unsigned int *restrict running, unsigned int *restrict blocked, diff --git a/top.c b/top.c index 67bab375..e0ab5990 100644 --- a/top.c +++ b/top.c @@ -934,14 +934,16 @@ static CPU_t *cpus_refresh (CPU_t *cpus) if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); cpus[Cpu_tot].x = 0; // FIXME: can't tell by kernel version number cpus[Cpu_tot].y = 0; // FIXME: can't tell by kernel version number - num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", + cpus[Cpu_tot].z = 0; // FIXME: can't tell by kernel version number + num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &cpus[Cpu_tot].u, &cpus[Cpu_tot].n, &cpus[Cpu_tot].s, &cpus[Cpu_tot].i, &cpus[Cpu_tot].w, &cpus[Cpu_tot].x, - &cpus[Cpu_tot].y + &cpus[Cpu_tot].y, + &cpus[Cpu_tot].z ); if (num < 4) std_err("failed /proc/stat read"); @@ -957,9 +959,10 @@ static CPU_t *cpus_refresh (CPU_t *cpus) if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); cpus[i].x = 0; // FIXME: can't tell by kernel version number cpus[i].y = 0; // FIXME: can't tell by kernel version number - num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu", + cpus[i].z = 0; // FIXME: can't tell by kernel version number + num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &cpus[i].id, - &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y + &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z ); if (num < 4) std_err("failed /proc/stat read"); @@ -1601,6 +1604,8 @@ static void before (char *me) States_fmts = STATES_line2x5; if (linux_version_code >= LINUX_VERSION(2, 6, 0)) // grrr... only some 2.6.0-testX :-( States_fmts = STATES_line2x6; + if (linux_version_code >= LINUX_VERSION(2, 6, 11)) + States_fmts = STATES_line2x7; /* get virtual page size -- nearing huge! */ Page_size = getpagesize(); @@ -2874,7 +2879,7 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) // we'll trim to zero if we get negative time ticks, // which has happened with some SMP kernels (pre-2.4?) #define TRIMz(x) ((tz = (SIC_t)(x)) < 0 ? 0 : tz) - SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, tot_frme, tz; + SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, z_frme, tot_frme, tz; float scale; u_frme = cpu->u - cpu->u_sav; @@ -2884,7 +2889,8 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) w_frme = cpu->w - cpu->w_sav; x_frme = cpu->x - cpu->x_sav; y_frme = cpu->y - cpu->y_sav; - tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme; + z_frme = cpu->z - cpu->z_sav; + tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme + z_frme; if (tot_frme < 1) tot_frme = 1; scale = 100.0 / (float)tot_frme; @@ -2901,7 +2907,8 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) (float)i_frme * scale, (float)w_frme * scale, (float)x_frme * scale, - (float)y_frme * scale + (float)y_frme * scale, + (float)z_frme * scale ) ); Msg_row += 1; @@ -2914,6 +2921,7 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) cpu->w_sav = cpu->w; cpu->x_sav = cpu->x; cpu->y_sav = cpu->y; + cpu->z_sav = cpu->z; #undef TRIMz } diff --git a/top.h b/top.h index de0a7201..b4ac0794 100644 --- a/top.h +++ b/top.h @@ -211,8 +211,8 @@ typedef struct HST_t { // calculations. It exists primarily for SMP support but serves // all environments. typedef struct CPU_t { - TIC_t u, n, s, i, w, x, y; // as represented in /proc/stat - TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav; // in the order of our display + TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat + TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav, z_sav; // in the order of our display unsigned id; // the CPU ID number } CPU_t; @@ -389,6 +389,8 @@ typedef struct WIN_t { " %#5.1f%% \02user,\03 %#5.1f%% \02system,\03 %#5.1f%% \02nice,\03 %#5.1f%% \02idle,\03 %#5.1f%% \02IO-wait\03\n" #define STATES_line2x6 "%s\03" \ " %#4.1f%% \02us,\03 %#4.1f%% \02sy,\03 %#4.1f%% \02ni,\03 %#4.1f%% \02id,\03 %#4.1f%% \02wa,\03 %#4.1f%% \02hi,\03 %#4.1f%% \02si\03\n" +#define STATES_line2x7 "%s\03" \ + "%#5.1f%%\02us,\03%#5.1f%%\02sy,\03%#5.1f%%\02ni,\03%#5.1f%%\02id,\03%#5.1f%%\02wa,\03%#5.1f%%\02hi,\03%#5.1f%%\02si,\03%#5.1f%%\02st\03\n" #ifdef CASEUP_SUMMK #define MEMORY_line1 "Mem: \03" \ " %8luK \02total,\03 %8luK \02used,\03 %8luK \02free,\03 %8luK \02buffers\03\n" diff --git a/vmstat.8 b/vmstat.8 index 65ff7c1a..c059ec05 100644 --- a/vmstat.8 +++ b/vmstat.8 @@ -113,7 +113,8 @@ These are percentages of total CPU time. us: Time spent running non-kernel code. (user time, including nice time) sy: Time spent running kernel code. (system time) id: Time spent idle. Prior to Linux 2.5.41, this includes IO-wait time. -wa: Time spent waiting for IO. Prior to Linux 2.5.41, shown as zero. +wa: Time spent waiting for IO. Prior to Linux 2.5.41, included in idle. +st: Time stolen from a virtual machine. Prior to Linux 2.6.11, unknown. .PP .SH FIELD DESCRIPTION FOR DISK MODE diff --git a/vmstat.c b/vmstat.c index 386f9a5e..a2d3c24b 100644 --- a/vmstat.c +++ b/vmstat.c @@ -150,9 +150,9 @@ static int format_1000(unsigned long long val64, char *restrict dst){ //////////////////////////////////////////////////////////////////////////// static void new_header(void){ - printf("procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----\n"); + printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n"); printf( - "%2s %2s %6s %6s %6s %6s %4s %4s %5s %5s %4s %5s %2s %2s %2s %2s\n", + "%2s %2s %6s %6s %6s %6s %4s %4s %5s %5s %4s %4s %2s %2s %2s %2s\n", "r","b", "swpd", "free", a_option?"inact":"buff", a_option?"active":"cache", "si","so", @@ -173,13 +173,13 @@ static unsigned long unitConvert(unsigned int size){ //////////////////////////////////////////////////////////////////////////// static void new_format(void) { - const char format[]="%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %5u %2u %2u %2u %2u\n"; + const char format[]="%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n"; unsigned int tog=0; /* toggle switch for cleaner code */ unsigned int i; unsigned int hz = Hertz; unsigned int running,blocked,dummy_1,dummy_2; - jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2], cpu_xxx[2], cpu_yyy[2]; - jiff duse, dsys, didl, diow, Div, divo2; + jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2], cpu_xxx[2], cpu_yyy[2], cpu_zzz[2]; + jiff duse, dsys, didl, diow, dstl, Div, divo2; unsigned long pgpgin[2], pgpgout[2], pswpin[2], pswpout[2]; unsigned int intr[2], ctxt[2]; unsigned int sleep_half; @@ -190,7 +190,7 @@ static void new_format(void) { new_header(); meminfo(); - getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl,cpu_iow,cpu_xxx,cpu_yyy, + getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl,cpu_iow,cpu_xxx,cpu_yyy,cpu_zzz, pgpgin,pgpgout,pswpin,pswpout, intr,ctxt, &running,&blocked, @@ -200,7 +200,8 @@ static void new_format(void) { dsys= *cpu_sys + *cpu_xxx + *cpu_yyy; didl= *cpu_idl; diow= *cpu_iow; - Div= duse+dsys+didl+diow; + dstl= *cpu_zzz; + Div= duse+dsys+didl+diow+dstl; divo2= Div/2UL; printf(format, running, blocked, @@ -216,7 +217,8 @@ static void new_format(void) { (unsigned)( (100*duse + divo2) / Div ), (unsigned)( (100*dsys + divo2) / Div ), (unsigned)( (100*didl + divo2) / Div ), - (unsigned)( (100*diow + divo2) / Div ) + (unsigned)( (100*diow + divo2) / Div ) /* , + (unsigned)( (100*dstl + divo2) / Div ) */ ); for(i=1;i