diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-03-06 14:28:27 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-03-06 14:28:27 +0000 |
commit | b3a3ac0f6b46feb2ff6abf4deba9a7395aed2575 (patch) | |
tree | e03d74d7bc6ce6baf1d2935a266b8c4b4343f520 /xen/drivers/char/console.c | |
parent | 6976476d8c502fa762076493b56ae1ee7d5106e1 (diff) | |
download | xen-b3a3ac0f6b46feb2ff6abf4deba9a7395aed2575.tar.gz xen-b3a3ac0f6b46feb2ff6abf4deba9a7395aed2575.tar.bz2 xen-b3a3ac0f6b46feb2ff6abf4deba9a7395aed2575.zip |
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>
Diffstat (limited to 'xen/drivers/char/console.c')
-rw-r--r-- | xen/drivers/char/console.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 3096b3ec9d..00a32022dd 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -315,6 +315,12 @@ static void serial_rx(char c, struct cpu_user_regs *regs) __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_GUEST_HANDLE(char) buffer, int count) { 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); @@ -426,7 +432,7 @@ static void __putstr(const char *str) while ( (c = *str++) != '\0' ) putchar_console_ring(c); - send_guest_global_virq(dom0, VIRQ_CON_RING); + tasklet_schedule(¬ify_dom0_con_ring_tasklet); } static int printk_prefix_check(char *p, char **pp) |