Messages in this thread Patch in this message |  | | | Date | Fri, 7 Dec 2007 13:11:07 +0100 | | From | Ingo Molnar <> | | Subject | Re: [PATCH] scheduler: fix x86 regression in native_sched_clock |
| |
* stefano.brivio@polimi.it <stefano.brivio@polimi.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@elte.hu> use cpu_clock() for TSC based udelay - it's more reliable than raw TSC based delay loops.
Signed-off-by: Ingo Molnar <mingo@elte.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)
|  |