File 19275-19296-schedular-deadlock-fixes.patch of Package xen
# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1237301107 0
# Node ID 043c39eabde1a2118604bcf80574ccc717ff768d
# Parent bc1fc6635e3ee7d389ca3e49e788fb2e54f20740
Do not deadlock in scheduler when sending VIRQ_CON_RING.
Instead defer the virq notification to tasklet context.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset: 19275:3fd8f9b349413c5a04d0e3f93e43463f1021c9dc
xen-unstable date: Fri Mar 06 14:28:27 2009 +0000
Avoid deadlock in tasklet_schedule() after console_force_unlock().
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset: 19296:f57ac4af36b431b10645ee145270ee658f46d58d
xen-unstable date: Mon Mar 09 09:56:16 2009 +0000
Index: xen-3.3.1-testing/xen/drivers/char/console.c
===================================================================
--- xen-3.3.1-testing.orig/xen/drivers/char/console.c
+++ xen-3.3.1-testing/xen/drivers/char/console.c
@@ -315,6 +315,12 @@ static void serial_rx(char c, struct cpu
__serial_rx(c, regs);
}
+static void notify_dom0_con_ring(unsigned long unused)
+{
+ send_guest_global_virq(dom0, VIRQ_CON_RING);
+}
+static DECLARE_TASKLET(notify_dom0_con_ring_tasklet, notify_dom0_con_ring, 0);
+
static long guest_console_write(XEN_GUEST_HANDLE(char) buffer, int count)
{
char kbuf[128], *kptr;
@@ -348,7 +354,7 @@ static long guest_console_write(XEN_GUES
{
for ( kptr = kbuf; *kptr != '\0'; kptr++ )
putchar_console_ring(*kptr);
- send_guest_global_virq(dom0, VIRQ_CON_RING);
+ tasklet_schedule(¬ify_dom0_con_ring_tasklet);
}
spin_unlock_irq(&console_lock);
@@ -414,6 +420,8 @@ long do_console_io(int cmd, int count, X
* *****************************************************
*/
+static bool_t console_locks_busted;
+
static void __putstr(const char *str)
{
int c;
@@ -423,10 +431,12 @@ static void __putstr(const char *str)
sercon_puts(str);
vga_puts(str);
- while ( (c = *str++) != '\0' )
- putchar_console_ring(c);
-
- send_guest_global_virq(dom0, VIRQ_CON_RING);
+ if ( !console_locks_busted )
+ {
+ while ( (c = *str++) != '\0' )
+ putchar_console_ring(c);
+ tasklet_schedule(¬ify_dom0_con_ring_tasklet);
+ }
}
static int printk_prefix_check(char *p, char **pp)
@@ -659,6 +669,7 @@ void console_force_unlock(void)
{
spin_lock_init(&console_lock);
serial_force_unlock(sercon_handle);
+ console_locks_busted = 1;
console_start_sync();
}