• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _LINUX_RATELIMIT_H
2 #define _LINUX_RATELIMIT_H
3 
4 #include <linux/param.h>
5 #include <linux/sched.h>
6 #include <linux/spinlock.h>
7 
8 #define DEFAULT_RATELIMIT_INTERVAL	(5 * HZ)
9 #define DEFAULT_RATELIMIT_BURST		10
10 
11 /* issue num suppressed message on exit */
12 #define RATELIMIT_MSG_ON_RELEASE	BIT(0)
13 
14 struct ratelimit_state {
15 	raw_spinlock_t	lock;		/* protect the state */
16 
17 	int		interval;
18 	int		burst;
19 	int		printed;
20 	int		missed;
21 	unsigned long	begin;
22 	unsigned long	flags;
23 };
24 
25 #define RATELIMIT_STATE_INIT(name, interval_init, burst_init) {		\
26 		.lock		= __RAW_SPIN_LOCK_UNLOCKED(name.lock),	\
27 		.interval	= interval_init,			\
28 		.burst		= burst_init,				\
29 	}
30 
31 #define RATELIMIT_STATE_INIT_DISABLED					\
32 	RATELIMIT_STATE_INIT(ratelimit_state, 0, DEFAULT_RATELIMIT_BURST)
33 
34 #define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init)		\
35 									\
36 	struct ratelimit_state name =					\
37 		RATELIMIT_STATE_INIT(name, interval_init, burst_init)	\
38 
ratelimit_state_init(struct ratelimit_state * rs,int interval,int burst)39 static inline void ratelimit_state_init(struct ratelimit_state *rs,
40 					int interval, int burst)
41 {
42 	memset(rs, 0, sizeof(*rs));
43 
44 	raw_spin_lock_init(&rs->lock);
45 	rs->interval	= interval;
46 	rs->burst	= burst;
47 }
48 
ratelimit_default_init(struct ratelimit_state * rs)49 static inline void ratelimit_default_init(struct ratelimit_state *rs)
50 {
51 	return ratelimit_state_init(rs, DEFAULT_RATELIMIT_INTERVAL,
52 					DEFAULT_RATELIMIT_BURST);
53 }
54 
ratelimit_state_exit(struct ratelimit_state * rs)55 static inline void ratelimit_state_exit(struct ratelimit_state *rs)
56 {
57 	if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE))
58 		return;
59 
60 	if (rs->missed) {
61 		pr_warn("%s: %d output lines suppressed due to ratelimiting\n",
62 			current->comm, rs->missed);
63 		rs->missed = 0;
64 	}
65 }
66 
67 static inline void
ratelimit_set_flags(struct ratelimit_state * rs,unsigned long flags)68 ratelimit_set_flags(struct ratelimit_state *rs, unsigned long flags)
69 {
70 	rs->flags = flags;
71 }
72 
73 extern struct ratelimit_state printk_ratelimit_state;
74 
75 extern int ___ratelimit(struct ratelimit_state *rs, const char *func);
76 #define __ratelimit(state) ___ratelimit(state, __func__)
77 
78 #ifdef CONFIG_PRINTK
79 
80 #define WARN_ON_RATELIMIT(condition, state)			\
81 		WARN_ON((condition) && __ratelimit(state))
82 
83 #define WARN_RATELIMIT(condition, format, ...)			\
84 ({								\
85 	static DEFINE_RATELIMIT_STATE(_rs,			\
86 				      DEFAULT_RATELIMIT_INTERVAL,	\
87 				      DEFAULT_RATELIMIT_BURST);	\
88 	int rtn = !!(condition);				\
89 								\
90 	if (unlikely(rtn && __ratelimit(&_rs)))			\
91 		WARN(rtn, format, ##__VA_ARGS__);		\
92 								\
93 	rtn;							\
94 })
95 
96 #else
97 
98 #define WARN_ON_RATELIMIT(condition, state)			\
99 	WARN_ON(condition)
100 
101 #define WARN_RATELIMIT(condition, format, ...)			\
102 ({								\
103 	int rtn = WARN(condition, format, ##__VA_ARGS__);	\
104 	rtn;							\
105 })
106 
107 #endif
108 
109 #endif /* _LINUX_RATELIMIT_H */
110