Re: [PATCH] USB: usb-skeleton.c: fix blocked forever in skel_read

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

 



On Friday 15 March 2013 00:19:00 Du Xing wrote:
> Ming Lei
> Below is the Patch v2 according to your solutions.is there any misunderstanding?

The problem is that I needed to work around the counting nature of completions.
If you go to a waitqueue the need is removed. Your original patch together with
the change to use a wait queue would be correct.

> ---
> diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
> index ce31017..3ad1840 100644
> --- a/drivers/usb/usb-skeleton.c
> +++ b/drivers/usb/usb-skeleton.c
> @@ -61,7 +61,6 @@ struct usb_skel {
>         __u8                    bulk_out_endpointAddr;  /* the address of the bulk out endpoint */
>         int                     errors;                 /* the last request tanked */
>         bool                    ongoing_read;           /* a read is going on */
> -       bool                    processed_urb;          /* indicates we haven't processed the urb */
>         spinlock_t              err_lock;               /* lock for errors */
>         struct kref             kref;
>         struct mutex            io_mutex;               /* synchronize I/O with disconnect */
> @@ -181,11 +180,12 @@ static void skel_read_bulk_callback(struct urb *urb)
>                 dev->errors = urb->status;
>         } else {
>                 dev->bulk_in_filled = urb->actual_length;
> +               dev->bulk_in_copied = 0;
>         }
>         dev->ongoing_read = 0;
> +       complete(&dev->bulk_in_completion);
>         spin_unlock(&dev->err_lock);
>  
> -       complete(&dev->bulk_in_completion);
>  }
>  
>  static int skel_do_read_io(struct usb_skel *dev, size_t count)
> @@ -227,7 +227,6 @@ static ssize_t skel_read(struct file *file, char *buffer, size_t count,
>  {
>         struct usb_skel *dev;
>         int rv;
> -       bool ongoing_io;
>  
>         dev = file->private_data;
>  
> @@ -248,10 +247,8 @@ static ssize_t skel_read(struct file *file, char *buffer, size_t count,
>         /* if IO is under way, we must not touch things */
>  retry:
>         spin_lock_irq(&dev->err_lock);
> -       ongoing_io = dev->ongoing_read;
> -       spin_unlock_irq(&dev->err_lock);
>  
> -       if (ongoing_io) {
> +       if (dev->ongoing_io) {
>                 /* nonblocking IO shall not wait */
>                 if (file->f_flags & O_NONBLOCK) {
>                         rv = -EAGAIN;
> @@ -264,23 +261,11 @@ retry:
>                 rv = wait_for_completion_interruptible(&dev->bulk_in_completion);

Not good. You are sleeping with a spinlock held. This is absolutely bad.
If you wish to retain the completion you need to change locking a bit more.

	Regards
		Oliver

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux