Skip to contentSkip to conversation

tty: Abstract tty buffer work

PATCH In review Peter Hurley 2 participants 3 messages Oct 17, 2015 – Oct 18, 2015 TTY layer and serial drivers

lore
Share & tools
lore
#0 lore raw

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
index fb8ccbf..1384426 100644
@@ -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
index a660ab1..7cc16db 100644
@@ -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
index 173fdeb..0c41dbc 100644
@@ -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
index e04a8cf..482f33f 100644
@@ -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
index 533d7f6..5b04b0a 100644
@@ -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
#1 lore raw

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
index 7cc16db..9a479e6 100644
@@ -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
#2 lore raw

Re: [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