[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20071207121107.GA21049@elte.hu>
Date: Fri, 7 Dec 2007 13:11:07 +0100
From: Ingo Molnar <mingo@...e.hu>
To: stefano.brivio@...imi.it
Cc: Nick Piggin <nickpiggin@...oo.com.au>, Robert Love <rml@...h9.net>,
linux-kernel@...r.kernel.org, Dave Jones <davej@...hat.com>,
"Rafael J. Wysocki" <rjw@...k.pl>, Michael Buesch <mb@...sch.de>,
Thomas Gleixner <tglx@...utronix.de>,
Andrew Morton <akpm@...ux-foundation.org>,
Len Brown <lenb@...nel.org>
Subject: Re: [PATCH] scheduler: fix x86 regression in native_sched_clock
* stefano.brivio@...imi.it <stefano.brivio@...imi.it> wrote:
>> It's a single CPU box, so sched_clock() jumping would still be
>> problematic, no?
>
> I guess so. Definitely, it didn't look like a printk issue. Drivers
> don't read logs, usually. But they got confused anyway (it seems that
> udelay's get scaled or fail or somesuch - I can't test it right now,
> will provide more feedback in a few hours).
no, i think it's just another aspect of the broken TSC on that hardware.
Does the patch below improve things?
Ingo
------------------->
Subject: x86: cpu_clock() based udelay
From: Ingo Molnar <mingo@...e.hu>
use cpu_clock() for TSC based udelay - it's more reliable than raw
TSC based delay loops.
Signed-off-by: Ingo Molnar <mingo@...e.hu>
---
arch/x86/lib/delay_32.c | 20 ++++++++++++--------
arch/x86/lib/delay_64.c | 27 ++++++++++++++++++---------
2 files changed, 30 insertions(+), 17 deletions(-)
Index: linux/arch/x86/lib/delay_32.c
===================================================================
--- linux.orig/arch/x86/lib/delay_32.c
+++ linux/arch/x86/lib/delay_32.c
@@ -38,17 +38,21 @@ static void delay_loop(unsigned long loo
:"0" (loops));
}
-/* TSC based delay: */
+/* cpu_clock() [TSC] based delay: */
static void delay_tsc(unsigned long loops)
{
- unsigned long bclock, now;
+ unsigned long long start, stop, now;
+ int this_cpu;
+
+ preempt_disable();
+
+ this_cpu = smp_processor_id();
+ start = now = cpu_clock(this_cpu);
+ stop = start + loops;
+
+ while ((long long)(stop - now) > 0)
+ now = cpu_clock(this_cpu);
- preempt_disable(); /* TSC's are per-cpu */
- rdtscl(bclock);
- do {
- rep_nop();
- rdtscl(now);
- } while ((now-bclock) < loops);
preempt_enable();
}
Index: linux/arch/x86/lib/delay_64.c
===================================================================
--- linux.orig/arch/x86/lib/delay_64.c
+++ linux/arch/x86/lib/delay_64.c
@@ -26,19 +26,28 @@ int read_current_timer(unsigned long *ti
return 0;
}
-void __delay(unsigned long loops)
+/* cpu_clock() [TSC] based delay: */
+static void delay_tsc(unsigned long loops)
{
- unsigned bclock, now;
+ unsigned long long start, stop, now;
+ int this_cpu;
+
+ preempt_disable();
+
+ this_cpu = smp_processor_id();
+ start = now = cpu_clock(this_cpu);
+ stop = start + loops;
+
+ while ((long long)(stop - now) > 0)
+ now = cpu_clock(this_cpu);
- preempt_disable(); /* TSC's are pre-cpu */
- rdtscl(bclock);
- do {
- rep_nop();
- rdtscl(now);
- }
- while ((now-bclock) < loops);
preempt_enable();
}
+
+void __delay(unsigned long loops)
+{
+ delay_tsc(loops);
+}
EXPORT_SYMBOL(__delay);
inline void __const_udelay(unsigned long xloops)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists