| From 625f38f64be245f4966f6e4f8bf25253c9b8749e Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Thu, 28 Nov 2019 18:22:03 +0100 |
| Subject: [PATCH] rsi: fix non-atomic allocation in completion handler |
| |
| commit b9b9f9fea21830f85cf0148cd8dce001ae55ead1 upstream. |
| |
| USB completion handlers are called in atomic context and must |
| specifically not allocate memory using GFP_KERNEL. |
| |
| Fixes: a1854fae1414 ("rsi: improve RX packet handling in USB interface") |
| Cc: stable <stable@vger.kernel.org> # 4.17 |
| Cc: Prameela Rani Garnepudi <prameela.j04cs@gmail.com> |
| Signed-off-by: Johan Hovold <johan@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/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c |
| index 64c56ce94136..d6cdabef264d 100644 |
| --- a/drivers/net/wireless/rsi/rsi_91x_usb.c |
| +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c |
| @@ -16,6 +16,7 @@ |
| */ |
| |
| #include <linux/module.h> |
| +#include <linux/types.h> |
| #include <net/rsi_91x.h> |
| #include "rsi_usb.h" |
| #include "rsi_hal.h" |
| @@ -29,7 +30,7 @@ MODULE_PARM_DESC(dev_oper_mode, |
| "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n" |
| "6[AP + BT classic], 14[AP + BT classic + BT LE]"); |
| |
| -static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num); |
| +static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t flags); |
| |
| /** |
| * rsi_usb_card_write() - This function writes to the USB Card. |
| @@ -285,7 +286,7 @@ static void rsi_rx_done_handler(struct urb *urb) |
| status = 0; |
| |
| out: |
| - if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num)) |
| + if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num, GFP_ATOMIC)) |
| rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__); |
| |
| if (status) |
| @@ -307,7 +308,7 @@ static void rsi_rx_urb_kill(struct rsi_hw *adapter, u8 ep_num) |
| * |
| * Return: 0 on success, a negative error code on failure. |
| */ |
| -static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) |
| +static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t mem_flags) |
| { |
| struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; |
| struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1]; |
| @@ -337,7 +338,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) |
| rsi_rx_done_handler, |
| rx_cb); |
| |
| - status = usb_submit_urb(urb, GFP_KERNEL); |
| + status = usb_submit_urb(urb, mem_flags); |
| if (status) { |
| rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__); |
| dev_kfree_skb(skb); |
| @@ -827,12 +828,12 @@ static int rsi_probe(struct usb_interface *pfunction, |
| rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__); |
| } |
| |
| - status = rsi_rx_urb_submit(adapter, WLAN_EP); |
| + status = rsi_rx_urb_submit(adapter, WLAN_EP, GFP_KERNEL); |
| if (status) |
| goto err1; |
| |
| if (adapter->priv->coex_mode > 1) { |
| - status = rsi_rx_urb_submit(adapter, BT_EP); |
| + status = rsi_rx_urb_submit(adapter, BT_EP, GFP_KERNEL); |
| if (status) |
| goto err_kill_wlan_urb; |
| } |
| -- |
| 2.7.4 |
| |