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()
怎么办?
换句话说,我关注以下场景:
- 由于硬件故障中断触发。请记住,关于
read()
系统调用,向循环缓冲区的传输是独立发生的。
- 下半部分 运行s,将传输标记为失败并调用
wake_up_interruptible()
。请注意,由于这是硬件故障,因此不会触发更多中断,并且在设备重置之前我们不会 运行 再次进入下半部分。
- 用户进程需要更多数据,并调用
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; \
})
首先检查条件,这意味着如果我获取数据或发生硬件故障,我不会阻塞,因为这是我传递给此函数的条件。
我有一个设备驱动程序,其中硬件不断地将数据流式传输到内核中的循环缓冲区 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()
怎么办?
换句话说,我关注以下场景:
- 由于硬件故障中断触发。请记住,关于
read()
系统调用,向循环缓冲区的传输是独立发生的。 - 下半部分 运行s,将传输标记为失败并调用
wake_up_interruptible()
。请注意,由于这是硬件故障,因此不会触发更多中断,并且在设备重置之前我们不会 运行 再次进入下半部分。 - 用户进程需要更多数据,并调用
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; \
})
首先检查条件,这意味着如果我获取数据或发生硬件故障,我不会阻塞,因为这是我传递给此函数的条件。