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 [EMAIL PROTECTED]
> Please read the FAQ at http://www.tux.org/lkml/

-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
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

PGP signature

Reply via email to