2008-03-10 06:25:38

by Dave Young

[permalink] [raw]
Subject: [PATCH RFC] [1/3] isolate ratelimit from printk.c for other use

This series include 3 patch, they need to be applied in order.
1) isolate ratelimit from printk.c
2) add WARN_ON_SECS macro
3) use WARN_ON_SECS macro in rcupreempt.h

Please give some comments and suggestions for improvement, thanks.

---

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 <[email protected]>

---
include/linux/kernel.h | 1
kernel/printk.c | 26 ------------------------
lib/Makefile | 2 -
lib/ratelimit.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 54 insertions(+), 26 deletions(-)

diff -uprN linux/include/linux/kernel.h linux.new/include/linux/kernel.h
--- linux/include/linux/kernel.h 2008-03-10 13:41:18.000000000 +0800
+++ linux.new/include/linux/kernel.h 2008-03-10 13:42:06.000000000 +0800
@@ -188,6 +188,7 @@ extern int log_buf_copy(char *dest, int
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);
diff -uprN linux/kernel/printk.c linux.new/kernel/printk.c
--- linux/kernel/printk.c 2008-03-10 13:41:37.000000000 +0800
+++ linux.new/kernel/printk.c 2008-03-10 13:42:19.000000000 +0800
@@ -1261,31 +1261,7 @@ void tty_write_message(struct tty_struct
*/
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);

diff -uprN linux/lib/Makefile linux.new/lib/Makefile
--- linux/lib/Makefile 2008-03-10 13:43:57.000000000 +0800
+++ linux.new/lib/Makefile 2008-03-10 13:42:38.000000000 +0800
@@ -6,7 +6,7 @@ lib-y := ctype.o string.o vsprintf.o cmd
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 -uprN linux/lib/ratelimit.c linux.new/lib/ratelimit.c
--- linux/lib/ratelimit.c 1970-01-01 07:00:00.000000000 +0700
+++ linux.new/lib/ratelimit.c 2008-03-10 13:42:46.000000000 +0800
@@ -0,0 +1,51 @@
+/*
+ * ratelimit.c - Do something with rate limit.
+ *
+ * Isolated from kernel/printk.c by Dave Young <[email protected]>
+ *
+ * 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 too 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 "__ratelimit: %d messages"
+ " suppressed.\n", lost);
+ return 1;
+ }
+ missed++;
+ spin_unlock_irqrestore(&ratelimit_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(__ratelimit);


2008-03-10 16:10:35

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH RFC] [1/3] isolate ratelimit from printk.c for other use

On Mon, 10 Mar 2008 14:31:15 +0800 Dave Young wrote:

> This series include 3 patch, they need to be applied in order.
> 1) isolate ratelimit from printk.c
> 2) add WARN_ON_SECS macro
> 3) use WARN_ON_SECS macro in rcupreempt.h
>
> Please give some comments and suggestions for improvement, thanks.
>
> ---
>
> 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 <[email protected]>
>
> ---
> include/linux/kernel.h | 1
> kernel/printk.c | 26 ------------------------
> lib/Makefile | 2 -
> lib/ratelimit.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 54 insertions(+), 26 deletions(-)

> diff -uprN linux/lib/ratelimit.c linux.new/lib/ratelimit.c
> --- linux/lib/ratelimit.c 1970-01-01 07:00:00.000000000 +0700
> +++ linux.new/lib/ratelimit.c 2008-03-10 13:42:46.000000000 +0800
> @@ -0,0 +1,51 @@
> +/*
> + * ratelimit.c - Do something with rate limit.
> + *
> + * Isolated from kernel/printk.c by Dave Young <[email protected]>
> + *
> + * 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 too callbacks

s/too/two/

> + * @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 "__ratelimit: %d messages"
> + " suppressed.\n", lost);

Would be better not to split the string, e.g.:

printk(KERN_WARNING "%s: %d messages suppressed\n",
__func__, lost);

> + return 1;
> + }
> + missed++;
> + spin_unlock_irqrestore(&ratelimit_lock, flags);
> + return 0;
> +}
> +EXPORT_SYMBOL(__ratelimit);

---
~Randy

2008-03-10 19:06:07

by Paul E. McKenney

[permalink] [raw]
Subject: Re: [PATCH RFC] [1/3] isolate ratelimit from printk.c for other use

On Mon, Mar 10, 2008 at 02:31:15PM +0800, Dave Young wrote:
> This series include 3 patch, they need to be applied in order.
> 1) isolate ratelimit from printk.c
> 2) add WARN_ON_SECS macro
> 3) use WARN_ON_SECS macro in rcupreempt.h
>
> Please give some comments and suggestions for improvement, thanks.

Works for me -- high-rate warnings are limited to one per ten seconds,
with 10s of thousands of suppressed messages, as expected. It would
of course be good to fix the typo called out by Randy.

Acked-by: Paul E. McKenney <[email protected]>
Tested-by: Paul E. McKenney <[email protected]>

> ---
>
> 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 <[email protected]>
>
> ---
> include/linux/kernel.h | 1
> kernel/printk.c | 26 ------------------------
> lib/Makefile | 2 -
> lib/ratelimit.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 54 insertions(+), 26 deletions(-)
>
> diff -uprN linux/include/linux/kernel.h linux.new/include/linux/kernel.h
> --- linux/include/linux/kernel.h 2008-03-10 13:41:18.000000000 +0800
> +++ linux.new/include/linux/kernel.h 2008-03-10 13:42:06.000000000 +0800
> @@ -188,6 +188,7 @@ extern int log_buf_copy(char *dest, int
> 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);
> diff -uprN linux/kernel/printk.c linux.new/kernel/printk.c
> --- linux/kernel/printk.c 2008-03-10 13:41:37.000000000 +0800
> +++ linux.new/kernel/printk.c 2008-03-10 13:42:19.000000000 +0800
> @@ -1261,31 +1261,7 @@ void tty_write_message(struct tty_struct
> */
> 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);
>
> diff -uprN linux/lib/Makefile linux.new/lib/Makefile
> --- linux/lib/Makefile 2008-03-10 13:43:57.000000000 +0800
> +++ linux.new/lib/Makefile 2008-03-10 13:42:38.000000000 +0800
> @@ -6,7 +6,7 @@ lib-y := ctype.o string.o vsprintf.o cmd
> 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 -uprN linux/lib/ratelimit.c linux.new/lib/ratelimit.c
> --- linux/lib/ratelimit.c 1970-01-01 07:00:00.000000000 +0700
> +++ linux.new/lib/ratelimit.c 2008-03-10 13:42:46.000000000 +0800
> @@ -0,0 +1,51 @@
> +/*
> + * ratelimit.c - Do something with rate limit.
> + *
> + * Isolated from kernel/printk.c by Dave Young <[email protected]>
> + *
> + * 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 too 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 "__ratelimit: %d messages"
> + " suppressed.\n", lost);
> + return 1;
> + }
> + missed++;
> + spin_unlock_irqrestore(&ratelimit_lock, flags);
> + return 0;
> +}
> +EXPORT_SYMBOL(__ratelimit);

2008-03-11 01:10:27

by Dave Young

[permalink] [raw]
Subject: Re: [PATCH RFC] [1/3] isolate ratelimit from printk.c for other use

On Mon, Mar 10, 2008 at 08:51:32AM -0700, Randy Dunlap wrote:
[snip]
> > +/*
> > + * __ratelimit - rate limiting
> > + * @ratelimit_jiffies: minimum time in jiffies between too callbacks
>
> s/too/two/

will fix

[snip]
> > + if (lost)
> > + printk(KERN_WARNING "__ratelimit: %d messages"
> > + " suppressed.\n", lost);
>
> Would be better not to split the string, e.g.:
>
> printk(KERN_WARNING "%s: %d messages suppressed\n",
> __func__, lost);
>

Yes, it's better to use __func__

Thanks randy.

Andrew, Could you use the following update? I don't want to bother you,
but...

Thanks.
---

Signed-off-by: Dave Young <[email protected]>

---
include/linux/kernel.h | 1
kernel/printk.c | 26 ------------------------
lib/Makefile | 2 -
lib/ratelimit.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 54 insertions(+), 26 deletions(-)

diff -uprN linux/include/linux/kernel.h linux.new/include/linux/kernel.h
--- linux/include/linux/kernel.h 2008-03-10 13:41:18.000000000 +0800
+++ linux.new/include/linux/kernel.h 2008-03-10 13:42:06.000000000 +0800
@@ -188,6 +188,7 @@ extern int log_buf_copy(char *dest, int
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);
diff -uprN linux/kernel/printk.c linux.new/kernel/printk.c
--- linux/kernel/printk.c 2008-03-10 13:41:37.000000000 +0800
+++ linux.new/kernel/printk.c 2008-03-10 13:42:19.000000000 +0800
@@ -1261,31 +1261,7 @@ void tty_write_message(struct tty_struct
*/
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);

diff -uprN linux/lib/Makefile linux.new/lib/Makefile
--- linux/lib/Makefile 2008-03-10 13:43:57.000000000 +0800
+++ linux.new/lib/Makefile 2008-03-10 13:42:38.000000000 +0800
@@ -6,7 +6,7 @@ lib-y := ctype.o string.o vsprintf.o cmd
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 -uprN linux/lib/ratelimit.c linux.new/lib/ratelimit.c
--- linux/lib/ratelimit.c 1970-01-01 07:00:00.000000000 +0700
+++ linux.new/lib/ratelimit.c 2008-03-11 09:02:03.000000000 +0800
@@ -0,0 +1,51 @@
+/*
+ * ratelimit.c - Do something with rate limit.
+ *
+ * Isolated from kernel/printk.c by Dave Young <[email protected]>
+ *
+ * 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);