at v4.13 2.7 kB view raw
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 14struct 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 39static 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 49static 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 55static 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 67static inline void 68ratelimit_set_flags(struct ratelimit_state *rs, unsigned long flags) 69{ 70 rs->flags = flags; 71} 72 73extern struct ratelimit_state printk_ratelimit_state; 74 75extern 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 */