mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-28 20:02:17 +00:00
![Herbert Xu](/assets/img/avatar_default.png)
As it stands if you include printk.h by itself it will fail to compile because it requires definitions from ratelimit.h. However, simply including ratelimit.h from printk.h does not work due to inclusion loops involving sched.h and kernel.h. This patch solves this by moving bits from ratelimit.h into a new header file which can then be included by printk.h without any worries about header loops. The build bot then revealed some intriguing failures arising out of this patch. On s390 there is an inclusion loop with asm/bug.h and linux/kernel.h that triggers a compile failure, because kernel.h will cause asm-generic/bug.h to be included before s390's own asm/bug.h has finished processing. This has been fixed by not including kernel.h in arch/s390/include/asm/bug.h. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Acked-by: Petr Mladek <pmladek@suse.com> Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Link: https://lore.kernel.org/r/20200721062248.GA18383@gondor.apana.org.au
79 lines
1.7 KiB
C
79 lines
1.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_RATELIMIT_H
|
|
#define _LINUX_RATELIMIT_H
|
|
|
|
#include <linux/ratelimit_types.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/spinlock.h>
|
|
|
|
static inline void ratelimit_state_init(struct ratelimit_state *rs,
|
|
int interval, int burst)
|
|
{
|
|
memset(rs, 0, sizeof(*rs));
|
|
|
|
raw_spin_lock_init(&rs->lock);
|
|
rs->interval = interval;
|
|
rs->burst = burst;
|
|
}
|
|
|
|
static inline void ratelimit_default_init(struct ratelimit_state *rs)
|
|
{
|
|
return ratelimit_state_init(rs, DEFAULT_RATELIMIT_INTERVAL,
|
|
DEFAULT_RATELIMIT_BURST);
|
|
}
|
|
|
|
static inline void ratelimit_state_exit(struct ratelimit_state *rs)
|
|
{
|
|
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE))
|
|
return;
|
|
|
|
if (rs->missed) {
|
|
pr_warn("%s: %d output lines suppressed due to ratelimiting\n",
|
|
current->comm, rs->missed);
|
|
rs->missed = 0;
|
|
}
|
|
}
|
|
|
|
static inline void
|
|
ratelimit_set_flags(struct ratelimit_state *rs, unsigned long flags)
|
|
{
|
|
rs->flags = flags;
|
|
}
|
|
|
|
extern struct ratelimit_state printk_ratelimit_state;
|
|
|
|
#ifdef CONFIG_PRINTK
|
|
|
|
#define WARN_ON_RATELIMIT(condition, state) ({ \
|
|
bool __rtn_cond = !!(condition); \
|
|
WARN_ON(__rtn_cond && __ratelimit(state)); \
|
|
__rtn_cond; \
|
|
})
|
|
|
|
#define WARN_RATELIMIT(condition, format, ...) \
|
|
({ \
|
|
static DEFINE_RATELIMIT_STATE(_rs, \
|
|
DEFAULT_RATELIMIT_INTERVAL, \
|
|
DEFAULT_RATELIMIT_BURST); \
|
|
int rtn = !!(condition); \
|
|
\
|
|
if (unlikely(rtn && __ratelimit(&_rs))) \
|
|
WARN(rtn, format, ##__VA_ARGS__); \
|
|
\
|
|
rtn; \
|
|
})
|
|
|
|
#else
|
|
|
|
#define WARN_ON_RATELIMIT(condition, state) \
|
|
WARN_ON(condition)
|
|
|
|
#define WARN_RATELIMIT(condition, format, ...) \
|
|
({ \
|
|
int rtn = WARN(condition, format, ##__VA_ARGS__); \
|
|
rtn; \
|
|
})
|
|
|
|
#endif
|
|
|
|
#endif /* _LINUX_RATELIMIT_H */
|