Branch data Line data Source code
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 : 3 : memset(rs, 0, sizeof(*rs)); 44 : : 45 : 3 : raw_spin_lock_init(&rs->lock); 46 : 3 : rs->interval = interval; 47 : 3 : 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 : 3 : static inline void ratelimit_state_exit(struct ratelimit_state *rs) 57 : : { 58 : 3 : if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) 59 : 3 : return; 60 : : 61 : 3 : if (rs->missed) { 62 : 0 : pr_warn("%s: %d output lines suppressed due to ratelimiting\n", 63 : : current->comm, rs->missed); 64 : 0 : rs->missed = 0; 65 : : } 66 : : } 67 : : 68 : : static inline void 69 : : ratelimit_set_flags(struct ratelimit_state *rs, unsigned long flags) 70 : : { 71 : 3 : 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 */