[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Simplify console driver and avoid unnecessary spinning in the
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 0a81c6edf2b1222aa1d7b5b5e834c4436d101045 # Parent 7062c49e99afb9fc0a8e71165a605fd00bc6b4f3 Simplify console driver and avoid unnecessary spinning in the transmit handler. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 7062c49e99af -r 0a81c6edf2b1 linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Fri Dec 2 14:37:31 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c Fri Dec 2 15:14:20 2005 @@ -389,7 +389,6 @@ } #ifndef CONFIG_XEN_SHADOW_MODE -asmlinkage int xprintk(const char *fmt, ...); void make_lowmem_page_readonly(void *va) { pte_t *pte = virt_to_ptep(va); diff -r 7062c49e99af -r 0a81c6edf2b1 linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Fri Dec 2 14:37:31 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Fri Dec 2 15:14:20 2005 @@ -55,7 +55,6 @@ #include <asm-xen/evtchn.h> #include <asm-xen/xencons.h> -#include "xencons_ring.h" /* * Modes: * 'xencons=off' [XC_OFF]: Console is disabled. @@ -247,7 +246,6 @@ if (xen_start_info->flags & SIF_INITDOMAIN) return; - /* Spin until console data is flushed through to the daemon. */ while (wc != wp) { int sent = 0; @@ -271,8 +269,7 @@ static int xencons_priv_irq; static char x_char; -/* Non-privileged receive callback. */ -static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { int i; unsigned long flags; @@ -311,10 +308,9 @@ spin_unlock_irqrestore(&xencons_lock, flags); } -/* Privileged and non-privileged transmit worker. */ static void __xencons_tx_flush(void) { - int sz, work_done = 0; + int sent, sz, work_done = 0; if (xen_start_info->flags & SIF_INITDOMAIN) { if (x_char) { @@ -340,20 +336,18 @@ } while (wc != wp) { - int sent; sz = wp - wc; if (sz > (wbuf_size - WBUF_MASK(wc))) sz = wbuf_size - WBUF_MASK(wc); sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); - if (sent > 0) { - wc += sent; - work_done = 1; - } + if (sent == 0) + break; + wc += sent; + work_done = 1; } } - if (work_done && (xencons_tty != NULL)) - { + if (work_done && (xencons_tty != NULL)) { wake_up_interruptible(&xencons_tty->write_wait); if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && (xencons_tty->ldisc.write_wakeup != NULL)) @@ -361,31 +355,26 @@ } } +void xencons_tx(void) +{ + unsigned long flags; + + spin_lock_irqsave(&xencons_lock, flags); + __xencons_tx_flush(); + spin_unlock_irqrestore(&xencons_lock, flags); +} + /* Privileged receive callback and transmit kicker. */ static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - static char rbuf[16]; - int i, l; - unsigned long flags; - - spin_lock_irqsave(&xencons_lock, flags); - - if (xencons_tty != NULL) - { - /* Receive work. */ - while ((l = HYPERVISOR_console_io( - CONSOLEIO_read, 16, rbuf)) > 0) - for (i = 0; i < l; i++) - tty_insert_flip_char(xencons_tty, rbuf[i], 0); - if (xencons_tty->flip.count != 0) - tty_flip_buffer_push(xencons_tty); - } - - /* Transmit work. */ - __xencons_tx_flush(); - - spin_unlock_irqrestore(&xencons_lock, flags); + static char rbuf[16]; + int l; + + while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0) + xencons_rx(rbuf, l, regs); + + xencons_tx(); return IRQ_HANDLED; } @@ -664,7 +653,8 @@ if ((rc = tty_register_driver(DRV(xencons_driver))) != 0) { printk("WARNING: Failed to register Xen virtual " "console driver as '%s%d'\n", - DRV(xencons_driver)->name, DRV(xencons_driver)->name_base); + DRV(xencons_driver)->name, + DRV(xencons_driver)->name_base); put_tty_driver(xencons_driver); xencons_driver = NULL; return rc; @@ -681,8 +671,6 @@ "console", NULL); BUG_ON(xencons_priv_irq < 0); - } else { - xencons_ring_register_receiver(xencons_rx); } printk("Xen virtual console successfully installed as %s%d\n", diff -r 7062c49e99af -r 0a81c6edf2b1 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Fri Dec 2 14:37:31 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Fri Dec 2 15:14:20 2005 @@ -19,11 +19,9 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/err.h> -#include "xencons_ring.h" #include <asm-xen/xen-public/io/console.h> static int xencons_irq; -static xencons_receiver_func *xencons_receiver; static inline struct xencons_interface *xencons_interface(void) { @@ -69,10 +67,8 @@ BUG_ON((prod - cons) > sizeof(intf->in)); while (cons != prod) { - if (xencons_receiver != NULL) - xencons_receiver( - intf->in + MASK_XENCONS_IDX(cons++, intf->in), - 1, regs); + xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs); + cons++; } mb(); @@ -80,12 +76,9 @@ notify_daemon(); + xencons_tx(); + return IRQ_HANDLED; -} - -void xencons_ring_register_receiver(xencons_receiver_func *f) -{ - xencons_receiver = f; } int xencons_ring_init(void) diff -r 7062c49e99af -r 0a81c6edf2b1 linux-2.6-xen-sparse/include/asm-xen/xencons.h --- a/linux-2.6-xen-sparse/include/asm-xen/xencons.h Fri Dec 2 14:37:31 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/xencons.h Fri Dec 2 15:14:20 2005 @@ -4,4 +4,11 @@ void xencons_force_flush(void); void xencons_resume(void); +/* Interrupt work hooks. Receive data, or kick data out. */ +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs); +void xencons_tx(void); + +int xencons_ring_init(void); +int xencons_ring_send(const char *data, unsigned len); + #endif /* __ASM_XENCONS_H__ */ diff -r 7062c49e99af -r 0a81c6edf2b1 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h Fri Dec 2 14:37:31 2005 +++ /dev/null Fri Dec 2 15:14:20 2005 @@ -1,23 +0,0 @@ -#ifndef _XENCONS_RING_H -#define _XENCONS_RING_H - -asmlinkage int xprintk(const char *fmt, ...); - -int xencons_ring_init(void); -int xencons_ring_send(const char *data, unsigned len); - -typedef void (xencons_receiver_func)( - char *buf, unsigned len, struct pt_regs *regs); -void xencons_ring_register_receiver(xencons_receiver_func *f); - -#endif /* _XENCONS_RING_H */ - -/* - * Local variables: - * c-file-style: "linux" - * indent-tabs-mode: t - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |