[PATCH] Add printk_timed_ratelimit()
Andrew Morton [Fri, 3 Nov 2006 06:07:16 +0000 (22:07 -0800)]
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>

include/linux/kernel.h
kernel/printk.c

index 80f39ca..24b6111 100644 (file)
@@ -171,6 +171,8 @@ __attribute_const__ roundup_pow_of_two(unsigned long x)
 
 extern int printk_ratelimit(void);
 extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst);
+extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
+                               unsigned int interval_msec);
 
 static inline void console_silent(void)
 {
index f7d427e..6642655 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/security.h>
 #include <linux/bootmem.h>
 #include <linux/syscalls.h>
+#include <linux/jiffies.h>
 
 #include <asm/uaccess.h>
 
@@ -1101,3 +1102,23 @@ int printk_ratelimit(void)
                                printk_ratelimit_burst);
 }
 EXPORT_SYMBOL(printk_ratelimit);
+
+/**
+ * printk_timed_ratelimit - caller-controlled printk ratelimiting
+ * @caller_jiffies: pointer to caller's state
+ * @interval_msecs: minimum interval between prints
+ *
+ * printk_timed_ratelimit() returns true if more than @interval_msecs
+ * milliseconds have elapsed since the last time printk_timed_ratelimit()
+ * returned true.
+ */
+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;
+}
+EXPORT_SYMBOL(printk_timed_ratelimit);