Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Dec 2010 10:55:58 GMT
From:      Hiro Aki <anycmd@mamemilk.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/152738: vmstat, printhdr() doesn't work correctly with -p option under multiple CPUs
Message-ID:  <201012011055.oB1AtwxM037275@red.freebsd.org>
Resent-Message-ID: <201012011100.oB1B0MGT008396@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         152738
>Category:       bin
>Synopsis:       vmstat, printhdr() doesn't work correctly with -p option under multiple CPUs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Dec 01 11:00:21 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Hiro Aki
>Release:        8.1.0
>Organization:
Any Command Reading Club
>Environment:
>Description:
vmstat with -P option under multi-CPU environment doesn't display the header correctly if it has a cpu unavailable. 

the reason is below:
in the function "printhdr()", ncpus  is the number of CPUs available, not the number of all CPUs. so it might have the case that printf() is not called enough times for the number of all CPUs. 

842:		for (i = 0; i < ncpus; i++) {
843:			if (cpumask & (1ul << i))
844:				printf("cpu%-2d    ", i);
845:		}

on the other hand, "pcpustats()", which display the state of multiple CPUs, this works fine, using maxid which is the number of all CPUs.  
1122:	for (i = 0; i <= maxid; i++) {
1123:		if ((cpumask & (1ul << i)) == 0)
1124:			continue;
1125:		for (state = 0; state < CPUSTATES; ++state) {
1126:			tmp = cur_cp_times[i * CPUSTATES + state];
1127:			cur_cp_times[i * CPUSTATES + state] -= last_cp_times[i *
CPUSTATES + state];
1128:			last_cp_times[i * CPUSTATES + state] = tmp;
1129:		}
1130:	}

>How-To-Repeat:
did the code inspection and haven't actually run the problem. don't have multi-cpu machine for the first place lol.
>Fix:
this is a patch for vmstat.c at revision 1.109
http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/usr.bin/vmstat/vmstat.c


*** vmstat.c	2010-11-29 23:18:40.000000000 +0900
--- vmstatCorrected.c	2010-11-29 23:20:21.000000000 +0900
***************
*** 169,175 ****
  static void	needhdr(int);
  static void	needresize(int);
  static void	doresize(void);
! static void	printhdr(int, u_long);
  static void	usage(void);
  
  static long	pct(long, long);
--- 169,175 ----
  static void	needhdr(int);
  static void	needresize(int);
  static void	doresize(void);
! static void	printhdr(int, u_long, int);
  static void	usage(void);
  
  static long	pct(long, long);
***************
*** 707,713 ****
  	}
  	for (hdrcnt = 1;;) {
  		if (!--hdrcnt)
! 			printhdr(ncpus, cpumask);
  		if (kd != NULL) {
  			if (kvm_getcptime(kd, cur.cp_time) < 0)
  				errx(1, "kvm_getcptime: %s", kvm_geterr(kd));
--- 707,713 ----
  	}
  	for (hdrcnt = 1;;) {
  		if (!--hdrcnt)
!             printhdr(ncpus, cpumask, maxid);
  		if (kd != NULL) {
  			if (kvm_getcptime(kd, cur.cp_time) < 0)
  				errx(1, "kvm_getcptime: %s", kvm_geterr(kd));
***************
*** 758,764 ****
                          errx(1, "%s", devstat_errbuf);
                          break;
                      case 1:
!                         printhdr(ncpus, cpumask);
                          break;
                      default:
                          break;
--- 758,764 ----
                          errx(1, "%s", devstat_errbuf);
                          break;
                      case 1:
!                         printhdr(ncpus, cpumask, maxid);
                          break;
                      default:
                          break;
***************
*** 827,833 ****
  }
  
  static void
! printhdr(int ncpus, u_long cpumask)
  {
  	int i, num_shown;
      
--- 827,833 ----
  }
  
  static void
! printhdr(int ncpus, u_long cpumask, int maxid)
  {
  	int i, num_shown;
      
***************
*** 839,845 ****
  		(void)printf("disk");
  	(void)printf("   faults         ");
  	if (Pflag) {
! 		for (i = 0; i < ncpus; i++) {
  			if (cpumask & (1ul << i))
  				printf("cpu%-2d    ", i);
  		}
--- 839,845 ----
  		(void)printf("disk");
  	(void)printf("   faults         ");
  	if (Pflag) {
!         for (i = 0; i <= maxid; i++) {
  			if (cpumask & (1ul << i))
  				printf("cpu%-2d    ", i);
  		}


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201012011055.oB1AtwxM037275>