public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86: fix hpet timer reinit for x86_64
@ 2009-02-04 10:40 Pavel Emelyanov
  2009-02-04 11:39 ` Vitaly Mayatskikh
  2009-02-04 13:49 ` Ingo Molnar
  0 siblings, 2 replies; 7+ messages in thread
From: Pavel Emelyanov @ 2009-02-04 10:40 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Linux Kernel Mailing List, Kirill Korotaev

There's a small problem with hpet_rtc_reinit function - it checks
for the
	hpet_readl(HPET_COUNTER) - hpet_t1_cmp > 0
to continue increasing both the HPET_T1_CMP (register) and the 
hpet_t1_cmp (variable).

But since the HPET_COUNTER is always 32-bit, if the hpet_t1_cmp
is 64-bit this condition will always be FALSE once the latter hits
the 32-bit boundary, and we can have a situation, when we don't
increase the HPET_T1_CMP register high enough.

The result - timer stops ticking, since HPET_T1_CMP becomes less, 
than the COUNTER and never increased again.

The solution is to cut the upper 32-bit from the hpet_t1_cmp
variable to make the comparison to HPET_COUNTER correct.

Reported-by: Kirill Korotaev <dev@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---

diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 64d5ad0..ec319d1 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -1075,7 +1075,7 @@ static void hpet_rtc_timer_reinit(void)
 		hpet_t1_cmp += delta;
 		hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
 		lost_ints++;
-	} while ((long)(hpet_readl(HPET_COUNTER) - hpet_t1_cmp) > 0);
+	} while ((long)(hpet_readl(HPET_COUNTER) - (u32)hpet_t1_cmp) > 0);
 
 	if (lost_ints) {
 		if (hpet_rtc_flags & RTC_PIE)

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86: fix hpet timer reinit for x86_64
  2009-02-04 10:40 [PATCH] x86: fix hpet timer reinit for x86_64 Pavel Emelyanov
@ 2009-02-04 11:39 ` Vitaly Mayatskikh
  2009-02-04 11:43   ` Kirill Korotaev
  2009-02-04 11:51   ` Pavel Emelyanov
  2009-02-04 13:49 ` Ingo Molnar
  1 sibling, 2 replies; 7+ messages in thread
From: Vitaly Mayatskikh @ 2009-02-04 11:39 UTC (permalink / raw)
  To: Pavel Emelyanov
  Cc: Thomas Gleixner, Linux Kernel Mailing List, Kirill Korotaev

At Wed, 04 Feb 2009 13:40:31 +0300, Pavel Emelyanov wrote:
> 
> There's a small problem with hpet_rtc_reinit function - it checks
> for the
> 	hpet_readl(HPET_COUNTER) - hpet_t1_cmp > 0
> to continue increasing both the HPET_T1_CMP (register) and the 
> hpet_t1_cmp (variable).
> 
> But since the HPET_COUNTER is always 32-bit, if the hpet_t1_cmp
> is 64-bit this condition will always be FALSE once the latter hits
> the 32-bit boundary, and we can have a situation, when we don't
> increase the HPET_T1_CMP register high enough.
> 
> The result - timer stops ticking, since HPET_T1_CMP becomes less, 
> than the COUNTER and never increased again.
> 
> The solution is to cut the upper 32-bit from the hpet_t1_cmp
> variable to make the comparison to HPET_COUNTER correct.

Why not to use u32 as a type for hpet_t1_cmp then?
--
wbr, Vitaly

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86: fix hpet timer reinit for x86_64
  2009-02-04 11:39 ` Vitaly Mayatskikh
@ 2009-02-04 11:43   ` Kirill Korotaev
  2009-02-04 11:51   ` Pavel Emelyanov
  1 sibling, 0 replies; 7+ messages in thread
From: Kirill Korotaev @ 2009-02-04 11:43 UTC (permalink / raw)
  To: Vitaly Mayatskikh, Pavel Emelyanov
  Cc: Thomas Gleixner, Linux Kernel Mailing List, Kirill Korotaev


On 2/4/09 2:39 PM, "Vitaly Mayatskikh" <v.mayatskih@gmail.com> wrote:

> At Wed, 04 Feb 2009 13:40:31 +0300, Pavel Emelyanov wrote:
>> 
>> There's a small problem with hpet_rtc_reinit function - it checks
>> for the
>>       hpet_readl(HPET_COUNTER) - hpet_t1_cmp > 0
>> to continue increasing both the HPET_T1_CMP (register) and the
>> hpet_t1_cmp (variable).
>> 
>> But since the HPET_COUNTER is always 32-bit, if the hpet_t1_cmp
>> is 64-bit this condition will always be FALSE once the latter hits
>> the 32-bit boundary, and we can have a situation, when we don't
>> increase the HPET_T1_CMP register high enough.
>> 
>> The result - timer stops ticking, since HPET_T1_CMP becomes less,
>> than the COUNTER and never increased again.
>> 
>> The solution is to cut the upper 32-bit from the hpet_t1_cmp
>> variable to make the comparison to HPET_COUNTER correct.
> 
> Why not to use u32 as a type for hpet_t1_cmp then?
> --
> wbr, Vitaly

Pavel, I agree, better please submit original fix
replacing unsigned long to unsigned int (or u32) in definition of
hpet_t1_cmp.

Thanks,
Kirill


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86: fix hpet timer reinit for x86_64
  2009-02-04 11:39 ` Vitaly Mayatskikh
  2009-02-04 11:43   ` Kirill Korotaev
@ 2009-02-04 11:51   ` Pavel Emelyanov
  1 sibling, 0 replies; 7+ messages in thread
From: Pavel Emelyanov @ 2009-02-04 11:51 UTC (permalink / raw)
  To: Vitaly Mayatskikh
  Cc: Thomas Gleixner, Linux Kernel Mailing List, Kirill Korotaev

Vitaly Mayatskikh wrote:
> At Wed, 04 Feb 2009 13:40:31 +0300, Pavel Emelyanov wrote:
>> There's a small problem with hpet_rtc_reinit function - it checks
>> for the
>> 	hpet_readl(HPET_COUNTER) - hpet_t1_cmp > 0
>> to continue increasing both the HPET_T1_CMP (register) and the 
>> hpet_t1_cmp (variable).
>>
>> But since the HPET_COUNTER is always 32-bit, if the hpet_t1_cmp
>> is 64-bit this condition will always be FALSE once the latter hits
>> the 32-bit boundary, and we can have a situation, when we don't
>> increase the HPET_T1_CMP register high enough.
>>
>> The result - timer stops ticking, since HPET_T1_CMP becomes less, 
>> than the COUNTER and never increased again.
>>
>> The solution is to cut the upper 32-bit from the hpet_t1_cmp
>> variable to make the comparison to HPET_COUNTER correct.
> 
> Why not to use u32 as a type for hpet_t1_cmp then?

That's the matter of taste from my POV, so I can re-send the patch
if x86 maintainers agree with your version.

> --
> wbr, Vitaly
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86: fix hpet timer reinit for x86_64
  2009-02-04 10:40 [PATCH] x86: fix hpet timer reinit for x86_64 Pavel Emelyanov
  2009-02-04 11:39 ` Vitaly Mayatskikh
@ 2009-02-04 13:49 ` Ingo Molnar
  2009-02-05  8:01   ` Kirill Korotaev
  1 sibling, 1 reply; 7+ messages in thread
From: Ingo Molnar @ 2009-02-04 13:49 UTC (permalink / raw)
  To: Pavel Emelyanov
  Cc: Thomas Gleixner, Linux Kernel Mailing List, Kirill Korotaev


* Pavel Emelyanov <xemul@openvz.org> wrote:

> There's a small problem with hpet_rtc_reinit function - it checks
> for the
> 	hpet_readl(HPET_COUNTER) - hpet_t1_cmp > 0
> to continue increasing both the HPET_T1_CMP (register) and the 
> hpet_t1_cmp (variable).
> 
> But since the HPET_COUNTER is always 32-bit, if the hpet_t1_cmp
> is 64-bit this condition will always be FALSE once the latter hits
> the 32-bit boundary, and we can have a situation, when we don't
> increase the HPET_T1_CMP register high enough.
> 
> The result - timer stops ticking, since HPET_T1_CMP becomes less, 
> than the COUNTER and never increased again.
> 
> The solution is to cut the upper 32-bit from the hpet_t1_cmp
> variable to make the comparison to HPET_COUNTER correct.
> 
> Reported-by: Kirill Korotaev <dev@openvz.org>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

applied to tip/timers/urgent, thanks Pavel!

I'm wondering, what symptoms were seen due to the bug? Did system time stop, 
or did it become erratic, or were there outright lockups?

	Ingo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86: fix hpet timer reinit for x86_64
  2009-02-04 13:49 ` Ingo Molnar
@ 2009-02-05  8:01   ` Kirill Korotaev
  2009-02-05 14:53     ` Ingo Molnar
  0 siblings, 1 reply; 7+ messages in thread
From: Kirill Korotaev @ 2009-02-05  8:01 UTC (permalink / raw)
  To: Ingo Molnar, Pavel Emelyanov
  Cc: Thomas Gleixner, Linux Kernel Mailing List, Kirill Korotaev




On 2/4/09 4:49 PM, "Ingo Molnar" <mingo@elte.hu> wrote:

> 
> 
> * Pavel Emelyanov <xemul@openvz.org> wrote:
> 
>> There's a small problem with hpet_rtc_reinit function - it checks
>> for the
>>       hpet_readl(HPET_COUNTER) - hpet_t1_cmp > 0
>> to continue increasing both the HPET_T1_CMP (register) and the
>> hpet_t1_cmp (variable).
>> 
>> But since the HPET_COUNTER is always 32-bit, if the hpet_t1_cmp
>> is 64-bit this condition will always be FALSE once the latter hits
>> the 32-bit boundary, and we can have a situation, when we don't
>> increase the HPET_T1_CMP register high enough.
>> 
>> The result - timer stops ticking, since HPET_T1_CMP becomes less,
>> than the COUNTER and never increased again.
>> 
>> The solution is to cut the upper 32-bit from the hpet_t1_cmp
>> variable to make the comparison to HPET_COUNTER correct.
>> 
>> Reported-by: Kirill Korotaev <dev@openvz.org>
>> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
> 
> applied to tip/timers/urgent, thanks Pavel!
> 
> I'm wondering, what symptoms were seen due to the bug? Did system time stop,
> or did it become erratic, or were there outright lockups?

Symptoms were observed in user space. An application doing read() on
/dev/rtc blocked sometimes for a long periods of time (as turned out - until
counter gets wrap around).

Regards,
Kirill


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86: fix hpet timer reinit for x86_64
  2009-02-05  8:01   ` Kirill Korotaev
@ 2009-02-05 14:53     ` Ingo Molnar
  0 siblings, 0 replies; 7+ messages in thread
From: Ingo Molnar @ 2009-02-05 14:53 UTC (permalink / raw)
  To: Kirill Korotaev
  Cc: Pavel Emelyanov, Thomas Gleixner, Linux Kernel Mailing List,
	Kirill Korotaev


* Kirill Korotaev <dev@parallels.com> wrote:

> On 2/4/09 4:49 PM, "Ingo Molnar" <mingo@elte.hu> wrote:
> 
> > 
> > 
> > * Pavel Emelyanov <xemul@openvz.org> wrote:
> > 
> >> There's a small problem with hpet_rtc_reinit function - it checks
> >> for the
> >>       hpet_readl(HPET_COUNTER) - hpet_t1_cmp > 0
> >> to continue increasing both the HPET_T1_CMP (register) and the
> >> hpet_t1_cmp (variable).
> >> 
> >> But since the HPET_COUNTER is always 32-bit, if the hpet_t1_cmp
> >> is 64-bit this condition will always be FALSE once the latter hits
> >> the 32-bit boundary, and we can have a situation, when we don't
> >> increase the HPET_T1_CMP register high enough.
> >> 
> >> The result - timer stops ticking, since HPET_T1_CMP becomes less,
> >> than the COUNTER and never increased again.
> >> 
> >> The solution is to cut the upper 32-bit from the hpet_t1_cmp
> >> variable to make the comparison to HPET_COUNTER correct.
> >> 
> >> Reported-by: Kirill Korotaev <dev@openvz.org>
> >> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
> > 
> > applied to tip/timers/urgent, thanks Pavel!
> > 
> > I'm wondering, what symptoms were seen due to the bug? Did system time stop,
> > or did it become erratic, or were there outright lockups?
> 
> Symptoms were observed in user space. An application doing read() on
> /dev/rtc blocked sometimes for a long periods of time (as turned out - until
> counter gets wrap around).

okay. Could you guys please put this info in the commit log on the 
resubmitted patch? Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-02-05 14:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-04 10:40 [PATCH] x86: fix hpet timer reinit for x86_64 Pavel Emelyanov
2009-02-04 11:39 ` Vitaly Mayatskikh
2009-02-04 11:43   ` Kirill Korotaev
2009-02-04 11:51   ` Pavel Emelyanov
2009-02-04 13:49 ` Ingo Molnar
2009-02-05  8:01   ` Kirill Korotaev
2009-02-05 14:53     ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox