[PATCH] Add printk_timed_ratelimit()

printk_ratelimit() has global state which makes it not useful for callers
which wish to perform ratelimiting at a particular frequency.

Add a printk_timed_ratelimit() which utilises caller-provided state storage to
permit more flexibility.

This function can in fact be used for things other than printk ratelimiting
and is perhaps poorly named.

Cc: Ulrich Drepper <drepper@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Andrew Morton and committed by Linus Torvalds f46c4833 7f6b8876

+23
+2
include/linux/kernel.h
··· 171 171 172 172 extern int printk_ratelimit(void); 173 173 extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst); 174 + extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, 175 + unsigned int interval_msec); 174 176 175 177 static inline void console_silent(void) 176 178 {
+21
kernel/printk.c
··· 31 31 #include <linux/security.h> 32 32 #include <linux/bootmem.h> 33 33 #include <linux/syscalls.h> 34 + #include <linux/jiffies.h> 34 35 35 36 #include <asm/uaccess.h> 36 37 ··· 1102 1101 printk_ratelimit_burst); 1103 1102 } 1104 1103 EXPORT_SYMBOL(printk_ratelimit); 1104 + 1105 + /** 1106 + * printk_timed_ratelimit - caller-controlled printk ratelimiting 1107 + * @caller_jiffies: pointer to caller's state 1108 + * @interval_msecs: minimum interval between prints 1109 + * 1110 + * printk_timed_ratelimit() returns true if more than @interval_msecs 1111 + * milliseconds have elapsed since the last time printk_timed_ratelimit() 1112 + * returned true. 1113 + */ 1114 + bool printk_timed_ratelimit(unsigned long *caller_jiffies, 1115 + unsigned int interval_msecs) 1116 + { 1117 + if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) { 1118 + *caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs); 1119 + return true; 1120 + } 1121 + return false; 1122 + } 1123 + EXPORT_SYMBOL(printk_timed_ratelimit);