Mailing List Archive

Simplify console driver and avoid unnecessary spinning in the
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID 0a81c6edf2b1222aa1d7b5b5e834c4436d101045
# Parent 7062c49e99afb9fc0a8e71165a605fd00bc6b4f3
Simplify console driver and avoid unnecessary spinning in the
transmit handler.

Signed-off-by: Keir Fraser <keir@xensource.com>

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@lists.xensource.com
http://lists.xensource.com/xen-changelog