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