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>