澄清request_threaded_irq的行为(Clarification about the

2019-08-17 19:03发布

我已经冲刷网页,但还没有找到令人信服的答案一对夫妇的我有相关的问题,相对于“request_threaded_irq”功能。

问题1:首先,我正在读这篇文章,关于螺纹IRQ的:

http://lwn.net/Articles/302043/

并有这一行是我不太清楚:

“转换一个中断给螺纹使得仅感当处理程序代码利用了它通过集成微进程/软中断功能和简化了锁定”。

我明白了,我们有一个“传统”,上半部/下半部分的方式提前走了,我们会需要或者自旋锁或禁用本地IRQ共享数据染指。 但是,我不明白的是,如何将线程中断简化通过整合任务蕾/软中断功能锁定的需要。

问题2:其次,有什么优势(如果有的话),做了request_threaded_handler方法已经在work_queue基于下半部的方法呢? 在这两种情况下,似乎,好像“工作”被推迟到一个专用的线程。 那么区别是什么呢 ?

问题3:最后,在下面的原型:

int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long irqflags, const char *devname, void *dev_id)

是否有可能的IRQ的“处理程序”部分继续由相关的IRQ触发(比如一个UART高速率receving字符),即使在“thread_fn”(写rx'd字节循环缓冲器)的一部分中断处理程序正在处理的IRQ从以前的唤醒? 所以,不会处理程序是试图“唤醒”一个已经运行的“thread_fn”? 将如何运行的IRQ thread_fn在这种情况下表现?

我真的很感激,如果有人可以帮助我理解这一点。

谢谢,VJ

Answer 1:

  1. 此前,下半部不是一个task ,仍然无法阻挡 。 唯一的区别是,中断被禁用。 该任务蕾软中断允许驾驶员的ISR线程和用户之间的API不同相互锁( ioctl() read()write()
  2. 我觉得work queue是接近相等。 然而, 微进程/ ksoftirq具有高优先级,并且用于由该处理器上的所有ISR基于功能。 这可能会提供更好的调度机会。 此外,有较少的驱动程序管理; 一切都已经内置到内核的ISR处理程序代码。
  3. 你必须处理这个问题。 通常乒乓缓冲器可用于或kfifo像你这样的建议。 该handler应该是贪婪并在返回之前得到来自UART的所有数据IRQ_WAKE_THREAD


Answer 2:

对于问题没有图3,当一个threadedirq被激活相应的中断线路被屏蔽/禁用。 在threadedirq运行和完成时它使它朝着它的结束。 因此,有关的threadedirq运行时不会有任何中断射击。



Answer 3:

For Question 2, An IRQ thread on creation is setup with a higher priority, unlike workqueues. In kernel/irq/manage.c, you'll see some code like the following for creation of kernel threads for threaded IRQs:

            static const struct sched_param param = {
                    .sched_priority = MAX_USER_RT_PRIO/2,
            };


            t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
                               new->name);
            if (IS_ERR(t)) {
                    ret = PTR_ERR(t);
                    goto out_mput;
            }

            sched_setscheduler_nocheck(t, SCHED_FIFO, &param);

Here you can see, the scheduling policy of the kernel thread is set to an RT one (SCHED_FIFO) and the priority of the thread is set to MAX_USER_RT_PRIO/2 which is higher than regular processes.

For Question 3, The situation you described can also occur with normal interrupts. Typically in the kernel, interrupts are disabled while an ISR executes. During the execution of the ISR, characters can keep filling the device's buffer and the device can and must continue to assert an interrupt even while interrupts are disabled.

It is the job of the device to make sure the IRQ line is kept asserted till all the characters are read and any processing is complete by the ISR. It is also important that the interrupt is level triggered, or depending on the design be latched by the interrupt controller.

Lastly, the device/peripheral should have an adequately sized FIFO so that characters delivered at a high rate are not lost by a slow ISR. The ISR should also be designed to read as many characters as possible when it executes.

Generally speaking what I've seen is, a controller would have a FIFO of a certain size X, and when the FIFO is filled X/2, it would fire an interrupt that would cause the ISR to grab as much data as possible. The ISR reads as much as possible and then clears the interrupt. Meanwhile, if the FIFO is still X/2, the device would keep the interrupt line asserted causing the ISR to execute again.



Answer 4:

将“硬” /“软”处理程序处理线程的原创作品是由托马斯Gleixner及建立团队时做PREEMPT_RT的Linux (又名Linux的AS-AN-RTOS)项目(这不是主线的一部分)。 为了真正拥有Linux上运行作为一个RTOS,我们无法容忍的地方中断处理程序中断最关键的RT(应用)线程的情况; 但如何才能保证应用程序的线程甚至会覆盖中断? 通过使(中断)螺纹,调度(SCHED_FIFO)和具有比所述的应用程序的线程优先级较低(中断线程rtprio默认为50)。 因此,与60 rtprio一个“RT” SCHED_FIFO线程的应用程序将能够“抢占”,甚至中断线程(不够密切,它的作品)。 这应该回答你Qs的。 2。

WRT与QS 3:正如其他人所说,你的代码必须处理这种情况。 话虽如此,PL注意的一个关键点,以利用螺纹处理程序是这样,你可以做的工作,(可能)块(睡觉)。 如果你的“下半部分”的工作是保证无阻塞一定要快,PL使用传统风格的顶级半/ BH“的处理程序。 我们怎样才能做到这一点? 很简单:不使用request_threaded_irq()只需要调用的request_irq() - 在代码中的注释清楚地说(WRT第三个参数):

* @thread_fn: Function called from the irq handler thread
*          If NULL, no irq thread is created"

另外,您也可以通过IRQF_NO_THREAD标志给request_irq。

(顺便说一句,快速检查与在23年3月14日内核源代码树的cscope显示的request_irq()被调用1502次[给我们非线程中断处理]和request_threaded_irq()[ 线程中断]显式调用204次)。



文章来源: Clarification about the behaviour of request_threaded_irq