linux/include/linux/ratelimit.h
<<
>>
Prefs
   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 */
 113