When low_latency flag is set the TTY receive flip buffer is copied to the line discipline directly instead of using a work queue in the background. Therefor only in case a workqueue is actually used for copying data to the line discipline we'll have to flush the workqueue. This prevents unnecessary spin lock/unlock on the workqueue spin lock that can cause additional scheduling overhead on a PREEMPT_RT system. On a 200 MHz AT91SAM9261 processor setup this fixes about 100us of scheduling overhead on the TTY read call. Signed-off-by: Ivo Sieben <meltedpianoman@xxxxxxxxx> --- v3: Prevented the flush the easy way: workque is not flused when low latency flag is set. This means that drivers that use the tty_schedule_flip() functions instead of the tty_flip_buffer_push() should never have the low_latency flag set, otherwise the workqueue won't be flushed. Added a WARN_ON() to detect those drivers. For PREEMPT_RT systems: this optimization will only work when the user has actually enabled the ASYNC_LOW_LATENCY option for the serial driver, otherwise the workqueue will still be flushed although it is not used since the PREMPT_RT patch makes the tty_flip_buffer_push() function to always bypass the workqueue. drivers/tty/tty_buffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 6146e8b..b952de1 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -342,6 +342,8 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); * Takes any pending buffers and transfers their ownership to the * ldisc side of the queue. It then schedules those characters for * processing by the line discipline. + * Note that this function can only be used when the low_latency flag + * is unset. Otherwise the workqueue won't be flushed. * * Locking: Takes tty->buf.lock */ @@ -349,6 +351,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); void tty_schedule_flip(struct tty_struct *tty) { unsigned long flags; + WARN_ON(tty->low_latency); spin_lock_irqsave(&tty->buf.lock, flags); if (tty->buf.tail != NULL) tty->buf.tail->commit = tty->buf.tail->used; @@ -514,7 +517,8 @@ static void flush_to_ldisc(struct work_struct *work) */ void tty_flush_to_ldisc(struct tty_struct *tty) { - flush_work(&tty->buf.work); + if (!tty->low_latency) + flush_work(&tty->buf.work); } /** -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html