at master 2.5 kB view raw
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 9static inline void ratelimit_state_init(struct ratelimit_state *rs, 10 int interval, int burst) 11{ 12 memset(rs, 0, sizeof(*rs)); 13 14 raw_spin_lock_init(&rs->lock); 15 rs->interval = interval; 16 rs->burst = burst; 17} 18 19static inline void ratelimit_default_init(struct ratelimit_state *rs) 20{ 21 return ratelimit_state_init(rs, DEFAULT_RATELIMIT_INTERVAL, 22 DEFAULT_RATELIMIT_BURST); 23} 24 25static inline void ratelimit_state_inc_miss(struct ratelimit_state *rs) 26{ 27 atomic_inc(&rs->missed); 28} 29 30static inline int ratelimit_state_get_miss(struct ratelimit_state *rs) 31{ 32 return atomic_read(&rs->missed); 33} 34 35static inline int ratelimit_state_reset_miss(struct ratelimit_state *rs) 36{ 37 return atomic_xchg_relaxed(&rs->missed, 0); 38} 39 40static inline void ratelimit_state_reset_interval(struct ratelimit_state *rs, int interval_init) 41{ 42 unsigned long flags; 43 44 raw_spin_lock_irqsave(&rs->lock, flags); 45 rs->interval = interval_init; 46 rs->flags &= ~RATELIMIT_INITIALIZED; 47 atomic_set(&rs->rs_n_left, rs->burst); 48 ratelimit_state_reset_miss(rs); 49 raw_spin_unlock_irqrestore(&rs->lock, flags); 50} 51 52static inline void ratelimit_state_exit(struct ratelimit_state *rs) 53{ 54 int m; 55 56 if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) 57 return; 58 59 m = ratelimit_state_reset_miss(rs); 60 if (m) 61 pr_warn("%s: %d output lines suppressed due to ratelimiting\n", current->comm, m); 62} 63 64static inline void 65ratelimit_set_flags(struct ratelimit_state *rs, unsigned long flags) 66{ 67 rs->flags = flags; 68} 69 70extern struct ratelimit_state printk_ratelimit_state; 71 72#ifdef CONFIG_PRINTK 73 74#define WARN_ON_RATELIMIT(condition, state) ({ \ 75 bool __rtn_cond = !!(condition); \ 76 WARN_ON(__rtn_cond && __ratelimit(state)); \ 77 __rtn_cond; \ 78}) 79 80#define WARN_RATELIMIT(condition, format, ...) \ 81({ \ 82 static DEFINE_RATELIMIT_STATE(_rs, \ 83 DEFAULT_RATELIMIT_INTERVAL, \ 84 DEFAULT_RATELIMIT_BURST); \ 85 int rtn = !!(condition); \ 86 \ 87 if (unlikely(rtn && __ratelimit(&_rs))) \ 88 WARN(rtn, format, ##__VA_ARGS__); \ 89 \ 90 rtn; \ 91}) 92 93#else 94 95#define WARN_ON_RATELIMIT(condition, state) \ 96 WARN_ON(condition) 97 98#define WARN_RATELIMIT(condition, format, ...) \ 99({ \ 100 int rtn = WARN(condition, format, ##__VA_ARGS__); \ 101 rtn; \ 102}) 103 104#endif 105 106#endif /* _LINUX_RATELIMIT_H */