aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ratelimit.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /lib/ratelimit.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'lib/ratelimit.c')
-rw-r--r--lib/ratelimit.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index 26187edcc7ea..027a03f4c56d 100644
--- a/lib/ratelimit.c
+++ b/lib/ratelimit.c
@@ -7,51 +7,61 @@
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
17static 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
19 * @func: name of calling function
20 *
21 * This enforces a rate limit: not more than @rs->burst callbacks
22 * in every @rs->interval
22 * 23 *
23 * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks 24 * RETURNS:
24 * in every @rs->ratelimit_jiffies 25 * 0 means callbacks will be suppressed.
26 * 1 means go ahead and do it.
25 */ 27 */
26int __ratelimit(struct ratelimit_state *rs) 28int ___ratelimit(struct ratelimit_state *rs, const char *func)
27{ 29{
28 unsigned long flags; 30 unsigned long flags;
31 int ret;
29 32
30 if (!rs->interval) 33 if (!rs->interval)
31 return 1; 34 return 1;
32 35
33 spin_lock_irqsave(&ratelimit_lock, flags); 36 /*
37 * If we contend on this state's lock then almost
38 * by definition we are too busy to print a message,
39 * in addition to the one that will be printed by
40 * the entity that is holding the lock already:
41 */
42 if (!spin_trylock_irqsave(&rs->lock, flags))
43 return 0;
44
34 if (!rs->begin) 45 if (!rs->begin)
35 rs->begin = jiffies; 46 rs->begin = jiffies;
36 47
37 if (time_is_before_jiffies(rs->begin + rs->interval)) { 48 if (time_is_before_jiffies(rs->begin + rs->interval)) {
38 if (rs->missed) 49 if (rs->missed)
39 printk(KERN_WARNING "%s: %d callbacks suppressed\n", 50 printk(KERN_WARNING "%s: %d callbacks suppressed\n",
40 __func__, rs->missed); 51 func, rs->missed);
41 rs->begin = 0; 52 rs->begin = 0;
42 rs->printed = 0; 53 rs->printed = 0;
43 rs->missed = 0; 54 rs->missed = 0;
44 } 55 }
45 if (rs->burst && rs->burst > rs->printed) 56 if (rs->burst && rs->burst > rs->printed) {
46 goto print; 57 rs->printed++;
47 58 ret = 1;
48 rs->missed++; 59 } else {
49 spin_unlock_irqrestore(&ratelimit_lock, flags); 60 rs->missed++;
50 return 0; 61 ret = 0;
62 }
63 spin_unlock_irqrestore(&rs->lock, flags);
51 64
52print: 65 return ret;
53 rs->printed++;
54 spin_unlock_irqrestore(&ratelimit_lock, flags);
55 return 1;
56} 66}
57EXPORT_SYMBOL(__ratelimit); 67EXPORT_SYMBOL(___ratelimit);