]>
Commit | Line | Data |
---|---|---|
5f97a5a8 DY |
1 | /* |
2 | * ratelimit.c - Do something with rate limit. | |
3 | * | |
4 | * Isolated from kernel/printk.c by Dave Young <[email protected]> | |
5 | * | |
717115e1 DY |
6 | * 2008-05-01 rewrite the function and use a ratelimit_state data struct as |
7 | * parameter. Now every user can use their own standalone ratelimit_state. | |
8 | * | |
5f97a5a8 DY |
9 | * This file is released under the GPLv2. |
10 | * | |
11 | */ | |
12 | ||
13 | #include <linux/kernel.h> | |
14 | #include <linux/jiffies.h> | |
15 | #include <linux/module.h> | |
16 | ||
717115e1 | 17 | static DEFINE_SPINLOCK(ratelimit_lock); |
717115e1 | 18 | |
5f97a5a8 DY |
19 | /* |
20 | * __ratelimit - rate limiting | |
717115e1 | 21 | * @rs: ratelimit_state data |
5f97a5a8 | 22 | * |
717115e1 DY |
23 | * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks |
24 | * in every @rs->ratelimit_jiffies | |
5f97a5a8 | 25 | */ |
717115e1 | 26 | int __ratelimit(struct ratelimit_state *rs) |
5f97a5a8 | 27 | { |
4d9c377c AD |
28 | unsigned long flags; |
29 | ||
717115e1 DY |
30 | if (!rs->interval) |
31 | return 1; | |
5f97a5a8 DY |
32 | |
33 | spin_lock_irqsave(&ratelimit_lock, flags); | |
717115e1 DY |
34 | if (!rs->begin) |
35 | rs->begin = jiffies; | |
5f97a5a8 | 36 | |
717115e1 DY |
37 | if (time_is_before_jiffies(rs->begin + rs->interval)) { |
38 | if (rs->missed) | |
39 | printk(KERN_WARNING "%s: %d callbacks suppressed\n", | |
40 | __func__, rs->missed); | |
41 | rs->begin = 0; | |
42 | rs->printed = 0; | |
43 | rs->missed = 0; | |
5f97a5a8 | 44 | } |
717115e1 DY |
45 | if (rs->burst && rs->burst > rs->printed) |
46 | goto print; | |
47 | ||
48 | rs->missed++; | |
5f97a5a8 DY |
49 | spin_unlock_irqrestore(&ratelimit_lock, flags); |
50 | return 0; | |
717115e1 DY |
51 | |
52 | print: | |
53 | rs->printed++; | |
54 | spin_unlock_irqrestore(&ratelimit_lock, flags); | |
55 | return 1; | |
5f97a5a8 DY |
56 | } |
57 | EXPORT_SYMBOL(__ratelimit); |