| From 6f6485463aada1ec6a0f3db6a03eb8e393d6bb55 Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <jhovold@gmail.com> |
| Date: Sat, 9 Nov 2013 12:38:09 +0100 |
| Subject: USB: serial: fix race in generic write |
| |
| From: Johan Hovold <jhovold@gmail.com> |
| |
| commit 6f6485463aada1ec6a0f3db6a03eb8e393d6bb55 upstream. |
| |
| Fix race in generic write implementation, which could lead to |
| temporarily degraded throughput. |
| |
| The current generic write implementation introduced by commit |
| 27c7acf22047 ("USB: serial: reimplement generic fifo-based writes") has |
| always had this bug, although it's fairly hard to trigger and the |
| consequences are not likely to be noticed. |
| |
| Specifically, a write() on one CPU while the completion handler is |
| running on another could result in only one of the two write urbs being |
| utilised to empty the remainder of the write fifo (unless there is a |
| second write() that doesn't race during that time). |
| |
| Signed-off-by: Johan Hovold <jhovold@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/serial/generic.c | 9 +-------- |
| 1 file changed, 1 insertion(+), 8 deletions(-) |
| |
| --- a/drivers/usb/serial/generic.c |
| +++ b/drivers/usb/serial/generic.c |
| @@ -176,14 +176,7 @@ retry: |
| return result; |
| } |
| |
| - /* Try sending off another urb, unless in irq context (in which case |
| - * there will be no free urb). */ |
| - if (!in_irq()) |
| - goto retry; |
| - |
| - clear_bit_unlock(USB_SERIAL_WRITE_BUSY, &port->flags); |
| - |
| - return 0; |
| + goto retry; /* try sending off another urb */ |
| } |
| |
| /** |