Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp245311ybi; Wed, 29 May 2019 20:32:51 -0700 (PDT) X-Google-Smtp-Source: APXvYqxhSpYQWKYfSAXhoyImuzEKnkjufELdJbOQVDRuUaHIVpOc3EigsNuM66DHzdR0zyYd4I64 X-Received: by 2002:a17:90a:9f8e:: with SMTP id o14mr1378820pjp.82.1559187171800; Wed, 29 May 2019 20:32:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559187171; cv=none; d=google.com; s=arc-20160816; b=URFuYzJ5HaUDPIhwE4IbzE4+2+bV8BUIeObZnxhsGkEWotkSD7rTh2OD0qMC/YhNS3 Iy/Ul0dZf3hLWA0Hu8Bn0jD3twtPXbcQIvsjQCihSI+BrkzyGyGiCJKlVXBXDIxZIeAw CYpOurjVJf617LmcNYkNQdBDy6t4KmchA/jFzuRlPh502Blfa7+6KjDDFsBIQQph0SeX 6ppI3l/nnqrnYYjPu5z0yNmbU7ZcnUwARQnPWqVxymc3bjXawH3SB5zg5/3Qdlboyhb3 69xSGKOYh5jMBQqFeabroS3FNQkkflDTHdWFkenOdPh1bJx/n9Lh2wh+U8Lur+euPbB4 ikZg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=pVDDmlP3UgshIlP/A253d4OXUxCq3wbZU34iWEqHObM=; b=tLQx8671fIZXOiTty1NLaCV+C3M61uQpVrh8sf0IH8f9NHWNbmf7VzDTrtIYM+DXTO 7u8hDwoVfw2pysrebOiBLTNmC1VL4NA4Ca4p99PVvHBWdKsHzCZHhEWbv3bSdGMiDBgM dcemOtkPYP0pEy1VI3v4GMZrSeULhDqNG/hxc8wX0fBbR7eVBx4uZTVpTiuuN4oLWZpd UH+0E+v4hp6fqp/wN0PvBVShEvYba7Gkg3PQwzmC8JK4XT7HzDkfHeVyB6WLi/PkGHuk uQuYDMDPMk+QMQhErAyoCvvbbmmoB9J05ZmBrOzIHRhpIu6+bfbWMJ9ptzVX9oKH+Kk+ hE1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=WsdwY2eq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q184si1417954pfc.199.2019.05.29.20.32.35; Wed, 29 May 2019 20:32:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=WsdwY2eq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388493AbfE3DaF (ORCPT + 99 others); Wed, 29 May 2019 23:30:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:33322 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732478AbfE3DVK (ORCPT ); Wed, 29 May 2019 23:21:10 -0400 Received: from localhost (ip67-88-213-2.z213-88-67.customer.algx.net [67.88.213.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id B55B4249C6; Thu, 30 May 2019 03:21:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1559186469; bh=DAZia6pEScLnyChBtoVglMHO6LuOLDhphpeN2FZxS0Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WsdwY2eqLsF6cfxRfhLP8Yw/0L50Hnn2sSPZA+VKynwH2Awtm8NDRV1BZkFkU3f6h P1gKi+2Ll1/mmJwdvAJG+GAKy3BUnKl/Sbf+sHS0E5fsPApzy+/NcEtQTWSlVOHBPo Heq6lILtoNNs6RPoj3XHWHiasY/P4/yk35QuMRoQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Piotr Figiel , Kalle Valo , Sasha Levin Subject: [PATCH 4.9 097/128] brcmfmac: fix race during disconnect when USB completion is in progress Date: Wed, 29 May 2019 20:07:09 -0700 Message-Id: <20190530030452.065702841@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190530030432.977908967@linuxfoundation.org> References: <20190530030432.977908967@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [ Upstream commit db3b9e2e1d58080d0754bdf9293dabf8c6491b67 ] It was observed that rarely during USB disconnect happening shortly after connect (before full initialization completes) usb_hub_wq would wait forever for the dev_init_lock to be unlocked. dev_init_lock would remain locked though because of infinite wait during usb_kill_urb: [ 2730.656472] kworker/0:2 D 0 260 2 0x00000000 [ 2730.660700] Workqueue: events request_firmware_work_func [ 2730.664807] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) [ 2730.670587] [<809dd164>] (schedule) from [<8069af44>] (usb_kill_urb+0xdc/0x114) [ 2730.676815] [<8069af44>] (usb_kill_urb) from [<7f258b50>] (brcmf_usb_free_q+0x34/0xa8 [brcmfmac]) [ 2730.684833] [<7f258b50>] (brcmf_usb_free_q [brcmfmac]) from [<7f2517d4>] (brcmf_detach+0xa0/0xb8 [brcmfmac]) [ 2730.693557] [<7f2517d4>] (brcmf_detach [brcmfmac]) from [<7f251a34>] (brcmf_attach+0xac/0x3d8 [brcmfmac]) [ 2730.702094] [<7f251a34>] (brcmf_attach [brcmfmac]) from [<7f2587ac>] (brcmf_usb_probe_phase2+0x468/0x4a0 [brcmfmac]) [ 2730.711601] [<7f2587ac>] (brcmf_usb_probe_phase2 [brcmfmac]) from [<7f252888>] (brcmf_fw_request_done+0x194/0x220 [brcmfmac]) [ 2730.721795] [<7f252888>] (brcmf_fw_request_done [brcmfmac]) from [<805748e4>] (request_firmware_work_func+0x4c/0x88) [ 2730.731125] [<805748e4>] (request_firmware_work_func) from [<80141474>] (process_one_work+0x228/0x808) [ 2730.739223] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) [ 2730.746105] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) [ 2730.752227] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) [ 2733.099695] kworker/0:3 D 0 1065 2 0x00000000 [ 2733.103926] Workqueue: usb_hub_wq hub_event [ 2733.106914] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) [ 2733.112693] [<809dd164>] (schedule) from [<809e2a8c>] (schedule_timeout+0x214/0x3e4) [ 2733.119621] [<809e2a8c>] (schedule_timeout) from [<809dde2c>] (wait_for_common+0xc4/0x1c0) [ 2733.126810] [<809dde2c>] (wait_for_common) from [<7f258d00>] (brcmf_usb_disconnect+0x1c/0x4c [brcmfmac]) [ 2733.135206] [<7f258d00>] (brcmf_usb_disconnect [brcmfmac]) from [<8069e0c8>] (usb_unbind_interface+0x5c/0x1e4) [ 2733.143943] [<8069e0c8>] (usb_unbind_interface) from [<8056d3e8>] (device_release_driver_internal+0x164/0x1fc) [ 2733.152769] [<8056d3e8>] (device_release_driver_internal) from [<8056c078>] (bus_remove_device+0xd0/0xfc) [ 2733.161138] [<8056c078>] (bus_remove_device) from [<8056977c>] (device_del+0x11c/0x310) [ 2733.167939] [<8056977c>] (device_del) from [<8069cba8>] (usb_disable_device+0xa0/0x1cc) [ 2733.174743] [<8069cba8>] (usb_disable_device) from [<8069507c>] (usb_disconnect+0x74/0x1dc) [ 2733.181823] [<8069507c>] (usb_disconnect) from [<80695e88>] (hub_event+0x478/0xf88) [ 2733.188278] [<80695e88>] (hub_event) from [<80141474>] (process_one_work+0x228/0x808) [ 2733.194905] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) [ 2733.201724] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) [ 2733.207913] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) It was traced down to a case where usb_kill_urb would be called on an URB structure containing more or less random data, including large number in its use_count. During the debugging it appeared that in brcmf_usb_free_q() the traversal over URBs' lists is not synchronized with operations on those lists in brcmf_usb_rx_complete() leading to handling brcmf_usbdev_info structure (holding lists' head) as lists' element and in result causing above problem. Fix it by walking through all URBs during brcmf_cancel_all_urbs using the arrays of requests instead of linked lists. Signed-off-by: Piotr Figiel Signed-off-by: Kalle Valo Signed-off-by: Sasha Levin --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index bfdf6ef224437..acf513fd9e6d5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -681,12 +681,18 @@ static int brcmf_usb_up(struct device *dev) static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo) { + int i; + if (devinfo->ctl_urb) usb_kill_urb(devinfo->ctl_urb); if (devinfo->bulk_urb) usb_kill_urb(devinfo->bulk_urb); - brcmf_usb_free_q(&devinfo->tx_postq, true); - brcmf_usb_free_q(&devinfo->rx_postq, true); + if (devinfo->tx_reqs) + for (i = 0; i < devinfo->bus_pub.ntxq; i++) + usb_kill_urb(devinfo->tx_reqs[i].urb); + if (devinfo->rx_reqs) + for (i = 0; i < devinfo->bus_pub.nrxq; i++) + usb_kill_urb(devinfo->rx_reqs[i].urb); } static void brcmf_usb_down(struct device *dev) -- 2.20.1