Messages in this thread |  | | Date | Thu, 28 Sep 2000 18:32:43 -0700 | From | Matthew Dharm <> | Subject | Re: Interrupt/Sleep deadlock |
| |
Heh.. I needed to figure this out about 6 months ago. Here's the "right answer"
Before sending the command to the board, call set_current_state(TASK_UNINTERRUPTIBLE). This will prevent the scheduler from interrupting your task, but more importantly it will prevent your task from being re-scheduled (once you give up control) until the task is woken up (which sets the state to TASK_RUNNING).
Then, send the command to the board. Then call schedule() or schedule_timeout() -- that won't return until your task is at TASK_RUNNING. Now, if the interrupt fires before you call schedule, then schedule will simply reschedule. But, the wakeup re-set the state to TASK_RUNNING for you, so your task _will_ get rescheduled (avoiding the deadlock).
See linux/drivers/usb/storage/transport.c usb_stor_bulk_msg() for the code I wrote that uses this. The key is in setting TASK_UNINTERRUPTABLE _before_ you send the command, so that it doesn't race with the interrupt.
Matt
On Thu, Sep 28, 2000 at 06:26:17PM -0700, Ivan Passos wrote: > > Hello, > > In order to get the configuration of a board, I have to send, from > userspace, an ioctl to the driver and wait for the board to complete its > action. The way this is implemented is as follows: > - In the ioctl, the driver sends a command to the board and then goes to > sleep (interruptible_sleep_on(&info->config_wait)); > - The board receives the command, handles it and answers back with an > interrupt; > - The driver's interrupt handler schedules a bottom-half action. > - The bottom-half calls wake_up_interuptible(&info->config_wait). > - The ioctl returns and the userspace application has the board > configuration. > > Now, the problem: the board is so fast that it interrupts back _before_ > the driver goes to sleep, i.e.: > - Driver sends command to board; > - Driver goes to sl... interrupt back from board!! > - Interrupt handler schedules bottom-half. > - Bottom-half calls wake_up. > - Ioctl continues, and _then_ goes to sleep. System locked. > > I can't disable interrupts before going to sleep, because the event that > wakes me up is an interrupt. However, if I don't protect it from the > interrupts, the system locks ... > > Is there any other way in Linux to implement this?!?!?! > > Thanks in advance for any help. > > Later, > Ivan > > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > Please read the FAQ at http://www.tux.org/lkml/
-- Matthew Dharm Home: mdharm-usb@one-eyed-alien.net Maintainer, Linux USB Mass Storage Driver
C: They kicked your ass, didn't they? S: They were cheating! -- The Chief and Stef User Friendly, 11/19/1997 [unhandled content-type:application/pgp-signature] |  |