xref: /linux-6.15/include/linux/ratelimit.h (revision cfd6ed45)
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 
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 
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 
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
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 	bool __rtn_cond = !!(condition);			\
82 	WARN_ON(__rtn_cond && __ratelimit(state));		\
83 	__rtn_cond;						\
84 })
85 
86 #define WARN_RATELIMIT(condition, format, ...)			\
87 ({								\
88 	static DEFINE_RATELIMIT_STATE(_rs,			\
89 				      DEFAULT_RATELIMIT_INTERVAL,	\
90 				      DEFAULT_RATELIMIT_BURST);	\
91 	int rtn = !!(condition);				\
92 								\
93 	if (unlikely(rtn && __ratelimit(&_rs)))			\
94 		WARN(rtn, format, ##__VA_ARGS__);		\
95 								\
96 	rtn;							\
97 })
98 
99 #else
100 
101 #define WARN_ON_RATELIMIT(condition, state)			\
102 	WARN_ON(condition)
103 
104 #define WARN_RATELIMIT(condition, format, ...)			\
105 ({								\
106 	int rtn = WARN(condition, format, ##__VA_ARGS__);	\
107 	rtn;							\
108 })
109 
110 #endif
111 
112 #endif /* _LINUX_RATELIMIT_H */
113