Messages in this thread | | | Date | Thu, 8 Mar 2007 19:24:10 -0800 | From | "Luong Ngo" <> | Subject | Re: Sleeping thread not receive signal until it wakes up |
| |
On 3/8/07, Robert Hancock <hancockr@shaw.ca> wrote: > Luong Ngo wrote: > > Hi Thomas and Dick, > > I appreciate all the responses. They are very good information to me. > > Actually, it wasn't me working on the driver but it's been there long > > time. I thought I just need to add the signal and signal handling > > part, not expecting it would lead me to the driver space. > > Here is what I have in the driver. Maybe racing condition could happen > > in scenario that the ioctl realease the lock but befor going to sleep, > > the ISR is invoked and call waking up on the queue, hence the ioctl > > will not be waken up since the wak up cal already executed. But I > > believe in our system, this could be tolerant since the hardware would > > keep raising interrupt if the abnormal condition still exists (Due to > > the ioctl being blocked so user app nevers get a chance to service the > > device). But is this the reason why my signal handler not get executed > > at all? Theoretically, according to the Richard Stevens book, I think > > the process should be waken up and received the signal even if it gets > > blocked in the IOCTL call, am i right? > > .. > > > static int ats89_ioctl(struct inode *inode, struct file *file, u_int > > cmd, u_long arg) > > { > > > > switch(cmd){ > > case GET_IRQ_CMD: { > > u32 regMask32; > > > > spin_lock_irq(dev->lock); > > while ((dev->irqMask & dev->irqEvent) == 0) { > > // Sleep until board interrupt happens > > spin_unlock_irq(dev->lock); > > interruptible_sleep_on(&(dev->boardIRQWaitQueue)); > > if (uncond_wakeup) { > > /* don't go back to loop */ > > break; > > } > > spin_lock_irq(dev->lock); > > } > > Kernel code does not get pre-empted by signals. If the code needs to be > interruptible by signals this has to be handled explicitly. > interruptible_sleep on will stop waiting if your task gets a signal, but > your code doesn't check the signal_pending flag to know whether it > should exit the loop. If signal_pending(current) is set after the sleep > you should likely be returning -ERESTARTSYS to allow the task to handle > the signal. Then after the signal handler from the task returns, the > ioctl will get called again. > > Also, as was pointed out, you should not use the sleep_on family of > functions, use the wait_event functions intead. sleep_on is racy, if the > interrupt happened just before you do the sleep, you'll sit there > waiting for something that already occurred. > > -- > Robert Hancock Saskatoon, SK, Canada > To email, remove "nospam" from hancockr@nospamshaw.ca > Home Page: http://www.roberthancock.com/ > > Robert, thanks a lot for your suggestion But I have added the signal_pending(current) check and signal handler is not invoked
spin_lock_irq(dev->lock); while ((dev->irqMask & dev->irqEvent) == 0) { // Sleep until board interrupt happens spin_unlock_irq(dev->lock); interruptible_sleep_on(&(dev->boardIRQWaitQueue));
if(signal_pending(current) { return -ERESTARTSYS; }
if (uncond_wakeup) { /* don't go back to loop */ break; } spin_lock_irq(dev->lock); } Still no luck yet. LNgo - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |