# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID fac36a01c06e49dfedd4124ab45131e6c67dec60
# Parent cfb1136ee8f73a07d0c6fed9dc6f4084d592c129
[XEN] Fix log-level printk logic for multi-line and partial-line printks.
Add support for switching to print-all mode, and use this for
debug-key output.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/common/keyhandler.c | 4 +
xen/drivers/char/console.c | 115 +++++++++++++++++++++++++++------------------
xen/include/xen/console.h | 3 +
3 files changed, 76 insertions(+), 46 deletions(-)
diff -r cfb1136ee8f7 -r fac36a01c06e xen/common/keyhandler.c
--- a/xen/common/keyhandler.c Fri Nov 03 10:52:29 2006 +0000
+++ b/xen/common/keyhandler.c Fri Nov 03 11:15:10 2006 +0000
@@ -36,8 +36,10 @@ static void keypress_softirq(void)
{
keyhandler_t *h;
unsigned char key = keypress_key;
+ console_start_log_everything();
if ( (h = key_table[key].u.handler) != NULL )
(*h)(key);
+ console_end_log_everything();
}
void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
@@ -46,8 +48,10 @@ void handle_keypress(unsigned char key,
if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
{
+ console_start_log_everything();
if ( (h = key_table[key].u.irq_handler) != NULL )
(*h)(key, regs);
+ console_end_log_everything();
}
else
{
diff -r cfb1136ee8f7 -r fac36a01c06e xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Fri Nov 03 10:52:29 2006 +0000
+++ b/xen/drivers/char/console.c Fri Nov 03 11:15:10 2006 +0000
@@ -101,7 +101,7 @@ custom_param("loglvl", parse_loglvl);
custom_param("loglvl", parse_loglvl);
custom_param("guest_loglvl", parse_guest_loglvl);
-static int xen_startup = 1;
+static atomic_t print_everything = ATOMIC_INIT(1);
#define ___parse_loglvl(s, ps, lvlstr, lvlnum) \
if ( !strncmp((s), (lvlstr), strlen(lvlstr)) ) { \
@@ -380,7 +380,7 @@ long do_console_io(int cmd, int count, X
* *****************************************************
*/
-static inline void __putstr(const char *str)
+static void __putstr(const char *str)
{
int c;
@@ -393,18 +393,47 @@ static inline void __putstr(const char *
}
}
+static int printk_prefix_check(char *p, char **pp)
+{
+ int loglvl = -1;
+ int upper_thresh = xenlog_upper_thresh;
+ int lower_thresh = xenlog_lower_thresh;
+
+ while ( (p[0] == '<') && (p[1] != '\0') && (p[2] == '>') )
+ {
+ switch ( p[1] )
+ {
+ case 'G':
+ upper_thresh = xenlog_guest_upper_thresh;
+ lower_thresh = xenlog_guest_lower_thresh;
+ if ( loglvl == -1 )
+ loglvl = XENLOG_GUEST_DEFAULT;
+ break;
+ case '0' ... '3':
+ loglvl = p[1] - '0';
+ break;
+ }
+ p += 3;
+ }
+
+ if ( loglvl == -1 )
+ loglvl = XENLOG_DEFAULT;
+
+ *pp = p;
+
+ return ((atomic_read(&print_everything) != 0) ||
+ (loglvl < lower_thresh) ||
+ ((loglvl < upper_thresh) && printk_ratelimit()));
+}
+
void printk(const char *fmt, ...)
{
static char buf[1024];
- static int start_of_line = 1;
+ static int start_of_line = 1, do_print;
va_list args;
char *p, *q;
unsigned long flags;
- int level = -1;
- int upper_thresh = xenlog_upper_thresh;
- int lower_thresh = xenlog_lower_thresh;
- int print_regardless = xen_startup;
/* console_lock can be acquired recursively from __printk_ratelimit(). */
local_irq_save(flags);
@@ -416,41 +445,18 @@ void printk(const char *fmt, ...)
p = buf;
- while ( (p[0] == '<') && (p[1] != '\0') && (p[2] == '>') )
- {
- switch ( p[1] )
- {
- case 'G':
- upper_thresh = xenlog_guest_upper_thresh;
- lower_thresh = xenlog_guest_lower_thresh;
- if ( level == -1 )
- level = XENLOG_GUEST_DEFAULT;
- break;
- case '0' ... '3':
- level = p[1] - '0';
- break;
- }
- p += 3;
- }
-
- if ( level == -1 )
- level = XENLOG_DEFAULT;
-
- if ( !print_regardless )
- {
- if ( level >= upper_thresh )
- goto out;
- if ( (level >= lower_thresh) && (!printk_ratelimit()) )
- goto out;
- }
-
while ( (q = strchr(p, '\n')) != NULL )
{
*q = '\0';
if ( start_of_line )
- __putstr(printk_prefix);
- __putstr(p);
- __putstr("\n");
+ do_print = printk_prefix_check(p, &p);
+ if ( do_print )
+ {
+ if ( start_of_line )
+ __putstr(printk_prefix);
+ __putstr(p);
+ __putstr("\n");
+ }
start_of_line = 1;
p = q + 1;
}
@@ -458,12 +464,16 @@ void printk(const char *fmt, ...)
if ( *p != '\0' )
{
if ( start_of_line )
- __putstr(printk_prefix);
- __putstr(p);
+ do_print = printk_prefix_check(p, &p);
+ if ( do_print )
+ {
+ if ( start_of_line )
+ __putstr(printk_prefix);
+ __putstr(p);
+ }
start_of_line = 0;
}
- out:
spin_unlock_recursive(&console_lock);
local_irq_restore(flags);
}
@@ -524,7 +534,7 @@ void console_endboot(void)
if ( opt_sync_console )
{
printk("**********************************************\n");
- printk("******* WARNING: CONSOLE OUTPUT IS SYCHRONOUS\n");
+ printk("******* WARNING: CONSOLE OUTPUT IS SYNCHRONOUS\n");
printk("******* This option is intended to aid debugging "
"of Xen by ensuring\n");
printk("******* that all output is synchronously delivered "
@@ -560,7 +570,17 @@ void console_endboot(void)
switch_serial_input();
/* Now we implement the logging thresholds. */
- xen_startup = 0;
+ console_end_log_everything();
+}
+
+void console_start_log_everything(void)
+{
+ atomic_inc(&print_everything);
+}
+
+void console_end_log_everything(void)
+{
+ atomic_dec(&print_everything);
}
void console_force_unlock(void)
@@ -577,12 +597,14 @@ void console_force_lock(void)
void console_start_sync(void)
{
+ console_start_log_everything();
serial_start_sync(sercon_handle);
}
void console_end_sync(void)
{
serial_end_sync(sercon_handle);
+ console_end_log_everything();
}
void console_putc(char c)
@@ -701,9 +723,10 @@ static void debugtrace_toggle(void)
watchdog_disable();
spin_lock_irqsave(&debugtrace_lock, flags);
- // dump the buffer *before* toggling, in case the act of dumping the
- // buffer itself causes more printk's...
- //
+ /*
+ * Dump the buffer *before* toggling, in case the act of dumping the
+ * buffer itself causes more printk() invocations.
+ */
printk("debugtrace_printk now writing to %s.\n",
!debugtrace_send_to_console ? "console": "buffer");
if ( !debugtrace_send_to_console )
diff -r cfb1136ee8f7 -r fac36a01c06e xen/include/xen/console.h
--- a/xen/include/xen/console.h Fri Nov 03 10:52:29 2006 +0000
+++ b/xen/include/xen/console.h Fri Nov 03 11:15:10 2006 +0000
@@ -26,6 +26,9 @@ void console_start_sync(void);
void console_start_sync(void);
void console_end_sync(void);
+void console_start_log_everything(void);
+void console_end_log_everything(void);
+
/*
* Steal output from the console. Returns +ve identifier, else -ve error.
* Takes the handle of the serial line to steal, and steal callback function.
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|