Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Sep 1996 17:29:32 -0700 (PDT)
From:      Julian Elischer <julian@current1.whistle.com>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/1652: Version roif itimer patch for -current
Message-ID:  <199609200029.RAA04362@current1.whistle.com>
Resent-Message-ID: <199609200040.RAA08123@freefall.freebsd.org>

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

>Number:         1652
>Category:       kern
>Synopsis:       changing time hangs system
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Sep 19 17:40:02 PDT 1996
>Last-Modified:
>Originator:     Julian Elischer
>Organization:
Whistle Communications
>Release:        FreeBSD 2.2-CURRENT i386
>Environment:

	all -current and stable

>Description:

	If a process has an itimer in effect when the time is radically changed
	the systems freezes for some time.


>How-To-Repeat:

	run the following program, and on another screen, change the time to 1999
	notice that the system freezes for a time..
	this is particularly bad when a system powers up with a bad battery
	and the time in in 1970. When the time is corrected, if an itimer is
	in effect, the system hangs for a while..


#include <sys/time.h>

struct itimerval itv;

main()
{
  
	itv.it_interval.tv_sec = 60;
	itv.it_value.tv_sec = 60;
	setitimer(ITIMER_REAL,&itv,NULL);
	while (1);
}

followed by:
date 9901010101

>Fix:
	
for -current:

Index: kern_time.c
===================================================================
RCS file: /cvs/freebsd/src/sys/kern/kern_time.c,v
retrieving revision 1.17
diff -c -r1.17 kern_time.c
*** 1.17	1996/07/12 07:55:35
--- kern_time.c	1996/09/20 00:28:31
***************
*** 56,61 ****
--- 56,62 ----
   */
  
  static void	timevalfix __P((struct timeval *));
+ static void    recalc_realtimer(struct timeval);
  
  #ifndef _SYS_SYSPROTO_H_
  struct gettimeofday_args {
***************
*** 122,127 ****
--- 123,129 ----
  		 */
  		delta.tv_sec = atv.tv_sec - time.tv_sec;
  		delta.tv_usec = atv.tv_usec - time.tv_usec;
+ 		recalc_realtimer(delta);
  		time = atv;
  		/*
  		 * XXX should arrange for microtime() to agree with atv if
***************
*** 144,149 ****
--- 146,165 ----
  		tz = atz;
  	return (0);
  }
+ 
+ 
+ static void     
+ recalc_realtimer(struct timeval delta)
+ {
+ 	struct proc *p;
+                 
+ 	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
+ 		if (timerisset(&p->p_realtimer.it_value)) {
+ 			timevaladd(&p->p_realtimer.it_value, &delta);
+ 			timevalfix(&p->p_realtimer.it_value);
+ 		}       
+ 	}
+ }      
  
  extern	int tickadj;			/* "standard" clock skew, us./tick */
  int	tickdelta;			/* current clock skew, us. per tick */


It is possible that this should only be called if delta is greater than a particular
size. Also SPL must be considered if the number of processes is large..

I could check this in myself, but I want comments first..
It's a killer for us when we are powering up the interjets for the first time
and they sync their clocks..

julian

>Audit-Trail:
>Unformatted:



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