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