Subject: kern/26470: all process stop for a long time by calling settimeofday() and setitimer()
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <karino@da.jp.nec.com>
List: netbsd-bugs
Date: 07/29/2004 04:32:58
>Number:         26470
>Category:       kern
>Synopsis:       all process stop for a long time by calling settimeofday() and setitimer()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 29 06:58:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Shuichi karino
>Release:        2.0F
>Organization:
NEC Corp.
>Environment:
NetBSD splpe596.spf.cl.nec.co.jp 2.0F NetBSD 2.0F (DEVENT) #0: Wed Jun  2 10:16:02 JST 2004  nakagawa@splpe596.spf.cl.nec.co.jp:/proj/src/sys/arch/i386/compile/DEVENT i386
>Description:
All process stops for a long time by calling setitimer() with short interval and then putting the system clock forward long.

Following loop is executed many times.
(in kern/kern_time.c:realitexpire())

	for (;;) {
		s = splclock();
		timeradd(&p->p_realtimer.it_value,
		    &p->p_realtimer.it_interval, &p->p_realtimer.it_value);
		if (timercmp(&p->p_realtimer.it_value, &mono_time, >)) {
			/*
			 * Don't need to check hzto() return value, here.
			 * callout_reset() does it for us.
			 */
			callout_reset(&p->p_realit_ch,
			    hzto2(&p->p_realtimer.it_value), realitexpire, p);
			splx(s);
			return;
		}
		splx(s);
	}


>How-To-Repeat:
An sample code to repeat the problem:

#include <sys/time.h>
#include <signal.h>
#include <stdio.h>

void alarm(int sig)
{
	return ;
}

int main()
{
	struct itimerval it;
	struct timeval tv;
	struct sigaction sigact; 

	bzero(&sigact, sizeof(struct sigaction));
	sigact.sa_flags   = SA_RESTART;
	sigact.sa_handler = alarm;

	if (sigaction(SIGALRM, &sigact, NULL) < 0) {
		perror("sigaction");
		exit(1);
	}

	bzero(&it, sizeof(struct itimerval));
	it.it_interval.tv_sec  = 0;
	it.it_interval.tv_usec = 1;
	it.it_value.tv_sec = 0;
	it.it_value.tv_usec = 1;

	if (setitimer(ITIMER_REAL, &it, NULL) < 0) {
		perror("setitimer");
		exit(1);
	}

	if (gettimeofday(&tv, NULL) < 0) {
		perror("gettimeofday");
		exit(1);
	}

	sleep(1);

	tv.tv_sec += 10000000; /* about 4 months */
	if (settimeofday(&tv, NULL) < 0) {
		perror("settimeofday");
		exit(1);
	}

	while (1) {
		sleep(1);
	}

	return 0;
}

/* EOF */

>Fix:

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