lkml.org 
[lkml]   [2007]   [Dec]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [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)

    \
     
     \ /
      Last update: 2007-12-07 13:15    [W:0.050 / U:121.544 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site