低延迟模式可安全用于Linux串行端口吗? [英] Is low latency mode safe to use with Linux serial ports?

查看:174
本文介绍了低延迟模式可安全用于Linux串行端口吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux串行端口上使用low_latency tty模式是否安全? tty_flip_buffer_push 函数记录为必须如果设置了port-> low_latency,则不会从IRQ上下文中调用它."但是,无论是否设置了标志,许多低级串行端口驱动程序都从ISR调用它.例如, mpc52xx驱动程序调用翻转缓冲区每次从其FIFO读取后无条件.

Is it safe to use the low_latency tty mode with Linux serial ports? The tty_flip_buffer_push function is documented that it "must not be called from IRQ context if port->low_latency is set." Nevertheless, many low-level serial port drivers call it from an ISR whether or not the flag is set. For example, the mpc52xx driver calls flip buffer unconditionally after each read from its FIFO.

ISR中低延迟翻转缓冲区的结果是在IRQ上下文中输入了行规驱动程序.我的目标是从高速mpc52xx串行端口读取数据,从而获得1毫秒或更短的延迟.设置low_latency可以达到延迟目标,但它也违反了tty_flip_buffer_push的已记录前提条件.

A consequence of the low latency flip buffer in the ISR is that the line discipline driver is entered within the IRQ context. My goal is to get latency of one millisecond or less, reading from a high speed mpc52xx serial port. Setting low_latency acheives the latency goal, but it also violates the documented precondition for tty_flip_buffer_push.

推荐答案

2011年8月19日,星期五的linux-serial .

不,低延迟通常并不安全.

No, low latency is not safe in general.

但是,在3.10.5的特定情况下,low_latency是安全的.

However, in the particular case of 3.10.5 low_latency is safe.

tty_flip_buffer_push上方的注释为:

如果设置了port-> low_latency,则不得从IRQ上下文中调用此函数."

"This function must not be called from IRQ context if port->low_latency is set."

但是,代码(3.10.5,drivers/tty/tty_buffer.c)与此矛盾:

However, the code (3.10.5, drivers/tty/tty_buffer.c) contradicts this:

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可使从中断上下文安全地调用此代码.

The use of spin_lock_irqsave/spin_unlock_irqrestore makes this code safe to call from interrupt context.

有一个针对low_latency的测试,如果已设置,则直接调用flush_to_ldisc.这会立即将翻转缓冲区刷新到行规则中,但代价是使中断处理时间更长. flush_to_ldisc例程也经过编码,可以安全地在中断上下文中使用.我认为较早的版本是不安全的.

There is a test for low_latency and if it is set, flush_to_ldisc is called directly. This flushes the flip buffer to the line discipline immediately, at the cost of making the interrupt processing longer. The flush_to_ldisc routine is also coded to be safe for use in interrupt context. I guess that an earlier version was unsafe.

如果未设置low_latency,则调用schedule_work.调用schedule_work是在中断上下文中从上半部分"调用下半部分"处理程序的经典方法.这将导致在下一个时钟滴答时从下半部"处理程序调用flush_to_ldisc.

If low_latency is not set, then schedule_work is called. Calling schedule_work is the classic way to invoke the "bottom half" handler from the "top half" in interrupt context. This causes flush_to_ldisc to be called from the "bottom half" handler at the next clock tick.

再深入一点,评论和测试似乎都在Alan Cox对tty_buffer.c的原始e0495736提交中.该提交是对早期代码的重新编写,因此似乎一次没有测试.谁添加了测试并将flush_to_ldisc设置为具有中断安全性的人,都不会费心去修复注释.

Looking a little deeper, both the comment and the test seem to be in Alan Cox's original e0495736 commit of tty_buffer.c. This commit was a re-write of earlier code, so it seems that at one time there wasn't a test. Whoever added the test and fixed flush_to_ldisc to be interrupt-safe did not bother to fix the comment.

因此,请始终相信代码,而不是注释.

So, always believe the code, not the comments.

但是,在3.12-rc *(截至2013年10月23日)的同一代码中,当删除flush_to_ldisc中的spin_lock_irqsave并添加了互斥锁时,似乎再次打开了问题.也就是说,在serial_struct标志中设置UPF_LOW_LATENCY并调用TIOCSSERIAL ioctl将再次导致原子调度".

However, in the same code in 3.12-rc* (as of October 23, 2013) it looks like the problem was opened again when the spin_lock_irqsave's in flush_to_ldisc were removed and mutex_locks were added. That is, setting UPF_LOW_LATENCY in the serial_struct flags and calling the TIOCSSERIAL ioctl will again cause "scheduling while atomic".

维护者的最新更新是:

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

因此,除非您确定永远不会从支持它的版本更改内核,否则您似乎不应该依赖low_latency.

So, it looks like you should not depend on low_latency unless you are sure that you are never going to change your kernel from a version that supports it.

更新:2014年2月18日,内核3.13.2

Stanislaw Gruszka写道:

Stanislaw Gruszka wrote:

Hi,

setserial has low_latency option which should minimize receive latency
(scheduler delay). AFAICT it is used if someone talk to external device
via RS-485/RS-232 and need to have quick requests and responses . On
kernel this feature was implemented by direct tty processing from
interrupt context:

void tty_flip_buffer_push(struct tty_port *port)
{
    struct tty_bufhead *buf = &port->buf;

    buf->tail->commit = buf->tail->used;

    if (port->low_latency)
            flush_to_ldisc(&buf->work);
    else
            schedule_work(&buf->work);
} 

But after 3.12 tty locking changes, calling flush_to_ldisc() from
interrupt context is a bug (we got scheduling while atomic bug report
here: https://bugzilla.redhat.com/show_bug.cgi?id=1065087 )

I'm not sure how this should be solved. After Peter get rid all of those
race condition in tty layer, we probably don't want go back to use
spin_lock's there. Maybe we can create WQ_HIGHPRI workqueue and schedule
flush_to_ldisc() work there. Or perhaps users that need to low latency,
should switch to thread irq and prioritize serial irq to meat
retirements. Anyway setserial low_latency is now broken and all who use
this feature in the past can not do this any longer on 3.12+ kernels.

Thoughts ?

Stanislaw

这篇关于低延迟模式可安全用于Linux串行端口吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆