Bring back console_start_log_everything() as a milder alternative to
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Jun 2008 13:15:00 +0000 (14:15 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Jun 2008 13:15:00 +0000 (14:15 +0100)
console_start_sync(). Revert keyhandler logic to use it. The
difference now is that serial logic is updated to not drop characters
if inb a log_everything region. Still this is milder than a sync
region since the async buffer must be filled before we start to
busy-wait on each character.

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 db57e5a9af976a86168e0d9ed3d5c8a7523c6963..2acd17ae7b9816b3e1da001397586d389077821f 100644 (file)
@@ -36,10 +36,10 @@ static void keypress_action(unsigned long unused)
 {
     keyhandler_t *h;
     unsigned char key = keypress_key;
-    console_start_sync();
+    console_start_log_everything();
     if ( (h = key_table[key].u.handler) != NULL )
         (*h)(key);
-    console_end_sync();
+    console_end_log_everything();
 }
 
 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_sync();
+        console_start_log_everything();
         if ( (h = key_table[key].u.irq_handler) != NULL )
             (*h)(key, regs);
-        console_end_sync();
+        console_end_log_everything();
     }
     else
     {
@@ -105,6 +105,9 @@ 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. */
@@ -120,6 +123,8 @@ 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 1007e3e628062bae5832fb51cff6752707e3774e..31e73c3201eb6784491e18f4124e68c3728dc490 100644 (file)
@@ -635,6 +635,18 @@ int console_has(const char *device)
     return 0;
 }
 
+void console_start_log_everything(void)
+{
+    serial_start_log_everything(sercon_handle);
+    atomic_inc(&print_everything);
+}
+
+void console_end_log_everything(void)
+{
+    serial_end_log_everything(sercon_handle);
+    atomic_dec(&print_everything);
+}
+
 void console_force_unlock(void)
 {
     spin_lock_init(&console_lock);
index c76a0250470e3f9384c22ff4992bf2e5b0ad237e..2d0dcd53513a20448b722d81245016d1d7e263d4 100644 (file)
@@ -108,19 +108,23 @@ static void __serial_putc(struct serial_port *port, char c)
 
         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) )
-                cpu_relax();
-            for ( i = 0; i < port->tx_fifo_size; i++ )
-                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
+            if ( port->tx_log_everything )
+            {
+                /* Buffer is full: we spin waiting for space to appear. */
+                int i;
+                while ( !port->driver->tx_empty(port) )
+                    cpu_relax();
+                for ( i = 0; i < port->tx_fifo_size; i++ )
+                    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 chars until buffer is half empty. */
+                port->tx_quench = 1;
+            }
             return;
         }
 
@@ -388,6 +392,37 @@ void serial_end_sync(int handle)
     spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
+void serial_start_log_everything(int handle)
+{
+    struct serial_port *port;
+    unsigned long flags;
+
+    if ( handle == -1 )
+        return;
+    
+    port = &com[handle & SERHND_IDX];
+
+    spin_lock_irqsave(&port->tx_lock, flags);
+    port->tx_log_everything++;
+    port->tx_quench = 0;
+    spin_unlock_irqrestore(&port->tx_lock, flags);
+}
+
+void serial_end_log_everything(int handle)
+{
+    struct serial_port *port;
+    unsigned long flags;
+
+    if ( handle == -1 )
+        return;
+    
+    port = &com[handle & SERHND_IDX];
+
+    spin_lock_irqsave(&port->tx_lock, flags);
+    port->tx_log_everything--;
+    spin_unlock_irqrestore(&port->tx_lock, flags);
+}
+
 int serial_tx_space(int handle)
 {
     struct serial_port *port;
index f5e8be9815dad96643f52ebe3c7a749711c7e5bc..5817f74958a1e6fadd6e974cae61cd7fc170e83a 100644 (file)
@@ -26,6 +26,9 @@ 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 b926672dfc60f86a9e649816c6c79b12eb59e824..91fd30bcec3447388601f25d3b2ba01cce88380c 100644 (file)
@@ -33,6 +33,7 @@ struct serial_port {
     char               *txbuf;
     unsigned int        txbufp, txbufc;
     bool_t              tx_quench;
+    int                 tx_log_everything;
     /* Force synchronous transmit. */
     int                 sync;
     /* Receiver callback functions (asynchronous receivers). */
@@ -97,6 +98,10 @@ void serial_force_unlock(int handle);
 void serial_start_sync(int handle);
 void serial_end_sync(int handle);
 
+/* Start/end a region where we will wait rather than drop characters. */
+void serial_start_log_everything(int handle);
+void serial_end_log_everything(int handle);
+
 /* Return number of bytes headroom in transmit buffer. */
 int serial_tx_space(int handle);