diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-05 12:50:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-05 12:50:22 -0500 |
commit | d0b093a8b5ae34ee8be1f7e0dd197fe4788fa1d5 (patch) | |
tree | deaed4192d440b6afb7470b0c36e69d9d65dd119 | |
parent | 3e72b810e30cdf4655279dd767eb798ac7a8fe5e (diff) | |
parent | 5c828713358cb9df8aa174371edcbbb62203a490 (diff) |
Merge branch 'core-printk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-printk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
ratelimit: Make suppressed output messages more useful
printk: Remove ratelimit.h from kernel.h
ratelimit: Fix/allow use in atomic contexts
ratelimit: Use per ratelimit context locking
-rw-r--r-- | include/linux/kernel.h | 5 | ||||
-rw-r--r-- | include/linux/net.h | 1 | ||||
-rw-r--r-- | include/linux/ratelimit.h | 33 | ||||
-rw-r--r-- | kernel/printk.c | 7 | ||||
-rw-r--r-- | kernel/sysctl.c | 3 | ||||
-rw-r--r-- | lib/ratelimit.c | 45 | ||||
-rw-r--r-- | net/core/sysctl_net_core.c | 2 | ||||
-rw-r--r-- | net/core/utils.c | 2 |
8 files changed, 61 insertions, 37 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index f4e3184fa054..3fa4c590cf12 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
16 | #include <linux/log2.h> | 16 | #include <linux/log2.h> |
17 | #include <linux/typecheck.h> | 17 | #include <linux/typecheck.h> |
18 | #include <linux/ratelimit.h> | ||
19 | #include <linux/dynamic_debug.h> | 18 | #include <linux/dynamic_debug.h> |
20 | #include <asm/byteorder.h> | 19 | #include <asm/byteorder.h> |
21 | #include <asm/bug.h> | 20 | #include <asm/bug.h> |
@@ -241,8 +240,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
241 | asmlinkage int printk(const char * fmt, ...) | 240 | asmlinkage int printk(const char * fmt, ...) |
242 | __attribute__ ((format (printf, 1, 2))) __cold; | 241 | __attribute__ ((format (printf, 1, 2))) __cold; |
243 | 242 | ||
244 | extern struct ratelimit_state printk_ratelimit_state; | 243 | extern int __printk_ratelimit(const char *func); |
245 | extern int printk_ratelimit(void); | 244 | #define printk_ratelimit() __printk_ratelimit(__func__) |
246 | extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, | 245 | extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, |
247 | unsigned int interval_msec); | 246 | unsigned int interval_msec); |
248 | 247 | ||
diff --git a/include/linux/net.h b/include/linux/net.h index 529a0931711d..d7e26e30c8c2 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -358,6 +358,7 @@ static const struct proto_ops name##_ops = { \ | |||
358 | 358 | ||
359 | #ifdef CONFIG_SYSCTL | 359 | #ifdef CONFIG_SYSCTL |
360 | #include <linux/sysctl.h> | 360 | #include <linux/sysctl.h> |
361 | #include <linux/ratelimit.h> | ||
361 | extern struct ratelimit_state net_ratelimit_state; | 362 | extern struct ratelimit_state net_ratelimit_state; |
362 | #endif | 363 | #endif |
363 | 364 | ||
diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h index 00044b856453..668cf1bef030 100644 --- a/include/linux/ratelimit.h +++ b/include/linux/ratelimit.h | |||
@@ -1,20 +1,31 @@ | |||
1 | #ifndef _LINUX_RATELIMIT_H | 1 | #ifndef _LINUX_RATELIMIT_H |
2 | #define _LINUX_RATELIMIT_H | 2 | #define _LINUX_RATELIMIT_H |
3 | |||
3 | #include <linux/param.h> | 4 | #include <linux/param.h> |
5 | #include <linux/spinlock_types.h> | ||
4 | 6 | ||
5 | #define DEFAULT_RATELIMIT_INTERVAL (5 * HZ) | 7 | #define DEFAULT_RATELIMIT_INTERVAL (5 * HZ) |
6 | #define DEFAULT_RATELIMIT_BURST 10 | 8 | #define DEFAULT_RATELIMIT_BURST 10 |
7 | 9 | ||
8 | struct ratelimit_state { | 10 | struct ratelimit_state { |
9 | int interval; | 11 | spinlock_t lock; /* protect the state */ |
10 | int burst; | 12 | |
11 | int printed; | 13 | int interval; |
12 | int missed; | 14 | int burst; |
13 | unsigned long begin; | 15 | int printed; |
16 | int missed; | ||
17 | unsigned long begin; | ||
14 | }; | 18 | }; |
15 | 19 | ||
16 | #define DEFINE_RATELIMIT_STATE(name, interval, burst) \ | 20 | #define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \ |
17 | struct ratelimit_state name = {interval, burst,} | 21 | \ |
22 | struct ratelimit_state name = { \ | ||
23 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ | ||
24 | .interval = interval_init, \ | ||
25 | .burst = burst_init, \ | ||
26 | } | ||
27 | |||
28 | extern int ___ratelimit(struct ratelimit_state *rs, const char *func); | ||
29 | #define __ratelimit(state) ___ratelimit(state, __func__) | ||
18 | 30 | ||
19 | extern int __ratelimit(struct ratelimit_state *rs); | 31 | #endif /* _LINUX_RATELIMIT_H */ |
20 | #endif | ||
diff --git a/kernel/printk.c b/kernel/printk.c index f38b07f78a4e..b5ac4d99c667 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
34 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
35 | #include <linux/kexec.h> | 35 | #include <linux/kexec.h> |
36 | #include <linux/ratelimit.h> | ||
36 | 37 | ||
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | 39 | ||
@@ -1376,11 +1377,11 @@ late_initcall(disable_boot_consoles); | |||
1376 | */ | 1377 | */ |
1377 | DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10); | 1378 | DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10); |
1378 | 1379 | ||
1379 | int printk_ratelimit(void) | 1380 | int __printk_ratelimit(const char *func) |
1380 | { | 1381 | { |
1381 | return __ratelimit(&printk_ratelimit_state); | 1382 | return ___ratelimit(&printk_ratelimit_state, func); |
1382 | } | 1383 | } |
1383 | EXPORT_SYMBOL(printk_ratelimit); | 1384 | EXPORT_SYMBOL(__printk_ratelimit); |
1384 | 1385 | ||
1385 | /** | 1386 | /** |
1386 | * printk_timed_ratelimit - caller-controlled printk ratelimiting | 1387 | * printk_timed_ratelimit - caller-controlled printk ratelimiting |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 0d949c517412..4dbf93a52ee9 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/sysrq.h> | 36 | #include <linux/sysrq.h> |
37 | #include <linux/highuid.h> | 37 | #include <linux/highuid.h> |
38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
39 | #include <linux/ratelimit.h> | ||
39 | #include <linux/hugetlb.h> | 40 | #include <linux/hugetlb.h> |
40 | #include <linux/initrd.h> | 41 | #include <linux/initrd.h> |
41 | #include <linux/key.h> | 42 | #include <linux/key.h> |
@@ -158,6 +159,8 @@ extern int no_unaligned_warning; | |||
158 | extern int unaligned_dump_stack; | 159 | extern int unaligned_dump_stack; |
159 | #endif | 160 | #endif |
160 | 161 | ||
162 | extern struct ratelimit_state printk_ratelimit_state; | ||
163 | |||
161 | #ifdef CONFIG_RT_MUTEXES | 164 | #ifdef CONFIG_RT_MUTEXES |
162 | extern int max_lock_depth; | 165 | extern int max_lock_depth; |
163 | #endif | 166 | #endif |
diff --git a/lib/ratelimit.c b/lib/ratelimit.c index 26187edcc7ea..09f5ce1810dc 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c | |||
@@ -7,15 +7,12 @@ | |||
7 | * parameter. Now every user can use their own standalone ratelimit_state. | 7 | * parameter. Now every user can use their own standalone ratelimit_state. |
8 | * | 8 | * |
9 | * This file is released under the GPLv2. | 9 | * This file is released under the GPLv2. |
10 | * | ||
11 | */ | 10 | */ |
12 | 11 | ||
13 | #include <linux/kernel.h> | 12 | #include <linux/ratelimit.h> |
14 | #include <linux/jiffies.h> | 13 | #include <linux/jiffies.h> |
15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
16 | 15 | ||
17 | static DEFINE_SPINLOCK(ratelimit_lock); | ||
18 | |||
19 | /* | 16 | /* |
20 | * __ratelimit - rate limiting | 17 | * __ratelimit - rate limiting |
21 | * @rs: ratelimit_state data | 18 | * @rs: ratelimit_state data |
@@ -23,35 +20,43 @@ static DEFINE_SPINLOCK(ratelimit_lock); | |||
23 | * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks | 20 | * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks |
24 | * in every @rs->ratelimit_jiffies | 21 | * in every @rs->ratelimit_jiffies |
25 | */ | 22 | */ |
26 | int __ratelimit(struct ratelimit_state *rs) | 23 | int ___ratelimit(struct ratelimit_state *rs, const char *func) |
27 | { | 24 | { |
28 | unsigned long flags; | 25 | unsigned long flags; |
26 | int ret; | ||
29 | 27 | ||
30 | if (!rs->interval) | 28 | if (!rs->interval) |
31 | return 1; | 29 | return 1; |
32 | 30 | ||
33 | spin_lock_irqsave(&ratelimit_lock, flags); | 31 | /* |
32 | * If we contend on this state's lock then almost | ||
33 | * by definition we are too busy to print a message, | ||
34 | * in addition to the one that will be printed by | ||
35 | * the entity that is holding the lock already: | ||
36 | */ | ||
37 | if (!spin_trylock_irqsave(&rs->lock, flags)) | ||
38 | return 1; | ||
39 | |||
34 | if (!rs->begin) | 40 | if (!rs->begin) |
35 | rs->begin = jiffies; | 41 | rs->begin = jiffies; |
36 | 42 | ||
37 | if (time_is_before_jiffies(rs->begin + rs->interval)) { | 43 | if (time_is_before_jiffies(rs->begin + rs->interval)) { |
38 | if (rs->missed) | 44 | if (rs->missed) |
39 | printk(KERN_WARNING "%s: %d callbacks suppressed\n", | 45 | printk(KERN_WARNING "%s: %d callbacks suppressed\n", |
40 | __func__, rs->missed); | 46 | func, rs->missed); |
41 | rs->begin = 0; | 47 | rs->begin = 0; |
42 | rs->printed = 0; | 48 | rs->printed = 0; |
43 | rs->missed = 0; | 49 | rs->missed = 0; |
44 | } | 50 | } |
45 | if (rs->burst && rs->burst > rs->printed) | 51 | if (rs->burst && rs->burst > rs->printed) { |
46 | goto print; | 52 | rs->printed++; |
47 | 53 | ret = 1; | |
48 | rs->missed++; | 54 | } else { |
49 | spin_unlock_irqrestore(&ratelimit_lock, flags); | 55 | rs->missed++; |
50 | return 0; | 56 | ret = 0; |
57 | } | ||
58 | spin_unlock_irqrestore(&rs->lock, flags); | ||
51 | 59 | ||
52 | print: | 60 | return ret; |
53 | rs->printed++; | ||
54 | spin_unlock_irqrestore(&ratelimit_lock, flags); | ||
55 | return 1; | ||
56 | } | 61 | } |
57 | EXPORT_SYMBOL(__ratelimit); | 62 | EXPORT_SYMBOL(___ratelimit); |
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 7db1de0497c6..887c03c4e3c6 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
@@ -10,7 +10,9 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/socket.h> | 11 | #include <linux/socket.h> |
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <linux/ratelimit.h> | ||
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | |||
14 | #include <net/ip.h> | 16 | #include <net/ip.h> |
15 | #include <net/sock.h> | 17 | #include <net/sock.h> |
16 | 18 | ||
diff --git a/net/core/utils.c b/net/core/utils.c index 83221aee7084..838250241d26 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/percpu.h> | 25 | #include <linux/percpu.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/ratelimit.h> | ||
28 | |||
27 | #include <net/sock.h> | 29 | #include <net/sock.h> |
28 | 30 | ||
29 | #include <asm/byteorder.h> | 31 | #include <asm/byteorder.h> |