Re: [PATCH 1/1] quatech_usb2: Potential lost wakeup scenario in TIOCMIWAIT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Sorry, please ignore the patch below.

The following lines should be in the reverse order (first we should
store the prev_msr_value and
later the current state):
> +               set_current_state(TASK_INTERRUPTIBLE);
>                prev_msr_value = port_extra->shadowMSR  & QT2_SERIAL_MSR_MASK;

Because of the above 2 lines, we might not be able to detect the
change in line 2 while
the task state might change to running.
Result: we would return from this function with -EIO.

Of course, the usermode app could do another ioctl for waiting for
change in status, but
this would be an error in my logic.

I will post another patch for this tomorrow.

On Tue, Sep 13, 2011 at 11:23 AM, Kautuk Consul <consul.kautuk@xxxxxxxxx> wrote:
> If the usermode app does an ioctl over this serial device  by
> using TIOCMIWAIT, then the code will wait by setting the current
> task state to TASK_INTERRUPTIBLE and then calling schedule().
> This will be woken up by the qt2_process_modem_status on URB
> completion when the port_extra->shadowMSR is set to the new
> modem status.
>
> However, this could result in a lost wakeup scenario due to a race
> in the logic in the qt2_ioctl(TIOCMIWAIT) loop and the URB completion
> for new modem status in qt2_process_modem_status.
> Due to this, the usermode app's task will continue to sleep despite a
> change in the modem status.
>
> Signed-off-by: Kautuk Consul <consul.kautuk@xxxxxxxxx>
> ---
>  drivers/staging/quatech_usb2/quatech_usb2.c |    8 ++++++--
>  1 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
> index ca098ca..af7cba2 100644
> --- a/drivers/staging/quatech_usb2/quatech_usb2.c
> +++ b/drivers/staging/quatech_usb2/quatech_usb2.c
> @@ -915,10 +915,10 @@ static int qt2_ioctl(struct tty_struct *tty,
>        } else if (cmd == TIOCMIWAIT) {
>                dbg("%s() port %d, cmd == TIOCMIWAIT enter",
>                        __func__, port->number);
> +               set_current_state(TASK_INTERRUPTIBLE);
>                prev_msr_value = port_extra->shadowMSR  & QT2_SERIAL_MSR_MASK;
>                while (1) {
>                        add_wait_queue(&port_extra->wait, &wait);
> -                       set_current_state(TASK_INTERRUPTIBLE);
>                        schedule();
>                        dbg("%s(): port %d, cmd == TIOCMIWAIT here\n",
>                                __func__, port->number);
> @@ -926,9 +926,12 @@ static int qt2_ioctl(struct tty_struct *tty,
>                        /* see if a signal woke us up */
>                        if (signal_pending(current))
>                                return -ERESTARTSYS;
> +                       set_current_state(TASK_INTERRUPTIBLE);
>                        msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK;
> -                       if (msr_value == prev_msr_value)
> +                       if (msr_value == prev_msr_value) {
> +                               __set_current_state(TASK_RUNNING);
>                                return -EIO;  /* no change - error */
> +                       }
>                        if ((arg & TIOCM_RNG &&
>                                ((prev_msr_value & QT2_SERIAL_MSR_RI) ==
>                                        (msr_value & QT2_SERIAL_MSR_RI))) ||
> @@ -941,6 +944,7 @@ static int qt2_ioctl(struct tty_struct *tty,
>                                (arg & TIOCM_CTS &&
>                                ((prev_msr_value & QT2_SERIAL_MSR_CTS) ==
>                                        (msr_value & QT2_SERIAL_MSR_CTS)))) {
> +                               __set_current_state(TASK_RUNNING);
>                                return 0;
>                        }
>                } /* end inifinite while */
> --
> 1.7.6
>
>
_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel



[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux