Skip to content

Commit

Permalink
ratelimit: extend to print suppressed messages on release
Browse files Browse the repository at this point in the history
Extend the ratelimiting facility to print the amount of suppressed lines
when it is being released.

This use case is aimed at short-termed, burst-like users for which we
want to output the suppressed lines stats only once, after it has been
disposed of.  For an example, see /dev/kmsg usage in a follow-on patch.

Also, change the printk() line we issue on release to not use
"callbacks" as it is misleading: we're not suppressing callbacks but
printk() calls.

This has been separated from a previous patch by Linus.

Link: http://lkml.kernel.org/r/20160716061745.15795-2-bp@alien8.de
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Dave Young <dyoung@redhat.com>
Cc: Franck Bui <fbui@suse.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
suryasaimadhu authored and torvalds committed Aug 2, 2016
1 parent b5644a1 commit 6b1d174
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
38 changes: 33 additions & 5 deletions include/linux/ratelimit.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
#define _LINUX_RATELIMIT_H

#include <linux/param.h>
#include <linux/sched.h>
#include <linux/spinlock.h>

#define DEFAULT_RATELIMIT_INTERVAL (5 * HZ)
#define DEFAULT_RATELIMIT_BURST 10

/* issue num suppressed message on exit */
#define RATELIMIT_MSG_ON_RELEASE BIT(0)

struct ratelimit_state {
raw_spinlock_t lock; /* protect the state */

Expand All @@ -15,6 +19,7 @@ struct ratelimit_state {
int printed;
int missed;
unsigned long begin;
unsigned long flags;
};

#define RATELIMIT_STATE_INIT(name, interval_init, burst_init) { \
Expand All @@ -34,12 +39,35 @@ struct ratelimit_state {
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;
rs->printed = 0;
rs->missed = 0;
rs->begin = 0;
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;
Expand Down
10 changes: 6 additions & 4 deletions lib/ratelimit.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
rs->begin = jiffies;

if (time_is_before_jiffies(rs->begin + rs->interval)) {
if (rs->missed)
printk(KERN_WARNING "%s: %d callbacks suppressed\n",
func, rs->missed);
if (rs->missed) {
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) {
pr_warn("%s: %d callbacks suppressed\n", func, rs->missed);
rs->missed = 0;
}
}
rs->begin = jiffies;
rs->printed = 0;
rs->missed = 0;
}
if (rs->burst && rs->burst > rs->printed) {
rs->printed++;
Expand Down

0 comments on commit 6b1d174

Please sign in to comment.