forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
1.6 KiB
70 lines
1.6 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* |
|
* ratelimit.c - Do something with rate limit. |
|
* |
|
* Isolated from kernel/printk.c by Dave Young <[email protected]> |
|
* |
|
* 2008-05-01 rewrite the function and use a ratelimit_state data struct as |
|
* parameter. Now every user can use their own standalone ratelimit_state. |
|
*/ |
|
|
|
#include <linux/ratelimit.h> |
|
#include <linux/jiffies.h> |
|
#include <linux/export.h> |
|
|
|
/* |
|
* __ratelimit - rate limiting |
|
* @rs: ratelimit_state data |
|
* @func: name of calling function |
|
* |
|
* This enforces a rate limit: not more than @rs->burst callbacks |
|
* in every @rs->interval |
|
* |
|
* RETURNS: |
|
* 0 means callbacks will be suppressed. |
|
* 1 means go ahead and do it. |
|
*/ |
|
int ___ratelimit(struct ratelimit_state *rs, const char *func) |
|
{ |
|
unsigned long flags; |
|
int ret; |
|
|
|
if (!rs->interval) |
|
return 1; |
|
|
|
/* |
|
* If we contend on this state's lock then almost |
|
* by definition we are too busy to print a message, |
|
* in addition to the one that will be printed by |
|
* the entity that is holding the lock already: |
|
*/ |
|
if (!raw_spin_trylock_irqsave(&rs->lock, flags)) |
|
return 0; |
|
|
|
if (!rs->begin) |
|
rs->begin = jiffies; |
|
|
|
if (time_is_before_jiffies(rs->begin + rs->interval)) { |
|
if (rs->missed) { |
|
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) { |
|
printk_deferred(KERN_WARNING |
|
"%s: %d callbacks suppressed\n", |
|
func, rs->missed); |
|
rs->missed = 0; |
|
} |
|
} |
|
rs->begin = jiffies; |
|
rs->printed = 0; |
|
} |
|
if (rs->burst && rs->burst > rs->printed) { |
|
rs->printed++; |
|
ret = 1; |
|
} else { |
|
rs->missed++; |
|
ret = 0; |
|
} |
|
raw_spin_unlock_irqrestore(&rs->lock, flags); |
|
|
|
return ret; |
|
} |
|
EXPORT_SYMBOL(___ratelimit);
|
|
|