diff options
| author | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-05-19 15:09:05 +1000 |
|---|---|---|
| committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-05-19 15:09:05 +1000 |
| commit | c203e45f069af47ca7623e4dcd8c00bfba2722e4 (patch) | |
| tree | 4563115b6565dcfd97015c1c9366fb3d07cabf19 /lib/ratelimit.c | |
| parent | a94477da38e0b261a7ecea71f4c95a3bcd5be69c (diff) | |
| parent | b8291ad07a7f3b5b990900f0001198ac23ba893e (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'lib/ratelimit.c')
| -rw-r--r-- | lib/ratelimit.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/ratelimit.c b/lib/ratelimit.c new file mode 100644 index 000000000000..485e3040dcd4 --- /dev/null +++ b/lib/ratelimit.c @@ -0,0 +1,51 @@ +/* + * ratelimit.c - Do something with rate limit. + * + * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com> + * + * This file is released under the GPLv2. + * + */ + +#include <linux/kernel.h> +#include <linux/jiffies.h> +#include <linux/module.h> + +/* + * __ratelimit - rate limiting + * @ratelimit_jiffies: minimum time in jiffies between two callbacks + * @ratelimit_burst: number of callbacks we do before ratelimiting + * + * This enforces a rate limit: not more than @ratelimit_burst callbacks + * in every ratelimit_jiffies + */ +int __ratelimit(int ratelimit_jiffies, int ratelimit_burst) +{ + static DEFINE_SPINLOCK(ratelimit_lock); + static unsigned toks = 10 * 5 * HZ; + static unsigned long last_msg; + static int missed; + unsigned long flags; + unsigned long now = jiffies; + + spin_lock_irqsave(&ratelimit_lock, flags); + toks += now - last_msg; + last_msg = now; + if (toks > (ratelimit_burst * ratelimit_jiffies)) + toks = ratelimit_burst * ratelimit_jiffies; + if (toks >= ratelimit_jiffies) { + int lost = missed; + + missed = 0; + toks -= ratelimit_jiffies; + spin_unlock_irqrestore(&ratelimit_lock, flags); + if (lost) + printk(KERN_WARNING "%s: %d messages suppressed\n", + __func__, lost); + return 1; + } + missed++; + spin_unlock_irqrestore(&ratelimit_lock, flags); + return 0; +} +EXPORT_SYMBOL(__ratelimit); |
