diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-04-09 09:48:08 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-04-09 09:48:08 +0000 |
commit | 0b00b6397904a181f46925672309f5d6887e4020 (patch) | |
tree | 685c45c23034136ff376c0b0a062508f98f8a7dc | |
parent | 5aa9e2fcf576425ea9f903150a6caf7ddc51b436 (diff) | |
download | xen-0b00b6397904a181f46925672309f5d6887e4020.tar.gz xen-0b00b6397904a181f46925672309f5d6887e4020.tar.bz2 xen-0b00b6397904a181f46925672309f5d6887e4020.zip |
bitkeeper revision 1.860 (40767158VSrp08a0j4zL0drGEP4xNg)
Synchronously flush console data when a domain dies.
-rw-r--r-- | .rootkeys | 1 | ||||
-rw-r--r-- | xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c | 47 | ||||
-rw-r--r-- | xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c | 17 | ||||
-rw-r--r-- | xenolinux-2.4.25-sparse/arch/xen/kernel/process.c | 9 | ||||
-rw-r--r-- | xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c | 5 | ||||
-rw-r--r-- | xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h | 16 | ||||
-rw-r--r-- | xenolinux-2.4.25-sparse/kernel/panic.c | 157 |
7 files changed, 87 insertions, 165 deletions
@@ -738,7 +738,6 @@ 3e5a4e686V0nioX2ZpFf056sgvdiQw xenolinux-2.4.25-sparse/include/linux/sunrpc/debug.h 401c0592pLrp_aCbQRo9GXiYQQaVVA xenolinux-2.4.25-sparse/include/linux/timer.h 3e5a4e68W_hpMlM3u_-QOKMp3gzcwQ xenolinux-2.4.25-sparse/init/do_mounts.c -3e5a4e68TJJavrunYwTAnLRSBxSYqQ xenolinux-2.4.25-sparse/kernel/panic.c 3f9d4b44247udoqWEgFkaHiWv6Uvyg xenolinux-2.4.25-sparse/kernel/time.c 401c059bjLBFYHRD4Py2uM3eA1D4zQ xenolinux-2.4.25-sparse/kernel/timer.c 3e6e7c1efbQe93xCvOpOVCnXTMmQ5w xenolinux-2.4.25-sparse/mkbuildtree diff --git a/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c b/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c index 3287790162..a6ee346857 100644 --- a/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c +++ b/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c @@ -50,6 +50,7 @@ static struct tq_struct xencons_tx_flush_task = { routine: xencons_tx_flush_task_routine }; + /******************** Kernel console driver ********************************/ static void kcons_write( @@ -112,7 +113,7 @@ void xen_console_init(void) } -/*** Useful function for console debugging -- goes straight to Xen ****/ +/*** Useful function for console debugging -- goes straight to Xen. ***/ asmlinkage int xprintk(const char *fmt, ...) { va_list args; @@ -133,6 +134,45 @@ asmlinkage int xprintk(const char *fmt, ...) return 0; } +/*** Forcibly flush console data before dying. ***/ +void xencons_force_flush(void) +{ + ctrl_msg_t msg; + int sz; + + /* Emergency console is synchronous, so there's nothing to flush. */ + if ( start_info.flags & SIF_INITDOMAIN ) + return; + + /* + * We use dangerous control-interface functions that require a quiescent + * system and no interrupts. Try to ensure this with a global cli(). + */ + cli(); + + /* Spin until console data is flushed through to the domain controller. */ + while ( (wc != wp) && !ctrl_if_transmitter_empty() ) + { + /* Interrupts are disabled -- we must manually reap responses. */ + ctrl_if_discard_responses(); + + if ( (sz = wp - wc) == 0 ) + continue; + if ( sz > sizeof(msg.msg) ) + sz = sizeof(msg.msg); + if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) ) + sz = WBUF_SIZE - WBUF_MASK(wc); + + msg.type = CMSG_CONSOLE; + msg.subtype = CMSG_CONSOLE_DATA; + msg.length = sz; + memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz); + + if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) + wc += sz; + } +} + /******************** User-space console driver (/dev/console) ************/ @@ -431,7 +471,7 @@ static void xencons_close(struct tty_struct *tty, struct file *filp) MOD_DEC_USE_COUNT; } -int __init xencons_init(void) +static int __init xencons_init(void) { memset(&xencons_driver, 0, sizeof(struct tty_driver)); xencons_driver.magic = TTY_DRIVER_MAGIC; @@ -481,7 +521,7 @@ int __init xencons_init(void) return 0; } -void __exit xencons_fini(void) +static void __exit xencons_fini(void) { int ret; @@ -501,4 +541,3 @@ void __exit xencons_fini(void) module_init(xencons_init); module_exit(xencons_fini); - diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c index 4c43d091e7..4002ae4c61 100644 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c @@ -315,3 +315,20 @@ void __init ctrl_if_init(void) ctrl_if_resume(); } + + +/* + * !! The following are DANGEROUS FUNCTIONS !! + * Use with care [for example, see xencons_force_flush()]. + */ + +int ctrl_if_transmitter_empty(void) +{ + return (get_ctrl_if()->tx_req_prod == ctrl_if_tx_resp_cons); +} + +void ctrl_if_discard_responses(void) +{ + ctrl_if_tx_resp_cons = get_ctrl_if()->tx_resp_prod; +} + diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c index 640179661b..1ef8521fcb 100644 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c @@ -117,17 +117,20 @@ void cpu_idle (void) void machine_restart(char * __unused) { + /* We really want to get pending console data out before we die. */ + extern void xencons_force_flush(void); + xencons_force_flush(); HYPERVISOR_exit(); } void machine_halt(void) { - HYPERVISOR_exit(); + machine_restart(NULL); } void machine_power_off(void) { - HYPERVISOR_exit(); + machine_restart(NULL); } extern void show_trace(unsigned long* esp); @@ -207,7 +210,7 @@ void release_thread(struct task_struct *dead_task) if (dead_task->mm) { // temporary debugging check if (dead_task->mm->context.size) { - printk("WARNING: dead process %8s still has LDT? <%p/%p>\n", + printk("WARNING: dead process %8s still has LDT? <%p/%08x>\n", dead_task->comm, dead_task->mm->context.ldt, dead_task->mm->context.size); diff --git a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c index be7cc61efe..6be85db7f1 100644 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c @@ -169,6 +169,11 @@ void __init setup_arch(char **cmdline_p) extern unsigned long cpu0_pte_quicklist[]; extern unsigned long cpu0_pgd_quicklist[]; + /* Force a quick death if the kernel panics. */ + extern int panic_timeout; + if ( panic_timeout == 0 ) + panic_timeout = 1; + #ifndef CONFIG_HIGHIO blk_nohighio = 1; #endif diff --git a/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h b/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h index c9e874bb0d..9d12487144 100644 --- a/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h +++ b/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h @@ -95,4 +95,20 @@ void ctrl_if_resume(void); /* Start-of-day setup. */ void ctrl_if_init(void); +/* + * Returns TRUE if there are no outstanding message requests at the domain + * controller. This can be used to ensure that messages have really flushed + * through when it is not possible to use the response-callback interface. + * WARNING: If other subsystems are using the control interface then this + * function might never return TRUE! + */ +int ctrl_if_transmitter_empty(void); /* !! DANGEROUS FUNCTION !! */ + +/* + * Manually discard response messages from the domain controller. + * WARNING: This is usually done automatically -- this function should only + * be called when normal interrupt mechanisms are disabled! + */ +void ctrl_if_discard_responses(void); /* !! DANGEROUS FUNCTION !! */ + #endif /* __ASM_XEN__CONTROL_IF_H__ */ diff --git a/xenolinux-2.4.25-sparse/kernel/panic.c b/xenolinux-2.4.25-sparse/kernel/panic.c deleted file mode 100644 index 9c96d92e40..0000000000 --- a/xenolinux-2.4.25-sparse/kernel/panic.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * linux/kernel/panic.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -/* - * This function is used through-out the kernel (including mm and fs) - * to indicate a major problem. - */ -#include <linux/config.h> -#include <linux/sched.h> -#include <linux/delay.h> -#include <linux/reboot.h> -#include <linux/notifier.h> -#include <linux/init.h> -#include <linux/sysrq.h> -#include <linux/interrupt.h> -#include <linux/console.h> - -asmlinkage void sys_sync(void); /* it's really int */ - -int panic_timeout; - -struct notifier_block *panic_notifier_list; - -static int __init panic_setup(char *str) -{ - panic_timeout = simple_strtoul(str, NULL, 0); - return 1; -} - -__setup("panic=", panic_setup); - -int machine_paniced; - -/** - * panic - halt the system - * @fmt: The text string to print - * - * Display a message, then perform cleanups. Functions in the panic - * notifier list are called after the filesystem cache is flushed (when possible). - * - * This function never returns. - */ - -NORET_TYPE void panic(const char * fmt, ...) -{ - static char buf[1024]; - va_list args; -#if defined(CONFIG_ARCH_S390) - unsigned long caller = (unsigned long) __builtin_return_address(0); -#endif - -#ifdef CONFIG_VT - disable_console_blank(); -#endif - machine_paniced = 1; - - bust_spinlocks(1); - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); - printk(KERN_EMERG "Kernel panic: %s\n",buf); - if (in_interrupt()) - printk(KERN_EMERG "In interrupt handler - not syncing\n"); - else if (!current->pid) - printk(KERN_EMERG "In idle task - not syncing\n"); - else - sys_sync(); - bust_spinlocks(0); - -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - - notifier_call_chain(&panic_notifier_list, 0, NULL); - - if (panic_timeout > 0) - { - /* - * Delay timeout seconds before rebooting the machine. - * We can't use the "normal" timers since we just panicked.. - */ - printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); - mdelay(panic_timeout*1000); - /* - * Should we run the reboot notifier. For the moment Im - * choosing not too. It might crash, be corrupt or do - * more harm than good for other reasons. - */ - machine_restart(NULL); - } -#ifdef __sparc__ - { - extern int stop_a_enabled; - /* Make sure the user can actually press L1-A */ - stop_a_enabled = 1; - printk("Press L1-A to return to the boot prom\n"); - } -#endif -#if defined(CONFIG_ARCH_S390) - disabled_wait(caller); -#endif - sti(); - for(;;) { -#if defined(CONFIG_X86) && defined(CONFIG_VT) - extern void panic_blink(void); - panic_blink(); -#endif - CHECK_EMERGENCY_SYNC -#if defined(CONFIG_XEN) - HYPERVISOR_exit(); -#endif - } -} - -/** - * print_tainted - return a string to represent the kernel taint state. - * - * The string is overwritten by the next call to print_taint(). - */ - -const char *print_tainted() -{ - static char buf[20]; - if (tainted) { - snprintf(buf, sizeof(buf), "Tainted: %c%c", - tainted & 1 ? 'P' : 'G', - tainted & 2 ? 'F' : ' '); - } - else - snprintf(buf, sizeof(buf), "Not tainted"); - return(buf); -} - -int tainted = 0; - -/* - * A BUG() call in an inline function in a header should be avoided, - * because it can seriously bloat the kernel. So here we have - * helper functions. - * We lose the BUG()-time file-and-line info this way, but it's - * usually not very useful from an inline anyway. The backtrace - * tells us what we want to know. - */ - -void __out_of_line_bug(int line) -{ - printk("kernel BUG in header file at line %d\n", line); - - BUG(); - - /* Satisfy __attribute__((noreturn)) */ - for ( ; ; ) - ; -} |