Improve serial output when dropping characters to drop them in big
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Jun 2008 10:39:42 +0000 (11:39 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Jun 2008 10:39:42 +0000 (11:39 +0100)
batches. Printing one character in one thousand is not useful!

Also make debug handlers all print synchronously.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/common/keyhandler.c
xen/drivers/char/console.c
xen/drivers/char/serial.c
xen/include/xen/console.h
xen/include/xen/serial.h

index 2acd17ae7b9816b3e1da001397586d389077821f..db57e5a9af976a86168e0d9ed3d5c8a7523c6963 100644 (file)
@@ -36,10 +36,10 @@ static void keypress_action(unsigned long unused)
 {
     keyhandler_t *h;
     unsigned char key = keypress_key;
-    console_start_log_everything();
+    console_start_sync();
     if ( (h = key_table[key].u.handler) != NULL )
         (*h)(key);
-    console_end_log_everything();
+    console_end_sync();
 }
 
 static DECLARE_TASKLET(keypress_tasklet, keypress_action, 0);
@@ -50,10 +50,10 @@ void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
 
     if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) )
     {
-        console_start_log_everything();
+        console_start_sync();
         if ( (h = key_table[key].u.irq_handler) != NULL )
             (*h)(key, regs);
-        console_end_log_everything();
+        console_end_sync();
     }
     else
     {
@@ -105,9 +105,6 @@ static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
 {
     unsigned int cpu;
 
-    /* We want to get everything out that we possibly can. */
-    console_start_sync();
-
     printk("'%c' pressed -> dumping registers\n", key);
 
     /* Get local execution state out immediately, in case we get stuck. */
@@ -123,8 +120,6 @@ static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
     }
 
     printk("\n");
-
-    console_end_sync();
 }
 
 static void dump_dom0_registers(unsigned char key)
index feef9a5506513d6ff1eb75f209ea7401b6009051..1007e3e628062bae5832fb51cff6752707e3774e 100644 (file)
@@ -635,16 +635,6 @@ int console_has(const char *device)
     return 0;
 }
 
-void console_start_log_everything(void)
-{
-    atomic_inc(&print_everything);
-}
-
-void console_end_log_everything(void)
-{
-    atomic_dec(&print_everything);
-}
-
 void console_force_unlock(void)
 {
     spin_lock_init(&console_lock);
@@ -659,14 +649,14 @@ void console_force_lock(void)
 
 void console_start_sync(void)
 {
-    console_start_log_everything();
+    atomic_inc(&print_everything);
     serial_start_sync(sercon_handle);
 }
 
 void console_end_sync(void)
 {
     serial_end_sync(sercon_handle);
-    console_end_log_everything();
+    atomic_dec(&print_everything);
 }
 
 void console_putc(char c)
index 34c188c6416260029b8afba9db7a94259f20a9f0..c76a0250470e3f9384c22ff4992bf2e5b0ad237e 100644 (file)
@@ -3,7 +3,7 @@
  * 
  * Framework for serial device drivers.
  * 
- * Copyright (c) 2003-2005, K A Fraser
+ * Copyright (c) 2003-2008, K A Fraser
  */
 
 #include <xen/config.h>
@@ -97,9 +97,18 @@ static void __serial_putc(struct serial_port *port, char c)
     if ( (port->txbuf != NULL) && !port->sync )
     {
         /* Interrupt-driven (asynchronous) transmitter. */
-#ifdef SERIAL_NEVER_DROP_CHARS
+
+        if ( port->tx_quench )
+        {
+            /* Buffer filled and we are dropping characters. */
+            if ( (port->txbufp - port->txbufc) > (serial_txbufsz / 2) )
+                return;
+            port->tx_quench = 0;
+        }
+
         if ( (port->txbufp - port->txbufc) == serial_txbufsz )
         {
+#ifdef SERIAL_NEVER_DROP_CHARS
             /* Buffer is full: we spin waiting for space to appear. */
             int i;
             while ( !port->driver->tx_empty(port) )
@@ -108,9 +117,13 @@ static void __serial_putc(struct serial_port *port, char c)
                 port->driver->putc(
                     port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
             port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c;
+#else
+            /* Buffer is full: drop characters until buffer is half empty. */
+            port->tx_quench = 1;
+#endif
             return;
         }
-#endif
+
         if ( ((port->txbufp - port->txbufc) == 0) &&
                   port->driver->tx_empty(port) )
         {
index 5817f74958a1e6fadd6e974cae61cd7fc170e83a..f5e8be9815dad96643f52ebe3c7a749711c7e5bc 100644 (file)
@@ -26,9 +26,6 @@ void console_force_lock(void);
 void console_start_sync(void);
 void console_end_sync(void);
 
-void console_start_log_everything(void);
-void console_end_log_everything(void);
-
 /*
  * Steal output from the console. Returns +ve identifier, else -ve error.
  * Takes the handle of the serial line to steal, and steal callback function.
index 1608cf53e3832c5dada0102a2809afed06135270..b926672dfc60f86a9e649816c6c79b12eb59e824 100644 (file)
@@ -3,7 +3,7 @@
  * 
  * Framework for serial device drivers.
  * 
- * Copyright (c) 2003-2005, K A Fraser
+ * Copyright (c) 2003-2008, K A Fraser
  */
 
 #ifndef __XEN_SERIAL_H__
@@ -32,6 +32,7 @@ struct serial_port {
     /* Transmit data buffer (interrupt-driven uart). */
     char               *txbuf;
     unsigned int        txbufp, txbufc;
+    bool_t              tx_quench;
     /* Force synchronous transmit. */
     int                 sync;
     /* Receiver callback functions (asynchronous receivers). */