ia64/xen-unstable

changeset 1298:de049ec69adc

bitkeeper revision 1.860 (40767158VSrp08a0j4zL0drGEP4xNg)

Synchronously flush console data when a domain dies.
author kaf24@scramble.cl.cam.ac.uk
date Fri Apr 09 09:48:08 2004 +0000 (2004-04-09)
parents 05184d300711
children fbb0f8e4a3f6
files .rootkeys xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c xenolinux-2.4.25-sparse/arch/xen/kernel/process.c xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h xenolinux-2.4.25-sparse/kernel/panic.c
line diff
     1.1 --- a/.rootkeys	Fri Apr 09 07:37:16 2004 +0000
     1.2 +++ b/.rootkeys	Fri Apr 09 09:48:08 2004 +0000
     1.3 @@ -738,7 +738,6 @@ 401c0590D_kwJDU59X8NyvqSv_Cl2A xenolinux
     1.4  3e5a4e686V0nioX2ZpFf056sgvdiQw xenolinux-2.4.25-sparse/include/linux/sunrpc/debug.h
     1.5  401c0592pLrp_aCbQRo9GXiYQQaVVA xenolinux-2.4.25-sparse/include/linux/timer.h
     1.6  3e5a4e68W_hpMlM3u_-QOKMp3gzcwQ xenolinux-2.4.25-sparse/init/do_mounts.c
     1.7 -3e5a4e68TJJavrunYwTAnLRSBxSYqQ xenolinux-2.4.25-sparse/kernel/panic.c
     1.8  3f9d4b44247udoqWEgFkaHiWv6Uvyg xenolinux-2.4.25-sparse/kernel/time.c
     1.9  401c059bjLBFYHRD4Py2uM3eA1D4zQ xenolinux-2.4.25-sparse/kernel/timer.c
    1.10  3e6e7c1efbQe93xCvOpOVCnXTMmQ5w xenolinux-2.4.25-sparse/mkbuildtree
     2.1 --- a/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c	Fri Apr 09 07:37:16 2004 +0000
     2.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c	Fri Apr 09 09:48:08 2004 +0000
     2.3 @@ -50,6 +50,7 @@ static struct tq_struct xencons_tx_flush
     2.4      routine: xencons_tx_flush_task_routine
     2.5  };
     2.6  
     2.7 +
     2.8  /******************** Kernel console driver ********************************/
     2.9  
    2.10  static void kcons_write(
    2.11 @@ -112,7 +113,7 @@ void xen_console_init(void)
    2.12  }
    2.13  
    2.14  
    2.15 -/*** Useful function for console debugging -- goes straight to Xen ****/
    2.16 +/*** Useful function for console debugging -- goes straight to Xen. ***/
    2.17  asmlinkage int xprintk(const char *fmt, ...)
    2.18  {
    2.19      va_list args;
    2.20 @@ -133,6 +134,45 @@ asmlinkage int xprintk(const char *fmt, 
    2.21      return 0;
    2.22  }
    2.23  
    2.24 +/*** Forcibly flush console data before dying. ***/
    2.25 +void xencons_force_flush(void)
    2.26 +{
    2.27 +    ctrl_msg_t msg;
    2.28 +    int        sz;
    2.29 +
    2.30 +    /* Emergency console is synchronous, so there's nothing to flush. */
    2.31 +    if ( start_info.flags & SIF_INITDOMAIN )
    2.32 +        return;
    2.33 +
    2.34 +    /*
    2.35 +     * We use dangerous control-interface functions that require a quiescent
    2.36 +     * system and no interrupts. Try to ensure this with a global cli().
    2.37 +     */
    2.38 +    cli();
    2.39 +
    2.40 +    /* Spin until console data is flushed through to the domain controller. */
    2.41 +    while ( (wc != wp) && !ctrl_if_transmitter_empty() )
    2.42 +    {
    2.43 +        /* Interrupts are disabled -- we must manually reap responses. */
    2.44 +        ctrl_if_discard_responses();
    2.45 +
    2.46 +        if ( (sz = wp - wc) == 0 )
    2.47 +            continue;
    2.48 +        if ( sz > sizeof(msg.msg) )
    2.49 +            sz = sizeof(msg.msg);
    2.50 +        if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) )
    2.51 +            sz = WBUF_SIZE - WBUF_MASK(wc);
    2.52 +
    2.53 +        msg.type    = CMSG_CONSOLE;
    2.54 +        msg.subtype = CMSG_CONSOLE_DATA;
    2.55 +        msg.length  = sz;
    2.56 +        memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz);
    2.57 +            
    2.58 +        if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 )
    2.59 +            wc += sz;
    2.60 +    }
    2.61 +}
    2.62 +
    2.63  
    2.64  /******************** User-space console driver (/dev/console) ************/
    2.65  
    2.66 @@ -431,7 +471,7 @@ static void xencons_close(struct tty_str
    2.67      MOD_DEC_USE_COUNT;
    2.68  }
    2.69  
    2.70 -int __init xencons_init(void)
    2.71 +static int __init xencons_init(void)
    2.72  {
    2.73      memset(&xencons_driver, 0, sizeof(struct tty_driver));
    2.74      xencons_driver.magic           = TTY_DRIVER_MAGIC;
    2.75 @@ -481,7 +521,7 @@ int __init xencons_init(void)
    2.76      return 0;
    2.77  }
    2.78  
    2.79 -void __exit xencons_fini(void)
    2.80 +static void __exit xencons_fini(void)
    2.81  {
    2.82      int ret;
    2.83  
    2.84 @@ -501,4 +541,3 @@ void __exit xencons_fini(void)
    2.85  
    2.86  module_init(xencons_init);
    2.87  module_exit(xencons_fini);
    2.88 -
     3.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c	Fri Apr 09 07:37:16 2004 +0000
     3.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/ctrl_if.c	Fri Apr 09 09:48:08 2004 +0000
     3.3 @@ -315,3 +315,20 @@ void __init ctrl_if_init(void)
     3.4  
     3.5      ctrl_if_resume();
     3.6  }
     3.7 +
     3.8 +
     3.9 +/*
    3.10 + * !! The following are DANGEROUS FUNCTIONS !!
    3.11 + * Use with care [for example, see xencons_force_flush()].
    3.12 + */
    3.13 +
    3.14 +int ctrl_if_transmitter_empty(void)
    3.15 +{
    3.16 +    return (get_ctrl_if()->tx_req_prod == ctrl_if_tx_resp_cons);
    3.17 +}
    3.18 +
    3.19 +void ctrl_if_discard_responses(void)
    3.20 +{
    3.21 +    ctrl_if_tx_resp_cons = get_ctrl_if()->tx_resp_prod;
    3.22 +}
    3.23 +
     4.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c	Fri Apr 09 07:37:16 2004 +0000
     4.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/process.c	Fri Apr 09 09:48:08 2004 +0000
     4.3 @@ -117,17 +117,20 @@ void cpu_idle (void)
     4.4  
     4.5  void machine_restart(char * __unused)
     4.6  {
     4.7 +    /* We really want to get pending console data out before we die. */
     4.8 +    extern void xencons_force_flush(void);
     4.9 +    xencons_force_flush();
    4.10      HYPERVISOR_exit();
    4.11  }
    4.12  
    4.13  void machine_halt(void)
    4.14  {
    4.15 -    HYPERVISOR_exit();
    4.16 +    machine_restart(NULL);
    4.17  }
    4.18  
    4.19  void machine_power_off(void)
    4.20  {
    4.21 -    HYPERVISOR_exit();
    4.22 +    machine_restart(NULL);
    4.23  }
    4.24  
    4.25  extern void show_trace(unsigned long* esp);
    4.26 @@ -207,7 +210,7 @@ void release_thread(struct task_struct *
    4.27      if (dead_task->mm) {
    4.28          // temporary debugging check
    4.29          if (dead_task->mm->context.size) {
    4.30 -            printk("WARNING: dead process %8s still has LDT? <%p/%p>\n",
    4.31 +            printk("WARNING: dead process %8s still has LDT? <%p/%08x>\n",
    4.32                     dead_task->comm, 
    4.33  		   dead_task->mm->context.ldt,
    4.34  		   dead_task->mm->context.size);
     5.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c	Fri Apr 09 07:37:16 2004 +0000
     5.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c	Fri Apr 09 09:48:08 2004 +0000
     5.3 @@ -169,6 +169,11 @@ void __init setup_arch(char **cmdline_p)
     5.4      extern unsigned long cpu0_pte_quicklist[];
     5.5      extern unsigned long cpu0_pgd_quicklist[];
     5.6  
     5.7 +    /* Force a quick death if the kernel panics. */
     5.8 +    extern int panic_timeout;
     5.9 +    if ( panic_timeout == 0 )
    5.10 +        panic_timeout = 1;
    5.11 +
    5.12  #ifndef CONFIG_HIGHIO
    5.13      blk_nohighio = 1;
    5.14  #endif
     6.1 --- a/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h	Fri Apr 09 07:37:16 2004 +0000
     6.2 +++ b/xenolinux-2.4.25-sparse/include/asm-xen/ctrl_if.h	Fri Apr 09 09:48:08 2004 +0000
     6.3 @@ -95,4 +95,20 @@ void ctrl_if_resume(void);
     6.4  /* Start-of-day setup. */
     6.5  void ctrl_if_init(void);
     6.6  
     6.7 +/*
     6.8 + * Returns TRUE if there are no outstanding message requests at the domain
     6.9 + * controller. This can be used to ensure that messages have really flushed
    6.10 + * through when it is not possible to use the response-callback interface.
    6.11 + * WARNING: If other subsystems are using the control interface then this
    6.12 + * function might never return TRUE!
    6.13 + */
    6.14 +int ctrl_if_transmitter_empty(void);  /* !! DANGEROUS FUNCTION !! */
    6.15 +
    6.16 +/*
    6.17 + * Manually discard response messages from the domain controller. 
    6.18 + * WARNING: This is usually done automatically -- this function should only
    6.19 + * be called when normal interrupt mechanisms are disabled!
    6.20 + */
    6.21 +void ctrl_if_discard_responses(void); /* !! DANGEROUS FUNCTION !! */
    6.22 +
    6.23  #endif /* __ASM_XEN__CONTROL_IF_H__ */
     7.1 --- a/xenolinux-2.4.25-sparse/kernel/panic.c	Fri Apr 09 07:37:16 2004 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,157 +0,0 @@
     7.4 -/*
     7.5 - *  linux/kernel/panic.c
     7.6 - *
     7.7 - *  Copyright (C) 1991, 1992  Linus Torvalds
     7.8 - */
     7.9 -
    7.10 -/*
    7.11 - * This function is used through-out the kernel (including mm and fs)
    7.12 - * to indicate a major problem.
    7.13 - */
    7.14 -#include <linux/config.h>
    7.15 -#include <linux/sched.h>
    7.16 -#include <linux/delay.h>
    7.17 -#include <linux/reboot.h>
    7.18 -#include <linux/notifier.h>
    7.19 -#include <linux/init.h>
    7.20 -#include <linux/sysrq.h>
    7.21 -#include <linux/interrupt.h>
    7.22 -#include <linux/console.h>
    7.23 -
    7.24 -asmlinkage void sys_sync(void);	/* it's really int */
    7.25 -
    7.26 -int panic_timeout;
    7.27 -
    7.28 -struct notifier_block *panic_notifier_list;
    7.29 -
    7.30 -static int __init panic_setup(char *str)
    7.31 -{
    7.32 -	panic_timeout = simple_strtoul(str, NULL, 0);
    7.33 -	return 1;
    7.34 -}
    7.35 -
    7.36 -__setup("panic=", panic_setup);
    7.37 -
    7.38 -int machine_paniced; 
    7.39 -
    7.40 -/**
    7.41 - *	panic - halt the system
    7.42 - *	@fmt: The text string to print
    7.43 - *
    7.44 - *	Display a message, then perform cleanups. Functions in the panic
    7.45 - *	notifier list are called after the filesystem cache is flushed (when possible).
    7.46 - *
    7.47 - *	This function never returns.
    7.48 - */
    7.49 - 
    7.50 -NORET_TYPE void panic(const char * fmt, ...)
    7.51 -{
    7.52 -	static char buf[1024];
    7.53 -	va_list args;
    7.54 -#if defined(CONFIG_ARCH_S390)
    7.55 -        unsigned long caller = (unsigned long) __builtin_return_address(0);
    7.56 -#endif
    7.57 -
    7.58 -#ifdef CONFIG_VT
    7.59 -	disable_console_blank();
    7.60 -#endif
    7.61 -	machine_paniced = 1;
    7.62 -	
    7.63 -	bust_spinlocks(1);
    7.64 -	va_start(args, fmt);
    7.65 -	vsprintf(buf, fmt, args);
    7.66 -	va_end(args);
    7.67 -	printk(KERN_EMERG "Kernel panic: %s\n",buf);
    7.68 -	if (in_interrupt())
    7.69 -		printk(KERN_EMERG "In interrupt handler - not syncing\n");
    7.70 -	else if (!current->pid)
    7.71 -		printk(KERN_EMERG "In idle task - not syncing\n");
    7.72 -	else
    7.73 -		sys_sync();
    7.74 -	bust_spinlocks(0);
    7.75 -
    7.76 -#ifdef CONFIG_SMP
    7.77 -	smp_send_stop();
    7.78 -#endif
    7.79 -
    7.80 -	notifier_call_chain(&panic_notifier_list, 0, NULL);
    7.81 -
    7.82 -	if (panic_timeout > 0)
    7.83 -	{
    7.84 -		/*
    7.85 -	 	 * Delay timeout seconds before rebooting the machine. 
    7.86 -		 * We can't use the "normal" timers since we just panicked..
    7.87 -	 	 */
    7.88 -		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
    7.89 -		mdelay(panic_timeout*1000);
    7.90 -		/*
    7.91 -		 *	Should we run the reboot notifier. For the moment Im
    7.92 -		 *	choosing not too. It might crash, be corrupt or do
    7.93 -		 *	more harm than good for other reasons.
    7.94 -		 */
    7.95 -		machine_restart(NULL);
    7.96 -	}
    7.97 -#ifdef __sparc__
    7.98 -	{
    7.99 -		extern int stop_a_enabled;
   7.100 -		/* Make sure the user can actually press L1-A */
   7.101 -		stop_a_enabled = 1;
   7.102 -		printk("Press L1-A to return to the boot prom\n");
   7.103 -	}
   7.104 -#endif
   7.105 -#if defined(CONFIG_ARCH_S390)
   7.106 -        disabled_wait(caller);
   7.107 -#endif
   7.108 -	sti();
   7.109 -	for(;;) {
   7.110 -#if defined(CONFIG_X86) && defined(CONFIG_VT) 
   7.111 -		extern void panic_blink(void);
   7.112 -		panic_blink(); 
   7.113 -#endif
   7.114 -		CHECK_EMERGENCY_SYNC
   7.115 -#if defined(CONFIG_XEN)
   7.116 -		HYPERVISOR_exit();
   7.117 -#endif
   7.118 -	}
   7.119 -}
   7.120 -
   7.121 -/**
   7.122 - *	print_tainted - return a string to represent the kernel taint state.
   7.123 - *
   7.124 - *	The string is overwritten by the next call to print_taint().
   7.125 - */
   7.126 - 
   7.127 -const char *print_tainted()
   7.128 -{
   7.129 -	static char buf[20];
   7.130 -	if (tainted) {
   7.131 -		snprintf(buf, sizeof(buf), "Tainted: %c%c",
   7.132 -			tainted & 1 ? 'P' : 'G',
   7.133 -			tainted & 2 ? 'F' : ' ');
   7.134 -	}
   7.135 -	else
   7.136 -		snprintf(buf, sizeof(buf), "Not tainted");
   7.137 -	return(buf);
   7.138 -}
   7.139 -
   7.140 -int tainted = 0;
   7.141 -
   7.142 -/*
   7.143 - * A BUG() call in an inline function in a header should be avoided,
   7.144 - * because it can seriously bloat the kernel.  So here we have
   7.145 - * helper functions.
   7.146 - * We lose the BUG()-time file-and-line info this way, but it's
   7.147 - * usually not very useful from an inline anyway.  The backtrace
   7.148 - * tells us what we want to know.
   7.149 - */
   7.150 -
   7.151 -void __out_of_line_bug(int line)
   7.152 -{
   7.153 -	printk("kernel BUG in header file at line %d\n", line);
   7.154 -
   7.155 -	BUG();
   7.156 -
   7.157 -	/* Satisfy __attribute__((noreturn)) */
   7.158 -	for ( ; ; )
   7.159 -		;
   7.160 -}