| From 7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <jhovold@gmail.com> |
| Date: Mon, 26 May 2014 19:22:52 +0200 |
| Subject: USB: sierra: fix urb and memory leak in resume error path |
| |
| From: Johan Hovold <jhovold@gmail.com> |
| |
| commit 7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb upstream. |
| |
| Neither the transfer buffer or the urb itself were released in the |
| resume error path for delayed writes. Also on errors, the remainder of |
| the queue was not even processed, which leads to further urb and buffer |
| leaks. |
| |
| The same error path also failed to balance the outstanding-urb counter, |
| something which results in degraded throughput or completely blocked |
| writes. |
| |
| Fix this by releasing urb and buffer and balancing counters on errors, |
| and by always processing the whole queue even when submission of one urb |
| fails. |
| |
| Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while |
| online") |
| |
| Signed-off-by: Johan Hovold <jhovold@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/serial/sierra.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/usb/serial/sierra.c |
| +++ b/drivers/usb/serial/sierra.c |
| @@ -1004,8 +1004,12 @@ static int sierra_resume(struct usb_seri |
| if (err < 0) { |
| intfdata->in_flight--; |
| usb_unanchor_urb(urb); |
| - usb_scuttle_anchored_urbs(&portdata->delayed); |
| - break; |
| + kfree(urb->transfer_buffer); |
| + usb_free_urb(urb); |
| + spin_lock(&portdata->lock); |
| + portdata->outstanding_urbs--; |
| + spin_unlock(&portdata->lock); |
| + continue; |
| } |
| } |
| |