| From 11cda0677175d1b72176eb9b25d8c08c48a8d2d0 Mon Sep 17 00:00:00 2001 |
| From: Michael Schenk <michael.schenk@albis-elcon.com> |
| Date: Thu, 26 Jan 2017 11:25:04 -0600 |
| Subject: [PATCH] rtlwifi: rtl_usb: Fix for URB leaking when doing ifconfig |
| up/down |
| |
| commit 575ddce0507789bf9830d089557d2199d2f91865 upstream. |
| |
| In the function rtl_usb_start we pre-allocate a certain number of urbs |
| for RX path but they will not be freed when calling rtl_usb_stop. This |
| results in leaking urbs when doing ifconfig up and down. Eventually, |
| the system has no available urbs. |
| |
| Signed-off-by: Michael Schenk <michael.schenk@albis-elcon.com> |
| Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> |
| Cc: Stable <stable@vger.kernel.org> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c |
| index 41617b7b0822..5412074c0e89 100644 |
| --- a/drivers/net/wireless/realtek/rtlwifi/usb.c |
| +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c |
| @@ -834,12 +834,30 @@ static void rtl_usb_stop(struct ieee80211_hw *hw) |
| struct rtl_priv *rtlpriv = rtl_priv(hw); |
| struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); |
| + struct urb *urb; |
| |
| /* should after adapter start and interrupt enable. */ |
| set_hal_stop(rtlhal); |
| cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); |
| /* Enable software */ |
| SET_USB_STOP(rtlusb); |
| + |
| + /* free pre-allocated URBs from rtl_usb_start() */ |
| + usb_kill_anchored_urbs(&rtlusb->rx_submitted); |
| + |
| + tasklet_kill(&rtlusb->rx_work_tasklet); |
| + cancel_work_sync(&rtlpriv->works.lps_change_work); |
| + |
| + flush_workqueue(rtlpriv->works.rtl_wq); |
| + |
| + skb_queue_purge(&rtlusb->rx_queue); |
| + |
| + while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { |
| + usb_free_coherent(urb->dev, urb->transfer_buffer_length, |
| + urb->transfer_buffer, urb->transfer_dma); |
| + usb_free_urb(urb); |
| + } |
| + |
| rtlpriv->cfg->ops->hw_disable(hw); |
| } |
| |
| -- |
| 2.12.0 |
| |