Re: (patch) Re: pmtimer and nanouptime

看板DFBSD_bugs作者時間21年前 (2004/09/28 02:01), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/2 (看更多)
On Tue, Jul 20, 2004 at 12:07:06PM -0700, Matthew Dillon wrote: > Please try this patch. > > -Matt > > Index: i386/isa/clock.c > =================================================================== > RCS file: /cvs/src/sys/i386/isa/clock.c,v > retrieving revision 1.15 > diff -u -r1.15 clock.c > --- i386/isa/clock.c 20 Jul 2004 04:12:08 -0000 1.15 > +++ i386/isa/clock.c 20 Jul 2004 19:02:13 -0000 > @@ -596,17 +596,21 @@ > } > > /* > - * Restore all the timers non-atomically (XXX: should be atomically). > + * Restore all the timers. > * > - * This function is called from apm_default_resume() to restore all the timers. > - * This should not be necessary, but there are broken laptops that do not > - * restore all the timers on resume. > + * This function is called from apm_default_resume() / pmtimer to restore > + * all the timers. We also have to restore our timebases, especially on > + * MP systems, because cputimer_count() counter's delta may have grown > + * too large for nanouptime() and friends to handle. > */ > void > timer_restore(void) > { > + crit_enter(); > i8254_restore(); /* restore timer_freq and hz */ > rtc_restore(); /* reenable RTC interrupts */ > + restoreclocks(); > + crit_exit(); > } > > /* > Index: kern/kern_clock.c > =================================================================== > RCS file: /cvs/src/sys/kern/kern_clock.c,v > retrieving revision 1.21 > diff -u -r1.21 kern_clock.c > --- kern/kern_clock.c 16 Jul 2004 05:51:09 -0000 1.21 > +++ kern/kern_clock.c 20 Jul 2004 19:05:49 -0000 > @@ -196,6 +196,36 @@ > } > > /* > + * Resynchronize gd_cpuclock_base after the system has been woken up from > + * a sleep. It is absolutely essential that all the cpus be properly > + * synchronized. Resynching is required because nanouptime() and friends > + * will overflow intermediate multiplications if more then 2 seconds > + * worth of cputimer_cont() delta has built up. > + */ > +#ifdef SMP > + > +static > +void > +restoreclocks_remote(lwkt_cpusync_t poll) > +{ > + mycpu->gd_cpuclock_base = *(sysclock_t *)poll->cs_data; > + mycpu->gd_time_seconds = globaldata_find(0)->gd_time_seconds; > +} > + > +#endif > + > +void > +restoreclocks(void) > +{ > + sysclock_t base = cputimer_count(); > +#ifdef SMP > + lwkt_cpusync_simple(-1, restoreclocks_remote, &base); > +#else > + mycpu->gd_cpuclock_base = base; > +#endif > +} > + > +/* > * This sets the current real time of day. Timespecs are in seconds and > * nanoseconds. We do not mess with gd_time_seconds and gd_cpuclock_base, > * instead we adjust basetime so basetime + gd_* results in the current > Index: sys/time.h > =================================================================== > RCS file: /cvs/src/sys/sys/time.h,v > retrieving revision 1.8 > diff -u -r1.8 time.h > --- sys/time.h 30 Jan 2004 05:42:18 -0000 1.8 > +++ sys/time.h 20 Jul 2004 19:02:43 -0000 > @@ -192,6 +192,7 @@ > extern time_t time_second; > > void initclocks_pcpu(void); > +void restoreclocks(void); > void getmicrouptime (struct timeval *tv); > void getmicrotime (struct timeval *tv); > void getnanouptime (struct timespec *tv); Can you please back out this change? This was supposed to fix my nanouptime() problem, but unfortunately resulted in system clock to always skew one hour ahead in a short period of time after resuming from ACPI S3 state. I'm using a kernel with this change backed out, but somehow nanouptime() no longer returns strange tv_nsec after resume.
文章代碼(AID): #11M5Ls00 (DFBSD_bugs)
文章代碼(AID): #11M5Ls00 (DFBSD_bugs)