# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Node ID e834d5b965d025e110f84d29512eab4703b86278
# Parent 50fa06501e54553fda4268d2c904d4984e7b7dec
[XEN] Implement rate-limited logging.
Taken from Andi Kleen's rate limit in the Linux kernel.
This keeps large amounts of prints in the HV down.
Signed-off-by: Steven Rostedt <srostedt@xxxxxxxxxx>
---
xen/arch/x86/mm.c | 9 ++++---
xen/drivers/char/console.c | 55 +++++++++++++++++++++++++++++++++++++++++++++
xen/include/xen/lib.h | 2 +
3 files changed, 63 insertions(+), 3 deletions(-)
diff -r 50fa06501e54 -r e834d5b965d0 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Oct 27 18:15:14 2006 +0100
+++ b/xen/arch/x86/mm.c Fri Oct 27 18:46:20 2006 +0100
@@ -109,9 +109,12 @@
#include <public/memory.h>
#ifdef VERBOSE
-#define MEM_LOG(_f, _a...) \
- printk("DOM%u: (file=mm.c, line=%d) " _f "\n", \
- current->domain->domain_id , __LINE__ , ## _a )
+#define MEM_LOG(_f, _a...) \
+ do { \
+ if ( printk_ratelimit() ) \
+ printk("DOM%u: (file=mm.c, line=%d) " _f "\n", \
+ current->domain->domain_id , __LINE__ , ## _a ); \
+ } while (0)
#else
#define MEM_LOG(_f, _a...) ((void)0)
#endif
diff -r 50fa06501e54 -r e834d5b965d0 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Fri Oct 27 18:15:14 2006 +0100
+++ b/xen/drivers/char/console.c Fri Oct 27 18:46:20 2006 +0100
@@ -4,6 +4,10 @@
* Emergency console I/O for Xen and the domain-0 guest OS.
*
* Copyright (c) 2002-2004, K A Fraser.
+ *
+ * Added printf_ratelimit
+ * Taken from Linux - Author: Andi Kleen (net_ratelimit)
+ * Ported to Xen - Steven Rostedt - Red Hat
*/
#include <xen/stdarg.h>
@@ -26,6 +30,7 @@
#include <asm/current.h>
#include <asm/debugger.h>
#include <asm/io.h>
+#include <asm/div64.h>
/* console: comma-separated list of console outputs. */
static char opt_console[30] = OPT_CONSOLE_STR;
@@ -448,6 +453,56 @@ int console_getc(void)
return serial_getc(sercon_handle);
}
+/*
+ * printk rate limiting, lifted from Linux.
+ *
+ * This enforces a rate limit: not more than one kernel message
+ * every printk_ratelimit_ms (millisecs).
+ */
+int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst)
+{
+ static DEFINE_SPINLOCK(ratelimit_lock);
+ static unsigned long toks = 10 * 5 * 1000;
+ static unsigned long last_msg;
+ static int missed;
+ unsigned long flags;
+ unsigned long long now = NOW(); /* ns */
+ unsigned long ms;
+
+ do_div(now, 1000000);
+ ms = (unsigned long)now;
+
+ spin_lock_irqsave(&ratelimit_lock, flags);
+ toks += ms - last_msg;
+ last_msg = ms;
+ if ( toks > (ratelimit_burst * ratelimit_ms))
+ toks = ratelimit_burst * ratelimit_ms;
+ if ( toks >= ratelimit_ms )
+ {
+ int lost = missed;
+ missed = 0;
+ toks -= ratelimit_ms;
+ spin_unlock_irqrestore(&ratelimit_lock, flags);
+ if ( lost )
+ printk("printk: %d messages suppressed.\n", lost);
+ return 1;
+ }
+ missed++;
+ spin_unlock_irqrestore(&ratelimit_lock, flags);
+ return 0;
+}
+
+/* minimum time in ms between messages */
+int printk_ratelimit_ms = 5 * 1000;
+
+/* number of messages we send before ratelimiting */
+int printk_ratelimit_burst = 10;
+
+int printk_ratelimit(void)
+{
+ return __printk_ratelimit(printk_ratelimit_ms,
+ printk_ratelimit_burst);
+}
/*
* **************************************************************
diff -r 50fa06501e54 -r e834d5b965d0 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h Fri Oct 27 18:15:14 2006 +0100
+++ b/xen/include/xen/lib.h Fri Oct 27 18:46:20 2006 +0100
@@ -56,6 +56,8 @@ extern void panic(const char *format, ..
extern void panic(const char *format, ...)
__attribute__ ((format (printf, 1, 2)));
extern long vm_assist(struct domain *, unsigned int, unsigned int);
+extern int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst);
+extern int printk_ratelimit(void);
/* vsprintf.c */
extern int sprintf(char * buf, const char * fmt, ...)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|