Line data Source code
1 : /*
2 : * ratelimit.c - Do something with rate limit.
3 : *
4 : * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com>
5 : *
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 : *
9 : * This file is released under the GPLv2.
10 : */
11 :
12 : #include <linux/ratelimit.h>
13 : #include <linux/jiffies.h>
14 : #include <linux/export.h>
15 :
16 : /*
17 : * __ratelimit - rate limiting
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
23 : *
24 : * RETURNS:
25 : * 0 means callbacks will be suppressed.
26 : * 1 means go ahead and do it.
27 : */
28 89 : int ___ratelimit(struct ratelimit_state *rs, const char *func)
29 : {
30 : unsigned long flags;
31 : int ret;
32 :
33 89 : if (!rs->interval)
34 : return 1;
35 :
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 88 : if (!raw_spin_trylock_irqsave(&rs->lock, flags))
43 : return 0;
44 :
45 88 : if (!rs->begin)
46 27 : rs->begin = jiffies;
47 :
48 88 : if (time_is_before_jiffies(rs->begin + rs->interval)) {
49 24 : if (rs->missed)
50 0 : printk(KERN_WARNING "%s: %d callbacks suppressed\n",
51 : func, rs->missed);
52 24 : rs->begin = 0;
53 24 : rs->printed = 0;
54 24 : rs->missed = 0;
55 : }
56 88 : if (rs->burst && rs->burst > rs->printed) {
57 88 : rs->printed++;
58 88 : ret = 1;
59 : } else {
60 0 : rs->missed++;
61 : ret = 0;
62 : }
63 264 : raw_spin_unlock_irqrestore(&rs->lock, flags);
64 :
65 88 : return ret;
66 : }
67 : EXPORT_SYMBOL(___ratelimit);
|