From julian@current1.whistle.com  Thu Sep 19 17:31:45 1996
Received: from whistle.com (s205m131.whistle.com [207.76.205.131])
          by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id RAA04054
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 19 Sep 1996 17:31:44 -0700 (PDT)
Received: (from smap@localhost) by whistle.com (8.7.5/8.6.12) id RAA17042 for <FreeBSD-gnats-submit@freebsd.org>; Thu, 19 Sep 1996 17:31:13 -0700 (PDT)
Received: from current1.whistle.com(207.76.205.22) by whistle.com via smap (V1.3)
	id sma017036; Thu Sep 19 17:31:07 1996
Received: (from julian@localhost) by current1.whistle.com (8.7.5/8.7.3) id RAA04362; Thu, 19 Sep 1996 17:29:32 -0700 (PDT)
Message-Id: <199609200029.RAA04362@current1.whistle.com>
Date: Thu, 19 Sep 1996 17:29:32 -0700 (PDT)
From: Julian Elischer <julian@current1.whistle.com>
Reply-To: julian@current1.whistle.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: Version roif itimer patch for -current
X-Send-Pr-Version: 3.2

>Number:         1652
>Category:       kern
>Synopsis:       changing time hangs system
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Sep 19 17:40:02 PDT 1996
>Closed-Date:    Fri Feb 21 16:14:18 PST 1997
>Last-Modified:  Fri Feb 21 16:14:49 PST 1997
>Originator:     Julian Elischer
>Release:        FreeBSD 2.2-CURRENT i386
>Organization:
Whistle Communications
>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

>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: FreeBSD-gnats-submit@freebsd.org, julian@current1.whistle.com
Cc:  Subject: Re: kern/1652: Version roif itimer patch for -current
Date: Fri, 20 Sep 1996 12:09:18 +1000

 >It is possible that this should only be called if delta is greater than a particular
 >size.
 
 No, delta is very unlikely to be small (else adjtime() should have been
 used instead of settimeofday()), and whatever you do to handle large
 adjustments should also work for small adjustements.
 
 >Also SPL must be considered if the number of processes is large..
 
 Yes, walking the queue at splclock() defeats the micro-optimized spl
 placement in settimeofday().  It think atomic update is only necessary
 for each itimer, not for all of them together.
 
 >I could check this in myself, but I want comments first..
 
 Mihoko Tanaka <mihoko@pa.yokogawa.co.jp> posted a similar fix the other
 day.
 
 All versions forgot to remove or update the load comment about this problem.
 
 I wonder why this problem has been around for so long, and why adjkerntz
 doesn't seem to cause it.
 
 Bruce
State-Changed-From-To: open->closed 
State-Changed-By: mpp 
State-Changed-When: Fri Feb 21 16:14:18 PST 1997 
State-Changed-Why:  
Fixed in rev 1.18 of kern_time.c. 
>Unformatted:
