slow tick when idle

Barney Wolff barney at databus.com
Wed Jun 3 22:17:15 UTC 2009


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 at 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 at 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.



More information about the freebsd-hardware mailing list