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

时间:2018-10-25 01:46:35

标签: c linux-kernel linux-device-driver

我有一个设备驱动程序,硬件在其中不断将数据流传输到内核空间中的循环缓冲区中。当用户调用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. 下半部分运行,将传输标记为失败并调用wake_up_interruptible()。请注意,由于这是硬件故障,因此不会再触发任何中断,并且在重置设备之前,我们不会再次运行下半部分。
  3. 用户进程需要更多数据,并调用read()。现在,我们进入包含wait_event_interruptible_hrtimeout()的代码行。是阻止我们唤醒等待的等待,还是等待队列知道上一次对wake_up_interruptible()的调用?

基本上,我想知道是否需要在调用wait_event_interruptible_hrtimeout()之前先检查传递给(error || data_ready)(即wait_event_interruptible_hrtimeout())的条件。

1 个答案:

答案 0 :(得分:0)

由于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;                                                          \
})

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