tty: stop using "delayed_work" in the tty layer
Using delayed-work for tty flip buffers ends up causing us to wait for
the next tick to complete some actions. That's usually not all that
noticeable, but for certain latency-critical workloads it ends up being
totally unacceptable.
As an extreme case of this, passing a token back-and-forth over a pty
will take two ticks per iteration, so even just a thousand iterations
will take 8 seconds assuming a common 250Hz configuration.
Avoiding the whole delayed work issue brings that ping-pong test-case
down to 0.009s on my machine.
In more practical terms, this latency has been a performance problem for
things like dive computer simulators (simulating the serial interface
using the ptys) and for other environments (Alan mentions a CP/M emulator).
Reported-by: Jef Driesen <jefdriesen@telenet.be>
Acked-by: Greg KH <gregkh@suse.de>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 0fc564a..e19e136 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -529,7 +529,7 @@
static int tty_ldisc_halt(struct tty_struct *tty)
{
clear_bit(TTY_LDISC, &tty->flags);
- return cancel_delayed_work_sync(&tty->buf.work);
+ return cancel_work_sync(&tty->buf.work);
}
/**
@@ -542,7 +542,7 @@
{
flush_work_sync(&tty->hangup_work);
flush_work_sync(&tty->SAK_work);
- flush_delayed_work_sync(&tty->buf.work);
+ flush_work_sync(&tty->buf.work);
}
/**
@@ -722,9 +722,9 @@
/* Restart the work queue in case no characters kick it off. Safe if
already running */
if (work)
- schedule_delayed_work(&tty->buf.work, 1);
+ schedule_work(&tty->buf.work);
if (o_work)
- schedule_delayed_work(&o_tty->buf.work, 1);
+ schedule_work(&o_tty->buf.work);
mutex_unlock(&tty->ldisc_mutex);
tty_unlock();
return retval;
@@ -830,12 +830,12 @@
/*
* this is like tty_ldisc_halt, but we need to give up
- * the BTM before calling cancel_delayed_work_sync,
- * which may need to wait for another function taking the BTM
+ * the BTM before calling cancel_work_sync, which may
+ * need to wait for another function taking the BTM
*/
clear_bit(TTY_LDISC, &tty->flags);
tty_unlock();
- cancel_delayed_work_sync(&tty->buf.work);
+ cancel_work_sync(&tty->buf.work);
mutex_unlock(&tty->ldisc_mutex);
tty_lock();