Re: [PATCH] usb: cdc-wdm: Fix "scheduling while atomic" after failed write

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

 



Am Donnerstag, 26. April 2012, 20:18:00 schrieb Bjørn Mork:
> Oliver Neukum <oliver@xxxxxxxxxx> writes:
> > Am Donnerstag, 26. April 2012, 18:30:39 schrieb Bjørn Mork:
> >
> >> So nothing from the wdm_disconnect() call. But that is expected, isn't
> >> it?  We don't disconnect from the device here.
> >
> > Now you confuse me. I thought the oops happens when the disconnect after
> > a write.
> 
> Eh, yes.  Sorry for that confusion.  The userspace application closes
> the character device file, so we do call wdm_release.  But the driver does
> not disconnect from the USB device, so we do not call wdm_disconnect.
> 
> So the events leading to the crash are
> 
>  open(file, RW + NONBLOCK)
>  write(file)
>  write(file)
>  close(file)
> 
> where the two writes are colliding.  Quite possibly with read's
> interleaved here, but I don't think they are relevant for the result.

Please try this patch.

	Regards
		Oliver

diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index c6f6560..0bb2b32 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -157,8 +157,9 @@ static void wdm_out_callback(struct urb *urb)
 	spin_lock(&desc->iuspin);
 	desc->werr = urb->status;
 	spin_unlock(&desc->iuspin);
-	clear_bit(WDM_IN_USE, &desc->flags);
 	kfree(desc->outbuf);
+	desc->outbuf = NULL;
+	clear_bit(WDM_IN_USE, &desc->flags);
 	wake_up(&desc->wait);
 }
 
@@ -338,7 +339,7 @@ static ssize_t wdm_write
 	if (we < 0)
 		return -EIO;
 
-	desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
+	buf = kmalloc(count, GFP_KERNEL);
 	if (!buf) {
 		rv = -ENOMEM;
 		goto outnl;
@@ -406,10 +407,12 @@ static ssize_t wdm_write
 	req->wIndex = desc->inum;
 	req->wLength = cpu_to_le16(count);
 	set_bit(WDM_IN_USE, &desc->flags);
+	desc->outbuf = buf;
 
 	rv = usb_submit_urb(desc->command, GFP_KERNEL);
 	if (rv < 0) {
 		kfree(buf);
+		desc->outbuf = NULL;
 		clear_bit(WDM_IN_USE, &desc->flags);
 		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
 	} else {
--
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