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>
