Linux 等待队列...排序重要吗?

Linux wait queues... does ordering matter?

我有一个设备驱动程序,其中硬件不断地将数据流式传输到内核中的循环缓冲区 space。当用户调用 read() 时,数据从这个缓冲区移动到调用者的缓冲区。如果硬件填充 DMA 描述符(即,更多数据已准备就绪)或硬件遇到错误,则会触发中断。在任何一种情况下,中断处理程序都会安排在下半部分完成的工作。

下半部分判断中断是由硬件故障还是数据可用引起的。在任何一种情况下,它都会设置一些标志,让 read() 系统调用知道发生了什么。设置所述标志后,下半部分调用 wake_up_interruptible(&my_waitqueue);

read() 系统调用中,如果内核缓冲区中没有可用数据,我想阻塞一段时间。如果超时到期,我只是让调用者知道数据不可用。因此,我调用 wait_event_interruptible_hrtimeout(my_waitqueue, (error || data_ready), my_timeout); 基本上,我阻止等待错误条件或数据可用。

我的问题是这些线程的顺序(即下半部分和 read() 调用)是否重要。特别是,我想知道 wait_event_interruptible_hrtimeout() 是否总是等待有人唤醒它?如果之前调用过 wake_up_interruptible() 怎么办?

换句话说,我关注以下场景:

  1. 由于硬件故障中断触发。请记住,关于 read() 系统调用,向循环缓冲区的传输是独立发生的。
  2. 下半部分 运行s,将传输标记为失败并调用 wake_up_interruptible()。请注意,由于这是硬件故障,因此不会触发更多中断,并且在设备重置之前我们不会 运行 再次进入下半部分。
  3. 用户进程需要更多数据,并调用 read()。我们现在点击包含 wait_event_interruptible_hrtimeout() 的代码行。我们是阻塞等待被唤醒还是等待队列知道之前对 wake_up_interruptible() 的调用?

基本上我想知道在调用 wait_event_interruptible_hrtimeout().

之前是否需要先检查我传递给 wait_event_interruptible_hrtimeout() 的条件(即 (error || data_ready)

感谢 Tsyvarev,我决定多研究一下内核源代码。

这是我发现的:

#define wait_event_interruptible_hrtimeout(wq, condition, timeout)  \
({                                                                  \
    long __ret = 0;                                                 \
    might_sleep();                                                  \
    if (!(condition))                                               \
        __ret = __wait_event_hrtimeout(wq, condition, timeout,      \
                                       TASK_INTERRUPTIBLE);         \
    __ret;                                                          \
})

首先检查条件,这意味着如果我获取数据或发生硬件故障,我不会阻塞,因为这是我传递给此函数的条件。