Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Jun 2009 18:06:32 -0400
From:      Barney Wolff <barney@databus.com>
To:        hardware@freebsd.org
Subject:   slow tick when idle
Message-ID:  <20090603220632.GA79172@pit.databus.com>

next in thread | raw e-mail | index | archive | help
I have an odd problem with wait timing.  When the system is quite busy,
for example doing multiple port builds, waits in select() or sleep()
work fine.  But when the system is otherwise mostly idle, waits run
at least 2.5% slow.  This happens on both a 6-stable from 12/08 and
7-stable from 5/28/09, and whether I use ACPI-fast or HPET.  Time of
day is not affected, only waits.

My machine is a Dell XPS410 with Intel Core2 2.13GHz, 2 cores.  The
problem does not occur on an older single-cpu Athlon XP with 7.2-rel.

Perhaps some artifact of cpu state under light load?

Is this a known problem with a known workaround?
Has anyone else seen it?
If there is no existing PR, I'll file one.

Here's a test program:  (must be run on an idle machine to show the problem)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
/*
	tstselect	sleepsecs=1 nbusy
	Check accuracy of select & sleep wait times, on idle or busy system.
	On my Dell XPS410 the wait is at least 2.5% too long when idle,
	accurate when busy, on both 6-stable and 7-stable.
	Barney Wolff	<barney@databus.com>	6/1/2009
*/

#include <stdio.h>
#include <sys/time.h>
#include <sys/select.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>

struct timeval strt,nd,wait;

int
main(int argc, char *argv[]) {
	if (argc > 1) wait.tv_sec = atoi(argv[1]);
	else wait.tv_sec = 1;
	wait.tv_usec = 0;

	if (argc > 2 && fork() == 0) {		/* busy up */
		int nfork = atoi(argv[2]);
		if (nfork < 0 || nfork > 10) nfork  = 1;
		while (--nfork >= 0) if (fork() == 0) while(1) ;
		exit(0);
	}

	(void)gettimeofday(&strt,NULL);
	(void)select(0,NULL,NULL,NULL,&wait);
	(void)gettimeofday(&nd,NULL);

	printf("select of %d secs waited %d usecs\n",wait.tv_sec,
		1000000*(nd.tv_sec-strt.tv_sec)+(nd.tv_usec-strt.tv_usec));

	(void)gettimeofday(&strt,NULL);
	(void)sleep((unsigned)wait.tv_sec);
	(void)gettimeofday(&nd,NULL);

	printf(" sleep of %d secs waited %d usecs\n",wait.tv_sec,
		1000000*(nd.tv_sec-strt.tv_sec)+(nd.tv_usec-strt.tv_usec));

	kill(0,SIGTERM);
	exit(0);
}
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

uname -a
FreeBSD pit.databus.com 7.2-STABLE FreeBSD 7.2-STABLE #0: Thu May 28 23:58:51 EDT 2009     toor@pit.databus.com:/usr/obj/usr/src/sys/PIT  i386

dmesg.boot is at:  https://bns.databus.com/pics/dmesg.boot
kernel conf is at: https://bns.databus.com/pics/PIT

Thanks for any insights,
Barney

-- 
Barney Wolff         I never met a computer I didn't like.




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