• G
    printk: correct the behavior of printk_timed_ratelimit() · f2d28a2e
    Guillaume Knispel 提交于
    Impact: fix jiffies-comparison sign-wrap behavior
    
    The behavior provided by printk_timed_ratelimit() is, in some
    situations, probably not what a caller would reasonably expect:
    
    bool printk_timed_ratelimit(unsigned long *caller_jiffies,
    			unsigned int interval_msecs)
    {
    	if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) {
    		*caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs);
    		return true;
    	}
    	return false;
    }
    
    On a 32 bit computer, if printk_timed_ratelimit() is initially called at
    time jiffies == Ja, *caller_jiffies is set to
    Ja + msecs_to_jiffies(interval_msecs): let's say Ja + 42 for this
    example.
    
    If this caller then doesn't call printk_timed_ratelimit() until
    jiffies == Ja + (1 << 31) + 42 (which can happen as soon as ~ 25 days
    later on a 1000 HZ system), printk_timed_ratelimit() will then always
    return false to this caller until jiffies loops completely (1 << 31 more
    ticks).
    
    Ths change makes it only return false if jiffies is in the small
    time window starting at the previous call when true was returned and
    ending interval_msecs later.  Note that if jiffies loops completely
    between two calls to printk_timed_ratelimit(), it will obviously still
    wrongly return false, but this is something with a low probability.
    
    If something completely reliable is needed I guess jiffies_64 must be
    used (which this change does not do).
    Signed-off-by: NGuillaume Knispel <gknispel@proformatique.com>
    Cc: Ulrich Drepper <drepper@redhat.com>
    Cc: Rusty Russell <rusty@rustcorp.com.au>
    Cc: Andrew Morton <akpm@osdl.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    LKML-Reference: <20090317161842.0059096b@xilun.lan.proformatique.com>
    Signed-off-by: NIngo Molnar <mingo@elte.hu>
    f2d28a2e
printk.c 31.9 KB