| From: Guenter Roeck <linux@roeck-us.net> |
| Date: Tue, 28 Jan 2020 14:14:57 -0800 |
| Subject: brcmfmac: abort and release host after error |
| |
| commit 863844ee3bd38219c88e82966d1df36a77716f3e upstream. |
| |
| With commit 216b44000ada ("brcmfmac: Fix use after free in |
| brcmf_sdio_readframes()") applied, we see locking timeouts in |
| brcmf_sdio_watchdog_thread(). |
| |
| brcmfmac: brcmf_escan_timeout: timer expired |
| INFO: task brcmf_wdog/mmc1:621 blocked for more than 120 seconds. |
| Not tainted 4.19.94-07984-g24ff99a0f713 #1 |
| "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. |
| brcmf_wdog/mmc1 D 0 621 2 0x00000000 last_sleep: 2440793077. last_runnable: 2440766827 |
| [<c0aa1e60>] (__schedule) from [<c0aa2100>] (schedule+0x98/0xc4) |
| [<c0aa2100>] (schedule) from [<c0853830>] (__mmc_claim_host+0x154/0x274) |
| [<c0853830>] (__mmc_claim_host) from [<bf10c5b8>] (brcmf_sdio_watchdog_thread+0x1b0/0x1f8 [brcmfmac]) |
| [<bf10c5b8>] (brcmf_sdio_watchdog_thread [brcmfmac]) from [<c02570b8>] (kthread+0x178/0x180) |
| |
| In addition to restarting or exiting the loop, it is also necessary to |
| abort the command and to release the host. |
| |
| Fixes: 216b44000ada ("brcmfmac: Fix use after free in brcmf_sdio_readframes()") |
| Cc: Dan Carpenter <dan.carpenter@oracle.com> |
| Cc: Matthias Kaehlcke <mka@chromium.org> |
| Cc: Brian Norris <briannorris@chromium.org> |
| Cc: Douglas Anderson <dianders@chromium.org> |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Reviewed-by: Douglas Anderson <dianders@chromium.org> |
| Acked-by: franky.lin@broadcom.com |
| Acked-by: Dan Carpenter <dan.carpenter@oracle.com> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| [bwh: Backported to 3.16: |
| - Use bus->sdiodev->func[1] instead of ->func1 |
| - Adjust filename] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |
| +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |
| @@ -1971,6 +1971,8 @@ static uint brcmf_sdio_readframes(struct |
| if (brcmf_sdio_hdparse(bus, bus->rxhdr, &rd_new, |
| BRCMF_SDIO_FT_NORMAL)) { |
| rd->len = 0; |
| + brcmf_sdio_rxfail(bus, true, true); |
| + sdio_release_host(bus->sdiodev->func[1]); |
| brcmu_pkt_buf_free_skb(pkt); |
| continue; |
| } |