Skip to content
  • Thomas Gleixner's avatar
    x86: Derandom delay_tsc for 64 bit · a7f4255f
    Thomas Gleixner authored
    Commit f0fbf0ab
    
     ("x86: integrate delay functions") converted
    delay_tsc() into a random delay generator for 64 bit.  The reason is
    that it merged the mostly identical versions of delay_32.c and
    delay_64.c.  Though the subtle difference of the result was:
    
     static void delay_tsc(unsigned long loops)
     {
    -	unsigned bclock, now;
    +	unsigned long bclock, now;
    
    Now the function uses rdtscl() which returns the lower 32bit of the
    TSC. On 32bit that's not problematic as unsigned long is 32bit. On 64
    bit this fails when the lower 32bit are close to wrap around when
    bclock is read, because the following check
    
           if ((now - bclock) >= loops)
           	  	break;
    
    evaluated to true on 64bit for e.g. bclock = 0xffffffff and now = 0
    because the unsigned long (now - bclock) of these values results in
    0xffffffff00000001 which is definitely larger than the loops
    value. That explains Tvortkos observation:
    
    "Because I am seeing udelay(500) (_occasionally_) being short, and
     that by delaying for some duration between 0us (yep) and 491us."
    
    Make those variables explicitely u32 again, so this works for both 32
    and 64 bit.
    
    Reported-by: default avatarTvrtko Ursulin <tvrtko.ursulin@onelan.co.uk>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: stable@vger.kernel.org # >= 2.6.27
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    a7f4255f