isolate ratelimit from printk.c for other use
authorDave Young <hidave.darkstar@gmail.com>
Tue, 29 Apr 2008 07:59:43 +0000 (00:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Apr 2008 15:06:06 +0000 (08:06 -0700)
Due to the rcupreempt.h WARN_ON trigged, I got 2G syslog file.  For some
serious complaining of kernel, we need repeat the warnings, so here I isolate
the ratelimit part of printk.c to a standalone file.

Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/kernel.h
kernel/printk.c
lib/Makefile
lib/ratelimit.c [new file with mode: 0644]

index 28caa53dd1f79803f173d4a7cb9088ce310bf70a..ad5d05efcd1af6a621817f9ac0b43a54738e75aa 100644 (file)
@@ -188,6 +188,7 @@ extern int log_buf_copy(char *dest, int idx, int len);
 extern int printk_ratelimit_jiffies;
 extern int printk_ratelimit_burst;
 extern int printk_ratelimit(void);
+extern int __ratelimit(int ratelimit_jiffies, int ratelimit_burst);
 extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst);
 extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
                                   unsigned int interval_msec);
index bdd4ea8c3f2b67520c1a55e0ba34a0a247d350fc..d3f9c0f788bff3def7e028adb61d3b4ca8de0303 100644 (file)
@@ -1287,31 +1287,7 @@ void tty_write_message(struct tty_struct *tty, char *msg)
  */
 int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
 {
-       static DEFINE_SPINLOCK(ratelimit_lock);
-       static unsigned toks = 10 * 5 * HZ;
-       static unsigned long last_msg;
-       static int missed;
-       unsigned long flags;
-       unsigned long now = jiffies;
-
-       spin_lock_irqsave(&ratelimit_lock, flags);
-       toks += now - last_msg;
-       last_msg = now;
-       if (toks > (ratelimit_burst * ratelimit_jiffies))
-               toks = ratelimit_burst * ratelimit_jiffies;
-       if (toks >= ratelimit_jiffies) {
-               int lost = missed;
-
-               missed = 0;
-               toks -= ratelimit_jiffies;
-               spin_unlock_irqrestore(&ratelimit_lock, flags);
-               if (lost)
-                       printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
-               return 1;
-       }
-       missed++;
-       spin_unlock_irqrestore(&ratelimit_lock, flags);
-       return 0;
+       return __ratelimit(ratelimit_jiffies, ratelimit_burst);
 }
 EXPORT_SYMBOL(__printk_ratelimit);
 
index 2d7001b7f5a4d641be0c618a6405d4c9863b41fb..0ae4eb047aac1b7a7dd662972442bccd16675f4f 100644 (file)
@@ -6,7 +6,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
         rbtree.o radix-tree.o dump_stack.o \
         idr.o int_sqrt.o extable.o prio_tree.o \
         sha1.o irq_regs.o reciprocal_div.o argv_split.o \
-        proportions.o prio_heap.o
+        proportions.o prio_heap.o ratelimit.o
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
new file mode 100644 (file)
index 0000000..485e304
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * ratelimit.c - Do something with rate limit.
+ *
+ * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com>
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+
+/*
+ * __ratelimit - rate limiting
+ * @ratelimit_jiffies: minimum time in jiffies between two callbacks
+ * @ratelimit_burst: number of callbacks we do before ratelimiting
+ *
+ * This enforces a rate limit: not more than @ratelimit_burst callbacks
+ * in every ratelimit_jiffies
+ */
+int __ratelimit(int ratelimit_jiffies, int ratelimit_burst)
+{
+       static DEFINE_SPINLOCK(ratelimit_lock);
+       static unsigned toks = 10 * 5 * HZ;
+       static unsigned long last_msg;
+       static int missed;
+       unsigned long flags;
+       unsigned long now = jiffies;
+
+       spin_lock_irqsave(&ratelimit_lock, flags);
+       toks += now - last_msg;
+       last_msg = now;
+       if (toks > (ratelimit_burst * ratelimit_jiffies))
+               toks = ratelimit_burst * ratelimit_jiffies;
+       if (toks >= ratelimit_jiffies) {
+               int lost = missed;
+
+               missed = 0;
+               toks -= ratelimit_jiffies;
+               spin_unlock_irqrestore(&ratelimit_lock, flags);
+               if (lost)
+                       printk(KERN_WARNING "%s: %d messages suppressed\n",
+                               __func__, lost);
+               return 1;
+       }
+       missed++;
+       spin_unlock_irqrestore(&ratelimit_lock, flags);
+       return 0;
+}
+EXPORT_SYMBOL(__ratelimit);