对Linux串口使用low_latency tty模式是否安全? tty_flip_buffer_push函数被记录为“如果设置了port-> low_latency,则不能从IRQ上下文调用它”。然而,无论标志是否设置,许多低级串行端口驱动程序都会从ISR调用它。例如,每次从FIFO读取后无条件地mpc52xx driver calls flip buffer。
ISR中低延迟翻转缓冲区的结果是在IRQ上下文中输入了线路规则驱动程序。我的目标是从高速mpc52xx串口读取延迟一毫秒或更短。设置low_latency可以实现延迟目标,但它也违反了tty_flip_buffer_push记录的前提条件。
答案 0 :(得分:3)
linux-serial on Fri, 19 Aug 2011上提出了这个问题。
不,低延迟一般不安全。
但是,在3.10.5的特定情况下low_latency
是安全的。
以上评论tty_flip_buffer_push
读取:
“如果设置了port-> low_latency,则不能从IRQ上下文调用此函数。”
但是,代码(3.10.5,drivers / tty / tty_buffer.c)与此相矛盾:
void tty_flip_buffer_push(struct tty_port *port)
{
struct tty_bufhead *buf = &port->buf;
unsigned long flags;
spin_lock_irqsave(&buf->lock, flags);
if (buf->tail != NULL)
buf->tail->commit = buf->tail->used;
spin_unlock_irqrestore(&buf->lock, flags);
if (port->low_latency)
flush_to_ldisc(&buf->work);
else
schedule_work(&buf->work);
}
EXPORT_SYMBOL(tty_flip_buffer_push);
使用spin_lock_irqsave
/ spin_unlock_irqrestore
可以安全地从中断上下文调用此代码。
low_latency
有一个测试,如果已设置,则直接调用flush_to_ldisc
。这会立即将翻转缓冲区刷新到线路规则,代价是中断处理时间更长。 flush_to_ldisc
例程也被编码为在中断上下文中使用是安全的。我想早期版本不安全。
如果low_latency
未设置,则会调用schedule_work
。调用schedule_work
是在中断上下文中从“上半部分”调用“下半部分”处理程序的经典方法。这会导致在下一个时钟周期从“下半部分”处理程序调用{{1}}。
更深入一点,评论和测试似乎都在Alan Cox的flush_to_ldisc
e0495736
提交中。这个提交是对早期代码的重写,所以似乎有一次没有测试。无论是谁添加了测试并将tty_buffer.c
修复为中断安全的,都无需修复评论。
所以,始终相信代码,而不是评论。
然而,在3.12-rc *(截至2013年10月23日)的相同代码中,当flush_to_ldisc中的spin_lock_irqsave被删除并添加了mutex_locks时,看起来问题再次被打开。也就是说,在serial_struct标志中设置UPF_LOW_LATENCY并调用TIOCSSERIAL ioctl将再次导致“原子调度”。
维护者的最新更新是:
flush_to_ldisc
因此,看起来您不应该依赖On 10/19/2013 07:16 PM, Jonathan Ben Avraham wrote:
> Hi Peter,
> "tty_flip_buffer_push" is called from IRQ handlers in most drivers/tty/serial UART drivers.
>
> "tty_flip_buffer_push" calls "flush_to_ldisc" if low_latency is set.
> "flush_to_ldisc" calls "mutex_lock" in 3.12-rc5, which cannot be used in interrupt context.
>
> Does this mean that setting "low_latency" cannot be used safely in 3.12-rc5?
Yes, I broke low_latency.
Part of the problem is that the 3.11- use of low_latency was unsafe; too many shared
data areas were simply accessed without appropriate safeguards.
I'm working on fixing it but probably won't make it for 3.12 final.
Regards,
Peter Hurley
,除非您确定永远不会从支持它的版本更改内核。
更新:2014年2月18日,内核3.13.2
Stanislaw Gruszka写道:
low_latency
答案 1 :(得分:1)
已将贴片发布到LKML以解决此问题。它删除了处理low_latency的通用代码,但保留了低级驱动程序的参数。
http://www.kernelhub.org/?p=2&msg=419071
我尝试使用串行控制台在Linux 3.12上强制执行low_latency。内核非常不稳定。如果启用了抢占,则在使用几分钟后它将挂起。
所以现在的答案就是远离它。