tty: Abstract tty buffer work
PATCH 1/2 tty: Abstract tty buffer work
Introduce API functions to restart and cancel tty buffer work, rather than manipulate buffer work directly.
--- drivers/tty/n_tty.c | 2 +- drivers/tty/tty_buffer.c | 10 ++++++++++ drivers/tty/tty_io.c | 2 +- drivers/tty/tty_port.c | 2 +- include/linux/tty.h | 2 ++ 5 files changed, 15 insertions(+), 3 deletions(-)
drivers/tty/n_tty.c +1 -1
@@ -201,7 +201,7 @@ static void n_tty_kick_worker(struct tty_struct *tty)*/ WARN_RATELIMIT (test_bit (TTY_LDISC_HALTED , &tty->flags),"scheduling buffer work for halted ldisc\n" ); -queue_work (system_unbound_wq, &tty->port->buf.work); +tty_buffer_restart_work (tty->port); } }
drivers/tty/tty_buffer.c +10 -0
@@ -587,3 +587,13 @@ void tty_buffer_set_lock_subclass(struct tty_port *port) {lockdep_set_subclass (&port->buf.lock,TTY_LOCK_SLAVE ); } + +bool tty_buffer_restart_work (struct tty_port *port) +{ +return queue_work (system_unbound_wq, &port->buf.work); +} + +bool tty_buffer_cancel_work (struct tty_port *port) +{ +return cancel_work_sync (&port->buf.work); +}
drivers/tty/tty_io.c +1 -1
@@ -1689,7 +1689,7 @@ static void release_tty(struct tty_struct *tty, int idx) tty->port->itty =NULL ;if (tty->link) tty->link->port->itty =NULL ; -cancel_work_sync (&tty->port->buf.work); +tty_buffer_cancel_work (tty->port);tty_kref_put (tty->link);tty_kref_put (tty);
drivers/tty/tty_port.c +1 -1
@@ -130,7 +130,7 @@ EXPORT_SYMBOL(tty_port_free_xmit_buf);*/ void tty_port_destroy (struct tty_port *port) { -cancel_work_sync (&port->buf.work); +tty_buffer_cancel_work (port);tty_buffer_free_all (port); }EXPORT_SYMBOL (tty_port_destroy);
include/linux/tty.h +2 -0
@@ -467,6 +467,8 @@ extern void tty_buffer_free_all(struct tty_port *port);extern void tty_buffer_flush (struct tty_struct *tty,struct tty_ldisc *ld);extern void tty_buffer_init (struct tty_port *port);extern void tty_buffer_set_lock_subclass (struct tty_port *port); +extern bool tty_buffer_restart_work (struct tty_port *port); +extern bool tty_buffer_cancel_work (struct tty_port *port);extern speed_t tty_termios_baud_rate (struct ktermios *termios);extern speed_t tty_termios_input_baud_rate (struct ktermios *termios); extern void tty_termios_encode_baud_rate(struct ktermios *termios,
Signature · 1 line
2.6.1
PATCH 2/2 tty: Use unbound workqueue for all input workers
The commonly accepted wisdom that scheduling work on the same cpu that handled interrupt i/o benefits from cache-locality is only true if the cpu is idle (since bound kworkers are often the highest vruntime and thus the lowest priority).
Measurements of scheduling via the unbound queue show lowered worst-case latency responses of up to 5x over bound workqueue, without increase in average latency or throughput.
pty i/o test measurements show >3x (!) reduced total running time; tests previously taking ~8s now complete in <2.5s.
--- drivers/tty/tty_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/tty_buffer.c +1 -1
@@ -403,7 +403,7 @@ void tty_schedule_flip(struct tty_port *port)* flush_to_ldisc() sees buffer data. */ smp_store_release (&buf->tail->commit, buf->tail->used); -schedule_work (&buf->work); +queue_work (system_unbound_wq, &buf->work); }EXPORT_SYMBOL (tty_schedule_flip);
Signature · 1 line
2.6.1
Greg Kroah-Hartman
maintainerRe: [PATCH 2/2] tty: Use unbound workqueue for all input workers
Quoted 11 lines · Peter Hurley
The commonly accepted wisdom that scheduling work on the same cpu that handled interrupt i/o benefits from cache-locality is only true if the cpu is idle (since bound kworkers are often the highest vruntime and thus the lowest priority).
Measurements of scheduling via the unbound queue show lowered worst-case latency responses of up to 5x over bound workqueue, without increase in average latency or throughput.
pty i/o test measurements show >3x (!) reduced total running time; tests previously taking ~8s now complete in <2.5s.
Wow, nice job with this, that's unexpected.
greg k-h