Skip to content

Commit

Permalink
Merge branch 'core-printk-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/linux-2.6-tip

* 'core-printk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  ratelimit: Make suppressed output messages more useful
  printk: Remove ratelimit.h from kernel.h
  ratelimit: Fix/allow use in atomic contexts
  ratelimit: Use per ratelimit context locking
  • Loading branch information
Linus Torvalds committed Dec 5, 2009
2 parents 3e72b81 + 5c82871 commit d0b093a
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 37 deletions.
5 changes: 2 additions & 3 deletions include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <linux/bitops.h>
#include <linux/log2.h>
#include <linux/typecheck.h>
#include <linux/ratelimit.h>
#include <linux/dynamic_debug.h>
#include <asm/byteorder.h>
#include <asm/bug.h>
Expand Down Expand Up @@ -241,8 +240,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
asmlinkage int printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2))) __cold;

extern struct ratelimit_state printk_ratelimit_state;
extern int printk_ratelimit(void);
extern int __printk_ratelimit(const char *func);
#define printk_ratelimit() __printk_ratelimit(__func__)
extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
unsigned int interval_msec);

Expand Down
1 change: 1 addition & 0 deletions include/linux/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ static const struct proto_ops name##_ops = { \

#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
#include <linux/ratelimit.h>
extern struct ratelimit_state net_ratelimit_state;
#endif

Expand Down
33 changes: 22 additions & 11 deletions include/linux/ratelimit.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
#ifndef _LINUX_RATELIMIT_H
#define _LINUX_RATELIMIT_H

#include <linux/param.h>
#include <linux/spinlock_types.h>

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

struct ratelimit_state {
int interval;
int burst;
int printed;
int missed;
unsigned long begin;
spinlock_t lock; /* protect the state */

int interval;
int burst;
int printed;
int missed;
unsigned long begin;
};

#define DEFINE_RATELIMIT_STATE(name, interval, burst) \
struct ratelimit_state name = {interval, burst,}
#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \
\
struct ratelimit_state name = { \
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \
.interval = interval_init, \
.burst = burst_init, \
}

extern int ___ratelimit(struct ratelimit_state *rs, const char *func);
#define __ratelimit(state) ___ratelimit(state, __func__)

extern int __ratelimit(struct ratelimit_state *rs);
#endif
#endif /* _LINUX_RATELIMIT_H */
7 changes: 4 additions & 3 deletions kernel/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <linux/bootmem.h>
#include <linux/syscalls.h>
#include <linux/kexec.h>
#include <linux/ratelimit.h>

#include <asm/uaccess.h>

Expand Down Expand Up @@ -1376,11 +1377,11 @@ late_initcall(disable_boot_consoles);
*/
DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10);

int printk_ratelimit(void)
int __printk_ratelimit(const char *func)
{
return __ratelimit(&printk_ratelimit_state);
return ___ratelimit(&printk_ratelimit_state, func);
}
EXPORT_SYMBOL(printk_ratelimit);
EXPORT_SYMBOL(__printk_ratelimit);

/**
* printk_timed_ratelimit - caller-controlled printk ratelimiting
Expand Down
3 changes: 3 additions & 0 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/sysrq.h>
#include <linux/highuid.h>
#include <linux/writeback.h>
#include <linux/ratelimit.h>
#include <linux/hugetlb.h>
#include <linux/initrd.h>
#include <linux/key.h>
Expand Down Expand Up @@ -158,6 +159,8 @@ extern int no_unaligned_warning;
extern int unaligned_dump_stack;
#endif

extern struct ratelimit_state printk_ratelimit_state;

#ifdef CONFIG_RT_MUTEXES
extern int max_lock_depth;
#endif
Expand Down
45 changes: 25 additions & 20 deletions lib/ratelimit.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,56 @@
* parameter. Now every user can use their own standalone ratelimit_state.
*
* This file is released under the GPLv2.
*
*/

#include <linux/kernel.h>
#include <linux/ratelimit.h>
#include <linux/jiffies.h>
#include <linux/module.h>

static DEFINE_SPINLOCK(ratelimit_lock);

/*
* __ratelimit - rate limiting
* @rs: ratelimit_state data
*
* This enforces a rate limit: not more than @rs->ratelimit_burst callbacks
* in every @rs->ratelimit_jiffies
*/
int __ratelimit(struct ratelimit_state *rs)
int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
unsigned long flags;
int ret;

if (!rs->interval)
return 1;

spin_lock_irqsave(&ratelimit_lock, flags);
/*
* If we contend on this state's lock then almost
* by definition we are too busy to print a message,
* in addition to the one that will be printed by
* the entity that is holding the lock already:
*/
if (!spin_trylock_irqsave(&rs->lock, flags))
return 1;

if (!rs->begin)
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);
rs->begin = 0;
func, rs->missed);
rs->begin = 0;
rs->printed = 0;
rs->missed = 0;
rs->missed = 0;
}
if (rs->burst && rs->burst > rs->printed)
goto print;

rs->missed++;
spin_unlock_irqrestore(&ratelimit_lock, flags);
return 0;
if (rs->burst && rs->burst > rs->printed) {
rs->printed++;
ret = 1;
} else {
rs->missed++;
ret = 0;
}
spin_unlock_irqrestore(&rs->lock, flags);

print:
rs->printed++;
spin_unlock_irqrestore(&ratelimit_lock, flags);
return 1;
return ret;
}
EXPORT_SYMBOL(__ratelimit);
EXPORT_SYMBOL(___ratelimit);
2 changes: 2 additions & 0 deletions net/core/sysctl_net_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
#include <linux/init.h>

#include <net/ip.h>
#include <net/sock.h>

Expand Down
2 changes: 2 additions & 0 deletions net/core/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <linux/types.h>
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/ratelimit.h>

#include <net/sock.h>

#include <asm/byteorder.h>
Expand Down

0 comments on commit d0b093a

Please sign in to comment.