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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html