]>
Commit | Line | Data |
---|---|---|
5f97a5a8 DY |
1 | /* |
2 | * ratelimit.c - Do something with rate limit. | |
3 | * | |
4 | * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com> | |
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 DY |
17 | static DEFINE_SPINLOCK(ratelimit_lock); |
18 | static unsigned long flags; | |
19 | ||
5f97a5a8 DY |
20 | /* |
21 | * __ratelimit - rate limiting | |
717115e1 | 22 | * @rs: ratelimit_state data |
5f97a5a8 | 23 | * |
717115e1 DY |
24 | * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks |
25 | * in every @rs->ratelimit_jiffies | |
5f97a5a8 | 26 | */ |
717115e1 | 27 | int __ratelimit(struct ratelimit_state *rs) |
5f97a5a8 | 28 | { |
717115e1 DY |
29 | if (!rs->interval) |
30 | return 1; | |
5f97a5a8 DY |
31 | |
32 | spin_lock_irqsave(&ratelimit_lock, flags); | |
717115e1 DY |
33 | if (!rs->begin) |
34 | rs->begin = jiffies; | |
5f97a5a8 | 35 | |
717115e1 DY |
36 | if (time_is_before_jiffies(rs->begin + rs->interval)) { |
37 | if (rs->missed) | |
38 | printk(KERN_WARNING "%s: %d callbacks suppressed\n", | |
39 | __func__, rs->missed); | |
40 | rs->begin = 0; | |
41 | rs->printed = 0; | |
42 | rs->missed = 0; | |
5f97a5a8 | 43 | } |
717115e1 DY |
44 | if (rs->burst && rs->burst > rs->printed) |
45 | goto print; | |
46 | ||
47 | rs->missed++; | |
5f97a5a8 DY |
48 | spin_unlock_irqrestore(&ratelimit_lock, flags); |
49 | return 0; | |
717115e1 DY |
50 | |
51 | print: | |
52 | rs->printed++; | |
53 | spin_unlock_irqrestore(&ratelimit_lock, flags); | |
54 | return 1; | |
5f97a5a8 DY |
55 | } |
56 | EXPORT_SYMBOL(__ratelimit); |