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/ratelimit_types.h> 6 : #include <linux/sched.h> 7 : #include <linux/spinlock.h> 8 : 9 0 : static inline void ratelimit_state_init(struct ratelimit_state *rs, 10 : int interval, int burst) 11 : { 12 0 : memset(rs, 0, sizeof(*rs)); 13 : 14 : raw_spin_lock_init(&rs->lock); 15 0 : rs->interval = interval; 16 0 : rs->burst = burst; 17 0 : } 18 : 19 : static inline void ratelimit_default_init(struct ratelimit_state *rs) 20 : { 21 0 : return ratelimit_state_init(rs, DEFAULT_RATELIMIT_INTERVAL, 22 : DEFAULT_RATELIMIT_BURST); 23 : } 24 : 25 0 : static inline void ratelimit_state_exit(struct ratelimit_state *rs) 26 : { 27 0 : if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) 28 : return; 29 : 30 0 : if (rs->missed) { 31 0 : pr_warn("%s: %d output lines suppressed due to ratelimiting\n", 32 : current->comm, rs->missed); 33 0 : rs->missed = 0; 34 : } 35 : } 36 : 37 : static inline void 38 : ratelimit_set_flags(struct ratelimit_state *rs, unsigned long flags) 39 : { 40 0 : rs->flags = flags; 41 : } 42 : 43 : extern struct ratelimit_state printk_ratelimit_state; 44 : 45 : #ifdef CONFIG_PRINTK 46 : 47 : #define WARN_ON_RATELIMIT(condition, state) ({ \ 48 : bool __rtn_cond = !!(condition); \ 49 : WARN_ON(__rtn_cond && __ratelimit(state)); \ 50 : __rtn_cond; \ 51 : }) 52 : 53 : #define WARN_RATELIMIT(condition, format, ...) \ 54 : ({ \ 55 : static DEFINE_RATELIMIT_STATE(_rs, \ 56 : DEFAULT_RATELIMIT_INTERVAL, \ 57 : DEFAULT_RATELIMIT_BURST); \ 58 : int rtn = !!(condition); \ 59 : \ 60 : if (unlikely(rtn && __ratelimit(&_rs))) \ 61 : WARN(rtn, format, ##__VA_ARGS__); \ 62 : \ 63 : rtn; \ 64 : }) 65 : 66 : #else 67 : 68 : #define WARN_ON_RATELIMIT(condition, state) \ 69 : WARN_ON(condition) 70 : 71 : #define WARN_RATELIMIT(condition, format, ...) \ 72 : ({ \ 73 : int rtn = WARN(condition, format, ##__VA_ARGS__); \ 74 : rtn; \ 75 : }) 76 : 77 : #endif 78 : 79 : #endif /* _LINUX_RATELIMIT_H */