Multithreading 关于请求\u线程\u irq行为的澄清
我在网上搜索了一下,但对于一些与“请求线程化”功能相关的问题,还没有找到令人信服的答案 问题1: 首先,我在读这篇关于线程IRQ的文章: 有一句话我不清楚: “只有当处理程序 代码通过集成tasklet/softirq来利用它 功能和简化锁定。” 我知道如果我们采用“传统”的上半部分/下半部分方法,我们可能需要自旋锁或禁用本地IRQ来处理共享数据。但是,我不明白的是,线程中断如何通过集成tasklet/softirq功能来简化锁定需求 问题2: 其次,与基于工作队列的下半部分方法相比,请求线程处理方法有什么优势(如果有的话)?在这两种情况下,似乎“工作”被推迟到一个专用线程。那么,有什么区别呢 问题3: 最后,在以下原型中:Multithreading 关于请求\u线程\u irq行为的澄清,multithreading,linux-kernel,linux-device-driver,Multithreading,Linux Kernel,Linux Device Driver,我在网上搜索了一下,但对于一些与“请求线程化”功能相关的问题,还没有找到令人信服的答案 问题1: 首先,我在读这篇关于线程IRQ的文章: 有一句话我不清楚: “只有当处理程序 代码通过集成tasklet/softirq来利用它 功能和简化锁定。” 我知道如果我们采用“传统”的上半部分/下半部分方法,我们可能需要自旋锁或禁用本地IRQ来处理共享数据。但是,我不明白的是,线程中断如何通过集成tasklet/softirq功能来简化锁定需求 问题2: 其次,与基于工作队列的下半部分方法相比,请求线程
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)
即使中断处理程序的“线程”部分(将rx字节写入循环缓冲区)正忙于处理来自先前唤醒的IRQ,IRQ的“处理程序”部分是否可能由相关IRQ(比如UART以高速率接收字符)连续触发?那么,处理程序是否会试图“唤醒”已经运行的“线程”_fn?在这种情况下,正在运行的irq线程将如何运行
如果有人能帮我理解这一点,我将不胜感激
谢谢,
vj
任务
,仍然是。唯一的区别是中断被禁用。tasklet或softirq允许驱动程序的ISR线程和用户API之间存在不同的互锁(ioctl()
,read()
,和write()
)工作队列
几乎相当。但是,tasklet/ksoftirq具有较高的优先级,并由该处理器上所有基于ISR的功能使用。这可能会提供更好的调度机会。此外,驾驶员需要管理的资源更少;所有内容都已内置到内核的ISR处理程序代码中kfifo
。处理程序应该是贪婪的,在返回IRQ\u WAKE\u线程之前从UART获取所有数据
kernel/irq/manage.c
中,您将看到一些类似以下的代码,用于为线程化irq创建内核线程:
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, ¶m);
在这里可以看到,内核线程的调度策略设置为RT one(SCHED_FIFO
),线程的优先级设置为MAX_USER\u RT_PRIO/2
,高于常规进程
关于问题3,
您描述的情况也可能发生在正常中断时。通常在内核中,执行ISR时会禁用中断。在执行ISR期间,字符可以不断填充设备的缓冲区,即使中断被禁用,设备也可以并且必须继续断言中断
设备的任务是确保IRQ行保持断言状态,直到所有字符被读取,并且ISR完成任何处理。同样重要的是,中断是电平触发的,或者取决于中断控制器锁定的设计
最后,设备/外围设备应具有适当大小的FIFO,以便高速传输的字符不会因慢速ISR而丢失。ISR还应设计为在执行时读取尽可能多的字符
一般来说,我所看到的是,控制器会有一个特定大小的FIFO
X
,当FIFO充满X/2
,它会触发一个中断,使ISR尽可能多地获取数据。ISR读取尽可能多的数据,然后清除中断。同时,如果FIFO仍然是X/2
,设备将保持中断线的断言,导致ISR再次执行。最初将“硬”/“软”处理程序转换为线程处理程序的工作是由Thomas Gleixner&team在构建(也称Linux为RTOS)项目时完成的(它不是主线的一部分)。
要真正让Linux作为RTOS运行,我们不能容忍中断处理程序中断最关键的rt(应用程序)线程的情况;但我们如何确保应用程序线程甚至覆盖中断??通过使其(中断)线程化、可调度(SCHED_FIFO),并具有比应用程序线程更低的优先级(中断线程rtprio默认为50)。因此,rtprio为60的“rt”SCHED_FIFO应用程序线程甚至可以“抢占”中断线程。这应该能回答你的问题。二,
对Qs 3的说明:
正如其他人所说,您的代码必须处理这种情况。
话虽如此,pl注意到使用线程处理程序的一个关键点是,您可以(可能)执行阻塞(休眠)的工作。如果您的“下半部分”工作保证是非阻塞的并且必须是快速的,则pl使用传统风格的“上半部分/bh”处理程序。
我们怎么能做到呢?简单:不要使用request\u-threaded\u-irq(),只需调用request\u-irq()-代码中的注释清楚地说明(wrt第三个参数):
或者,您可以将IRQF_NO_线程标志传递给request_irq
(顺便说一句,在3.14.23 k上与cscope进行快速检查
* @thread_fn: Function called from the irq handler thread
* If NULL, no irq thread is created"