aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ratelimit.h30
-rw-r--r--lib/ratelimit.c29
2 files changed, 33 insertions, 26 deletions
diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h
index 00044b856453..187bc16c1f15 100644
--- a/include/linux/ratelimit.h
+++ b/include/linux/ratelimit.h
@@ -1,20 +1,30 @@
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
8struct ratelimit_state { 10struct 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 }
18 27
19extern int __ratelimit(struct ratelimit_state *rs); 28extern int __ratelimit(struct ratelimit_state *rs);
20#endif 29
30#endif /* _LINUX_RATELIMIT_H */
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index 26187edcc7ea..0e2c28e8a0ca 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/kernel.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
@@ -26,11 +23,12 @@ static DEFINE_SPINLOCK(ratelimit_lock);
26int __ratelimit(struct ratelimit_state *rs) 23int __ratelimit(struct ratelimit_state *rs)
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 spin_lock_irqsave(&rs->lock, flags);
34 if (!rs->begin) 32 if (!rs->begin)
35 rs->begin = jiffies; 33 rs->begin = jiffies;
36 34
@@ -38,20 +36,19 @@ int __ratelimit(struct ratelimit_state *rs)
38 if (rs->missed) 36 if (rs->missed)
39 printk(KERN_WARNING "%s: %d callbacks suppressed\n", 37 printk(KERN_WARNING "%s: %d callbacks suppressed\n",
40 __func__, rs->missed); 38 __func__, rs->missed);
41 rs->begin = 0; 39 rs->begin = 0;
42 rs->printed = 0; 40 rs->printed = 0;
43 rs->missed = 0; 41 rs->missed = 0;
44 } 42 }
45 if (rs->burst && rs->burst > rs->printed) 43 if (rs->burst && rs->burst > rs->printed) {
46 goto print; 44 rs->printed++;
47 45 ret = 1;
48 rs->missed++; 46 } else {
49 spin_unlock_irqrestore(&ratelimit_lock, flags); 47 rs->missed++;
50 return 0; 48 ret = 0;
49 }
50 spin_unlock_irqrestore(&rs->lock, flags);
51 51
52print: 52 return ret;
53 rs->printed++;
54 spin_unlock_irqrestore(&ratelimit_lock, flags);
55 return 1;
56} 53}
57EXPORT_SYMBOL(__ratelimit); 54EXPORT_SYMBOL(__ratelimit);