1#ifndef _LINUX_RATELIMIT_H
2#define _LINUX_RATELIMIT_H
3
4#include <linux/param.h>
5#include <linux/spinlock.h>
6
7#define DEFAULT_RATELIMIT_INTERVAL	(5 * HZ)
8#define DEFAULT_RATELIMIT_BURST		10
9
10struct ratelimit_state {
11	raw_spinlock_t	lock;		/* protect the state */
12
13	int		interval;
14	int		burst;
15	int		printed;
16	int		missed;
17	unsigned long	begin;
18};
19
20#define RATELIMIT_STATE_INIT(name, interval_init, burst_init) {		\
21		.lock		= __RAW_SPIN_LOCK_UNLOCKED(name.lock),	\
22		.interval	= interval_init,			\
23		.burst		= burst_init,				\
24	}
25
26#define RATELIMIT_STATE_INIT_DISABLED					\
27	RATELIMIT_STATE_INIT(ratelimit_state, 0, DEFAULT_RATELIMIT_BURST)
28
29#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init)		\
30									\
31	struct ratelimit_state name =					\
32		RATELIMIT_STATE_INIT(name, interval_init, burst_init)	\
33
34static inline void ratelimit_state_init(struct ratelimit_state *rs,
35					int interval, int burst)
36{
37	raw_spin_lock_init(&rs->lock);
38	rs->interval = interval;
39	rs->burst = burst;
40	rs->printed = 0;
41	rs->missed = 0;
42	rs->begin = 0;
43}
44
45extern struct ratelimit_state printk_ratelimit_state;
46
47extern int ___ratelimit(struct ratelimit_state *rs, const char *func);
48#define __ratelimit(state) ___ratelimit(state, __func__)
49
50#ifdef CONFIG_PRINTK
51
52#define WARN_ON_RATELIMIT(condition, state)			\
53		WARN_ON((condition) && __ratelimit(state))
54
55#define WARN_RATELIMIT(condition, format, ...)			\
56({								\
57	static DEFINE_RATELIMIT_STATE(_rs,			\
58				      DEFAULT_RATELIMIT_INTERVAL,	\
59				      DEFAULT_RATELIMIT_BURST);	\
60	int rtn = !!(condition);				\
61								\
62	if (unlikely(rtn && __ratelimit(&_rs)))			\
63		WARN(rtn, format, ##__VA_ARGS__);		\
64								\
65	rtn;							\
66})
67
68#else
69
70#define WARN_ON_RATELIMIT(condition, state)			\
71	WARN_ON(condition)
72
73#define WARN_RATELIMIT(condition, format, ...)			\
74({								\
75	int rtn = WARN(condition, format, ##__VA_ARGS__);	\
76	rtn;							\
77})
78
79#endif
80
81#endif /* _LINUX_RATELIMIT_H */
82