I have a device driver where the hardware is constantly streaming data into a circular buffer in kernel space. When the user calls read()
, data is moved from this buffer to the caller's buffer. An interrupt fires if the hardware fills a DMA descriptor (i.e., more data is ready) or if the hardware encountered an error. In either case, the interrupt handler schedules work to be done in the bottom half.
The bottom half figures out if the interrupt was caused by a hardware failure or data becoming available. In either case it sets some flags to let the read()
syscall know what happened. After setting said flags, the bottom half calls wake_up_interruptible(&my_waitqueue);
In the read()
syscall, I want to block for some timeout if there is not data available in the kernel buffer. If the timeout expires, I just let the caller know that data isn't available. As a result, I call wait_event_interruptible_hrtimeout(my_waitqueue, (error || data_ready), my_timeout);
Basically, I block waiting for either an error condition or data becoming available.
My question pertains to whether or not the ordering of these threads (i.e., the bottom half and the read()
call) matters. Particularly, I am wondering if wait_event_interruptible_hrtimeout()
always waits for someone to wake it up? What if there was a previous call to wake_up_interruptible()
?
Said differently, I am concerned with the following scenario:
- Interrupt fires due to hardware failure. Remember that transfers to the circular buffer occur independently with regards to the
read()
syscall. - Bottom half runs, flags the transfer as failed and calls
wake_up_interruptible()
. Note that since this is a hardware failure, no more interrupts will fire and we won't run the bottom half again until the device is reset. - User process wants more data, and calls
read()
. We now hit the line of code containingwait_event_interruptible_hrtimeout()
. Do we block waiting to be woken up or does the wait queue know about the previous call towake_up_interruptible()
?
Basically I am wondering if I need to first check the condition I passed into wait_event_interruptible_hrtimeout()
(i.e., (error || data_ready)
) before calling wait_event_interruptible_hrtimeout()
.
wake_up_interruptible()
?" -wake_up
functions calls never affect on futher waitings. "if I need to first check the condition" - Condition is checked insidewait_event
macro even before the first attempt to wait. – Tsyvarev