blob: 26187edcc7ead6c8c14bd69f1bb77cb3ca4640b4 [file] [log] [blame]
Dave Young5f97a5a2008-04-29 00:59:43 -07001/*
2 * ratelimit.c - Do something with rate limit.
3 *
4 * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com>
5 *
Dave Young717115e2008-07-25 01:45:58 -07006 * 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 *
Dave Young5f97a5a2008-04-29 00:59:43 -07009 * 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
Dave Young717115e2008-07-25 01:45:58 -070017static DEFINE_SPINLOCK(ratelimit_lock);
Dave Young717115e2008-07-25 01:45:58 -070018
Dave Young5f97a5a2008-04-29 00:59:43 -070019/*
20 * __ratelimit - rate limiting
Dave Young717115e2008-07-25 01:45:58 -070021 * @rs: ratelimit_state data
Dave Young5f97a5a2008-04-29 00:59:43 -070022 *
Dave Young717115e2008-07-25 01:45:58 -070023 * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks
24 * in every @rs->ratelimit_jiffies
Dave Young5f97a5a2008-04-29 00:59:43 -070025 */
Dave Young717115e2008-07-25 01:45:58 -070026int __ratelimit(struct ratelimit_state *rs)
Dave Young5f97a5a2008-04-29 00:59:43 -070027{
Alexey Dobriyan4d9c3772008-07-28 15:46:21 -070028 unsigned long flags;
29
Dave Young717115e2008-07-25 01:45:58 -070030 if (!rs->interval)
31 return 1;
Dave Young5f97a5a2008-04-29 00:59:43 -070032
33 spin_lock_irqsave(&ratelimit_lock, flags);
Dave Young717115e2008-07-25 01:45:58 -070034 if (!rs->begin)
35 rs->begin = jiffies;
Dave Young5f97a5a2008-04-29 00:59:43 -070036
Dave Young717115e2008-07-25 01:45:58 -070037 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;
Dave Young5f97a5a2008-04-29 00:59:43 -070044 }
Dave Young717115e2008-07-25 01:45:58 -070045 if (rs->burst && rs->burst > rs->printed)
46 goto print;
47
48 rs->missed++;
Dave Young5f97a5a2008-04-29 00:59:43 -070049 spin_unlock_irqrestore(&ratelimit_lock, flags);
50 return 0;
Dave Young717115e2008-07-25 01:45:58 -070051
52print:
53 rs->printed++;
54 spin_unlock_irqrestore(&ratelimit_lock, flags);
55 return 1;
Dave Young5f97a5a2008-04-29 00:59:43 -070056}
57EXPORT_SYMBOL(__ratelimit);