/*
 * ratelimit.c - Do something with rate limit.
 *
 * Isolated from kernel/printk.c by Dave Young <hidave.darkstar@gmail.com>
 *
 * 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.
 *
 * This file is released under the GPLv2.
 */

#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)) {
				pr_warn("%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);
8e3efe8'>refs</a><a class='active' href='/cgit.cgi/linux/net-next.git/log/net/ipv4/protocol.c'>log</a><a href='/cgit.cgi/linux/net-next.git/tree/net/ipv4/protocol.c?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8'>tree</a><a href='/cgit.cgi/linux/net-next.git/commit/net/ipv4/protocol.c?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8'>commit</a><a href='/cgit.cgi/linux/net-next.git/diff/net/ipv4/protocol.c?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8'>diff</a></td><td class='form'><form class='right' method='get' action='/cgit.cgi/linux/net-next.git/log/net/ipv4/protocol.c'>
<input type='hidden' name='id' value='e5fbd977641c92a3a2b559bb5ebb425458e3efe8'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/cgit.cgi/linux/net-next.git/log/?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8'>root</a>/<a href='/cgit.cgi/linux/net-next.git/log/net?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8'>net</a>/<a href='/cgit.cgi/linux/net-next.git/log/net/ipv4?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8'>ipv4</a>/<a href='/cgit.cgi/linux/net-next.git/log/net/ipv4/protocol.c?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8'>protocol.c</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th class='left'>Age</th><th class='left'>Commit message (<a href='/cgit.cgi/linux/net-next.git/log/net/ipv4/protocol.c?id=e5fbd977641c92a3a2b559bb5ebb425458e3efe8&amp;showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Files</th><th class='left'>Lines</th></tr>
ef='/cgit.cgi/linux/net-next.git/log/tools/perf/arch/x86/util/perf_regs.c?id=1105a2d3b36d1603043662d7f46c962b30ebca9e'>perf_regs.c</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th class='left'>Age</th><th class='left'>Commit message (<a href='/cgit.cgi/linux/net-next.git/log/tools/perf/arch/x86/util/perf_regs.c?id=1105a2d3b36d1603043662d7f46c962b30ebca9e&amp;showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Files</th><th class='left'>Lines</th></tr>