mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
Bring back console_start_log_everything() as a milder alternative to
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>
This commit is contained in:
1 parent
8b53284ae7
commit
2754857001
5 files changed
+77
-17
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
+48
-13
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||