Date: Tue, 13 Jul 2010 10:52:42 +0300 From: Alexander Motin <mav@FreeBSD.org> To: Bruce Evans <brde@optusnet.com.au> Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org Subject: Re: svn commit: r209900 - head/sys/kern Message-ID: <4C3C1B4A.5070501@FreeBSD.org> In-Reply-To: <20100713162403.T62787@delplex.bde.org> References: <201007111647.o6BGlk0O033551@svn.freebsd.org> <201007120813.19223.jhb@freebsd.org> <4C3B0F63.6000905@FreeBSD.org> <20100713162403.T62787@delplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Bruce Evans wrote: > Fix for cputick calibration: > > % diff -c2 ./kern/kern_tc.c~ ./kern/kern_tc.c > % *** ./kern/kern_tc.c~ Thu Mar 20 01:05:27 2008 > % --- ./kern/kern_tc.c Thu Mar 20 01:05:29 2008 > % *************** > % *** 884,888 **** > % return; > % % ! getbinuptime(&t_this); > % c_this = cpu_ticks(); > % if (t_last.sec != 0) { > % --- 884,888 ---- > % return; > % % ! binuptime(&t_this); > % c_this = cpu_ticks(); > % if (t_last.sec != 0) { > > Minor fix for accuracy. > > % *************** > % *** 922,931 **** > % c_delta <<= 20; > % c_delta /= divi; > % ! if (c_delta > cpu_tick_frequency) { > % ! if (0 && bootverbose) > % ! printf("cpu_tick increased to %ju Hz\n", > % ! c_delta); > % ! cpu_tick_frequency = c_delta; > % ! } > % } > % } > % --- 922,930 ---- > % c_delta <<= 20; > % c_delta /= divi; > % ! if (0 && bootverbose) > % ! printf( > % ! "cpu_tick_frequency changed from %ju to %ju Hz\n", > % ! cpu_tick_frequency, c_delta); > % ! cpu_tick_frequency = c_delta; > % } > % } > > Variable frequencies have the interesting capability of varying in > both positive and negative directions. This fixes the case of > negative-going changes. Without this, the overflowing timecounter > cases caused cpu_tick_frequency to become huge (100's of times the > correct value), and it was clamped to the hugest value ever seen. The > way this mostly fixes the problem is that cpu_tick_frequency can be > off by a factor of 100, but only for 16 seconds or so until the next > calibration fixes it. I have no hardware to check, but I have feeling that calibration didn't work well also for older CPUs with variable TSC frequency, when frequency is decreasing. I see TSC timecounter frequency changed at tsc_freq_changed(), but set_cputicker() is not called there to adopt it, neither calibration can reduce it by itself. > I don't use this in the same kernels that have the fix for the > timecounters. An integrated fix would prevent recalibration until 16 > seconds after the timecounter has been restored. > > Setting cpu_tick_variable to 0 is an even simpler fix if the cputicker > is not very variable. Yes. In fact cputicker is invariable for the most of modern x86 CPUs. But it's frequency is not always precisely known. > Without this, normal frequency drift due to temperature changes caused > cpu_tick frequency to become larger than the correct value by a few > ppm. Again it was clamped to the largest value ever seen, but errors > of a few ppm are hard to see. -- Alexander Motin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4C3C1B4A.5070501>