* Workaround for buggy PIT
@ 2006-03-14 18:05 Tomas Kopal
2006-03-15 12:32 ` Keir Fraser
0 siblings, 1 reply; 5+ messages in thread
From: Tomas Kopal @ 2006-03-14 18:05 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: Type: text/plain, Size: 987 bytes --]
Hi all,
I am using xen for some time now and I am very happy with it, thanks for
all the good work.
The only problem I had with xen on our server was that sometimes
(usually few times per day) the time in dom0 went berserk and started
running about three times faster. The only fix for that was reboot of
the machine.
I remember seeing similar problems reported long time ago on this list,
although I can't locate them at the moment.
Well, in my case, I traced the problem down to a buggy chipset. The
VIA686a PIT timer randomly looses it's programming and needs to be
reset. The linux kernel has a workaround for this, but this does not get
used when xen comes to play as the hypervisor takes over control of the PIT.
I have implemented similar workaround in xen hypervisor. So far I am
running it for about three weeks now and the server is perfectly stable.
I am interested in your comments, and I would be happy if you could
apply this patch to xen sources.
Thanks
Tomas Kopal
[-- Attachment #2: xen-timer.c.diff --]
[-- Type: text/plain, Size: 2196 bytes --]
diff -r f4cef1aa2521 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Tue Mar 14 16:09:34 2006 +0100
+++ b/xen/arch/x86/time.c Tue Mar 14 19:14:35 2006 +0100
@@ -286,6 +286,7 @@ static u64 pit_counter64;
static u64 pit_counter64;
static u16 pit_stamp;
+#define LATCH (((CLOCK_TICK_RATE)+(HZ/2))/HZ)
static u16 pit_read_counter(void)
{
u16 count;
@@ -293,6 +294,32 @@ static u16 pit_read_counter(void)
outb(0x80, PIT_MODE);
count = inb(PIT_CH2);
count |= inb(PIT_CH2) << 8;
+
+ /* VIA686 Timer bug workaround
+ The timer sometimes looses it's programming, returning huge
+ counts. The delta counted should not be more than LATCH in
+ ideal world, but due to interrupt being disabled sometimes,
+ we can get longer intervals. Account for that by accepting
+ double the LATCH value.
+ To correct the error, we need to reset the counter. The
+ information about time elapsed is lost, so assume the interval
+ was LATCH long. This can make a slight difference in timer speed
+ if we were called from timer calibration code. It should not
+ be too much and it should be corrected on next callibration round.
+ */
+ if (pit_stamp - count > 2 * LATCH)
+ {
+ printk(KERN_WARNING "PIT Timer HW error: %u\n", pit_stamp - count);
+ /* reset the timer */
+ outb(0xb0, PIT_MODE); /* binary, mode 0, LSB/MSB, Ch 2 */
+ outb(LATCH & 0xff, PIT_CH2); /* LSB of count */
+ outb(LATCH >> 8, PIT_CH2); /* MSB of count */
+ /* reset the stamp */
+ pit_stamp = LATCH;
+ /* correct the count returned to make LATCH difference */
+ count = 0;
+ }
+
return count;
}
@@ -315,6 +342,13 @@ static void init_pit(void)
static void init_pit(void)
{
read_platform_count = read_pit_count;
+
+ /* setup the timer */
+ spin_lock_irq(&platform_timer_lock);
+ outb(0xb0, PIT_MODE); /* binary, mode 0, LSB/MSB, Ch 2 */
+ outb(0, PIT_CH2); /* LSB of count */
+ outb(0, PIT_CH2); /* MSB of count */
+ spin_unlock_irq(&platform_timer_lock);
pit_overflow();
platform_timer_stamp = pit_counter64;
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: Workaround for buggy PIT 2006-03-14 18:05 Workaround for buggy PIT Tomas Kopal @ 2006-03-15 12:32 ` Keir Fraser 2006-03-15 19:52 ` Tomas Kopal 0 siblings, 1 reply; 5+ messages in thread From: Keir Fraser @ 2006-03-15 12:32 UTC (permalink / raw) To: Tomas Kopal; +Cc: xen-devel On 14 Mar 2006, at 18:05, Tomas Kopal wrote: > Well, in my case, I traced the problem down to a buggy chipset. The > VIA686a PIT timer randomly looses it's programming and needs to be > reset. The linux kernel has a workaround for this, but this does not > get > used when xen comes to play as the hypervisor takes over control of > the PIT. > I have implemented similar workaround in xen hypervisor. So far I am > running it for about three weeks now and the server is perfectly > stable. > > I am interested in your comments, and I would be happy if you could > apply this patch to xen sources. Do you have any details on what mode the timer enters when it loses its programming, whether this affects all PIT channels, etc? The patch is potentially okay -- it differs from Linux in that we free-run channel 2 (we don't periodically and automatically re-latch) and so the Linux test for count > latch does not work. The test you use (diff > 2*latch) is kind of weird, even if it does seem to work for you: I wonder what kind of mode it enters where readings make it look like it is running at three times normal speed? Also, although you detect and fix up channel 2 problems, all that code is driven off the channel 0 timer interrupt handler. What happens if ch0 loses its programming? :-) Really I want to understand this problem rather better before committing a patch for a six-year-old chipset. -- Keir ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Workaround for buggy PIT 2006-03-15 12:32 ` Keir Fraser @ 2006-03-15 19:52 ` Tomas Kopal 2006-03-15 22:44 ` Keir Fraser 0 siblings, 1 reply; 5+ messages in thread From: Tomas Kopal @ 2006-03-15 19:52 UTC (permalink / raw) To: Keir Fraser; +Cc: xen-devel On 15.3.2006 13:32, Keir Fraser wrote: > > On 14 Mar 2006, at 18:05, Tomas Kopal wrote: > >> Well, in my case, I traced the problem down to a buggy chipset. The >> VIA686a PIT timer randomly looses it's programming and needs to be >> reset. The linux kernel has a workaround for this, but this does not get >> used when xen comes to play as the hypervisor takes over control of >> the PIT. >> I have implemented similar workaround in xen hypervisor. So far I am >> running it for about three weeks now and the server is perfectly stable. >> >> I am interested in your comments, and I would be happy if you could >> apply this patch to xen sources. > > Do you have any details on what mode the timer enters when it loses its > programming, whether this affects all PIT channels, etc? Well, there is not much info on this. There is no official VIA info, only speculations. Probably the most info I found on LKLM. The best summary I found is here: http://www.uwsg.iu.edu/hypermail/linux/kernel/0111.0/1613.html and http://www.uwsg.iu.edu/hypermail/linux/kernel/0205.3/1068.html One of initial problem descriptions: http://www.uwsg.iu.edu/hypermail/linux/kernel/0205.2/1405.html It seems to affect only one channel AFAIK, but it's not always the same (Linux kernel is using channel 0, Xen channel 2, and the problem is the same for both). It's probably not affecting all channels together, as bug on channel 1 could be quite disastrous to the memory contents. But similar problems may be in other chipsets too: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q274323 http://support.microsoft.com/default.aspx?scid=kb;en-us;Q266344 So having a bit more "robust" PIT handling should generally help. > The patch is > potentially okay -- it differs from Linux in that we free-run channel 2 > (we don't periodically and automatically re-latch) and so the Linux test > for count > latch does not work. The test you use (diff > 2*latch) is > kind of weird, even if it does seem to work for you: I wonder what kind > of mode it enters where readings make it look like it is running at > three times normal speed? I think that the mode is not changed, just the immediate value in the timer. My explanation is that the timer sometimes (probably when the system is under heavy load, like during domU shutdown) returns "random jump", probably by resetting current timer value to some other, random one, but continues counting. If this happen during calibration call, the calibrated values are completely off, and the system time starts to run away due to using invalid calibration data. Together with xntpd it can get even more messy. (Just for the record, I tried to turn xntpd in dom0 off, but the problem remained). But this is not backed up by any real evidence, so take it with heaps of salt :-). The test for diff > 2*latch is a bit of heuristics :-). You are right that this differs from Linux, Xen is not resetting the counter to latch but free running it. But the diff between subsequent values should be always near the latch value, as this is driven by the channel 0 set to interrupt by latch. I was printing out real diff values (detecting min and max over periods of time) and it varied about 40% around the latch value. I didn't want to get too many false positives, so I set it to double the expected value. As the problematic values tend to be quite high, I think this is a safe threshold. > > Also, although you detect and fix up channel 2 problems, all that code > is driven off the channel 0 timer interrupt handler. What happens if ch0 > loses its programming? :-) Don't know. It either does not loose it, or the effect of it loosing it is not that obvious. Do you know any easy way how to detect this? (i.e. detect missing or late interrupts? We can't use channel 2 as we can't trust it. Maybe we can use the TSC?) As I said, I expect the timer to continue counting, so if I am right, the only problem which it can cause is that the timer will come a bit later. Apart from time keeping, this should not be a big deal, or is it? As I am thinking about this now, the cause may even be that the counter problem is in channel 0 only. Then the timer interrupt would come a lot later and the difference in values of channel 2 could overflow to negative values? > > Really I want to understand this problem rather better before committing > a patch for a six-year-old chipset. > > -- Keir Yes, the chipset is quite old. We were already thinking about replacing it, but after this fix, it will probably have to serve a bit longer :-). I share your desire to understand the problem, but I still don't understand it, and it seems that the people from LKLM didn't completely understood it either. And according to the MSDN records, it may be quite wide-spread, even on newer chipsets... Feel free to make it compile-time option, or just move it to contrib. But if it can save trouble I had to go through to anyone, it would be definitely beneficial to have in the mainstream, especially when it does not add any penalty to fault-less systems. Thanks a lot Tomas ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Workaround for buggy PIT 2006-03-15 19:52 ` Tomas Kopal @ 2006-03-15 22:44 ` Keir Fraser 2006-03-16 20:47 ` Tomas Kopal 0 siblings, 1 reply; 5+ messages in thread From: Keir Fraser @ 2006-03-15 22:44 UTC (permalink / raw) To: Tomas Kopal; +Cc: xen-devel On 15 Mar 2006, at 19:52, Tomas Kopal wrote: > I was printing out real diff values (detecting min and max over periods > of time) and it varied about 40% around the latch value. I didn't want > to get too many false positives, so I set it to double the expected > value. As the problematic values tend to be quite high, I think this is > a safe threshold. 40% range is huge, given that Xen disables interrupts only for very short periods of time. If you think that the timer ends up corrupting its count value, but continues counting in the mode we originally programmed it to, there would be no need for your patch to reprogram the timer. We could just clamp diff and let the timer continue to free-run from whatever value it corrupted itself to. Would that simpler patch, with no reprogramming, work for you? I agree with your suspicion that this may be a channel-0 problem. The 40% value range points at some serious weirdness. As for other timer problems -- the really common one (latched reads do not latch, so you get inconsistent 16-bit reads) don't long-term affect our time stability. We end up out by a few hundred microseconds on that read of the clock, but the 16-bit timer value doesn't wrap or anything really bad like that, so we can recover. Phew. :-) -- Keir ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Workaround for buggy PIT 2006-03-15 22:44 ` Keir Fraser @ 2006-03-16 20:47 ` Tomas Kopal 0 siblings, 0 replies; 5+ messages in thread From: Tomas Kopal @ 2006-03-16 20:47 UTC (permalink / raw) To: Keir Fraser, xen-devel OK, gathered a bit more data. On 15.3.2006 23:44, Keir Fraser wrote: > > On 15 Mar 2006, at 19:52, Tomas Kopal wrote: > >> I was printing out real diff values (detecting min and max over periods >> of time) and it varied about 40% around the latch value. I didn't want >> to get too many false positives, so I set it to double the expected >> value. As the problematic values tend to be quite high, I think this is >> a safe threshold. > > 40% range is huge, given that Xen disables interrupts only for very > short periods of time. Sorry, I overshot. It's up to 30%. Here is part of my debug log, using TSC. It was gathering minimum and maximum values over time approximately 15 minutes each line. It's still a lot though, but as these are absolute extremes over long period of time, it may be not as bad most of the time. (XEN) Stats: min_tsc = 7272785, max_tsc = 9728578 (XEN) Stats: min_tsc = 6315016, max_tsc = 10686693 (XEN) Stats: min_tsc = 7287942, max_tsc = 9717338 (XEN) Stats: min_tsc = 7349398, max_tsc = 9653272 (XEN) Stats: min_tsc = 7101256, max_tsc = 9898106 (XEN) Stats: min_tsc = 6246158, max_tsc = 10753919 (XEN) Stats: min_tsc = 6263384, max_tsc = 10999952 (XEN) Stats: min_tsc = 6207822, max_tsc = 10799607 (XEN) Stats: min_tsc = 6919892, max_tsc = 10073639 (XEN) Stats: min_tsc = 6137085, max_tsc = 10864224 (XEN) Stats: min_tsc = 6276877, max_tsc = 10724951 (XEN) Stats: min_tsc = 7151101, max_tsc = 9848466 (XEN) Stats: min_tsc = 7020142, max_tsc = 9978974 (XEN) Stats: min_tsc = 7002859, max_tsc = 9992022 > > If you think that the timer ends up corrupting its count value, but > continues counting in the mode we originally programmed it to, there > would be no need for your patch to reprogram the timer. We could just > clamp diff and let the timer continue to free-run from whatever value it > corrupted itself to. Would that simpler patch, with no reprogramming, > work for you? I tried not to reset the timer and once the error appeared, it didn't go away for quite a long time (it did disappear at the end though). It definitely was not one time problem only. That leads me to believe that the mode IS changed after all, and it switches to mode with pre-programmed reset value, so the counter does not overflow as expected with free-run and the result of the subtraction is flawed. > > I agree with your suspicion that this may be a channel-0 problem. The > 40% value range points at some serious weirdness. As you can see from the following snippet, if we can trust TSC, the channel 0 is not affected when the error occur, the interrupts still occur regularly. (XEN) Stats: min_tsc = 6125635, max_tsc = 11387514 (XEN) Stats: min_tsc = 5518772, max_tsc = 11457692 (XEN) Stats: min_tsc = 6331729, max_tsc = 10671097 (XEN) PIT Timer HW error: 40750 (XEN) Stats: min_tsc = 6137681, max_tsc = 10868227 (XEN) Stats: min_tsc = 6372589, max_tsc = 10626930 (XEN) Stats: min_tsc = 6096761, max_tsc = 10902500 (XEN) Stats: min_tsc = 6218072, max_tsc = 10784801 (XEN) Stats: min_tsc = 6232108, max_tsc = 10775067 (XEN) Stats: min_tsc = 6088005, max_tsc = 10914563 (XEN) PIT Timer HW error: 39470 (XEN) Stats: min_tsc = 5037753, max_tsc = 11961922 (XEN) Stats: min_tsc = 6189690, max_tsc = 10810470 (XEN) Stats: min_tsc = 6247146, max_tsc = 10754276 Thanks Tomas ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-03-16 20:47 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-03-14 18:05 Workaround for buggy PIT Tomas Kopal 2006-03-15 12:32 ` Keir Fraser 2006-03-15 19:52 ` Tomas Kopal 2006-03-15 22:44 ` Keir Fraser 2006-03-16 20:47 ` Tomas Kopal
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.