Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp171565ybc; Mon, 11 Nov 2019 22:52:27 -0800 (PST) X-Google-Smtp-Source: APXvYqxboPVXChQjdYBrNfiT9d+GbUcPvxdur5fa6d3Qy/nCY7MijAQzB9RxlymnsYBcwdGcz/X5 X-Received: by 2002:a17:906:3501:: with SMTP id r1mr25689888eja.301.1573541547001; Mon, 11 Nov 2019 22:52:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573541546; cv=none; d=google.com; s=arc-20160816; b=0ja/vr8k9kjWsZt1EoL5GVOo8fMoQ5bR1V4Wa3rupq+hrDxct305JzH/VZstBy4WsK hugeX6P6sHEiznN5L2335KheyZguQuWu/clZ27lKU7HUNgt1Lw+1ajxehyxeOHQlWwT7 DLQ8ElWS2JFpTt/gtxU1KtkLtshB9SEbaC5DjeQf5o4ckxuNPcoIdGpKRu48ZA3pSbh6 4M7oHj+jze9HzabgK5G1je2xJqhXEuVNioOm3kRToiBm6e3Fo7wWPyGN5QjiAF3P3ZqE 4vQ7qVgOjUQ1w/eh7c1cPJFI8Y6efV3BYIKwRcriN4GXO1OYMcyhCdm0rDTKArvS+aE1 a3Jg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:dkim-signature:mime-version:message-id :date:subject:cc:from; bh=uaQU/d9YZIhPAFnpZUJ/WgAWpgBHxUlq6+ZdUcJ/2w0=; b=BAIu6AwUaMa9qQOOm/Fr3orrKDbelfykwgcpid8HXkgvwMXFEnk+xEx7Q2q9iBwORo vG4E7I/lZtyPMfRXUCUP1mEYs9KHuQ9HJs2HIlw8lhf/y54OMBJJxcvaKyzVrkDcn1Gv zy2+sJPBLbKW2/P4STdDNodUPBht3lZh+O7w1wH8LbCO9EtVyUlnnUirQkxNhmFeg6V3 NkF7JikNdGuNewRA5/H2VKeiU9SmFYOGMFwIgvm4VXgLYXq2GAYewWuSiyEYvtYqHOHs oMAJxkhsMYsjbSBsQbGRJ1cvOoG/0f+6ID5WpKGbilDoSu3jitHc/qz/V3prY4nZ1KMt 6idA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@nvidia.com header.s=n1 header.b=cSKBTpCV; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id fx12si10622759ejb.154.2019.11.11.22.52.02; Mon, 11 Nov 2019 22:52:26 -0800 (PST) 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=fail header.i=@nvidia.com header.s=n1 header.b=cSKBTpCV; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725955AbfKLGvR (ORCPT + 99 others); Tue, 12 Nov 2019 01:51:17 -0500 Received: from hqemgate15.nvidia.com ([216.228.121.64]:19472 "EHLO hqemgate15.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725781AbfKLGvR (ORCPT ); Tue, 12 Nov 2019 01:51:17 -0500 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqemgate15.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Mon, 11 Nov 2019 22:51:15 -0800 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Mon, 11 Nov 2019 22:51:15 -0800 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Mon, 11 Nov 2019 22:51:15 -0800 Received: from HQMAIL101.nvidia.com (172.20.187.10) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 12 Nov 2019 06:51:15 +0000 Received: from hqnvemgw03.nvidia.com (10.124.88.68) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Tue, 12 Nov 2019 06:51:15 +0000 Received: from henryl-tu10x.nvidia.com (Not Verified[10.19.109.97]) by hqnvemgw03.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Mon, 11 Nov 2019 22:51:14 -0800 From: Henry Lin CC: Henry Lin , Jaroslav Kysela , Takashi Iwai , Greg Kroah-Hartman , Allison Randal , Thomas Gleixner , Richard Fontana , , Subject: [PATCH] usb-audio: not submit urb for stopped endpoint Date: Tue, 12 Nov 2019 14:51:06 +0800 Message-ID: <20191112065108.7766-1-henryl@nvidia.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1573541475; bh=uaQU/d9YZIhPAFnpZUJ/WgAWpgBHxUlq6+ZdUcJ/2w0=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: MIME-Version:Content-Type; b=cSKBTpCVzDDNzjJOZ7Bs2de/FsrJr/iybeyLPt0/Bhxg+ztWxOu2eFJWEeGuvpwwm fV4+hrOnpMfYzdYKlMi/7pkPJpxI4gCxF5/ilFNsg9a/YmEAEMXY60m7izlUcMDNlI mmx1Y7VQ80UPo7UHJkya+Hq+mUbp3qgHNWb8NnYP1ty3J/nFQkPYa74lBmVO7x8Oih bXiBR17J8WI4rRYsM5LUKi8y/2WjNljnYJPiE0QQ8aRi6cMUuJjVS98nrCPi/5mx6w R0HpEUVA4YpkkbB/YkI2hADJVLr59tc9jbsubxx1TG6mEA6TWYXojp0giuvFROtfO8 3CkkHxdUNBT0w== To: unlisted-recipients:; (no To-header on input) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org While output urb's snd_complete_urb() is executing, calling prepare_outbound_urb() may cause endpoint stopped before prepare_outbound_urb() returns and result in next urb submitted to stopped endpoint. usb-audio driver cannot re-use it afterwards as the urb is still hold by usb stack. This change checks EP_FLAG_RUNNING flag after prepare_outbound_urb() again to let snd_complete_urb() know the endpoint already stopped and does not submit next urb. We observed two scenario have this issue: 1. While executing snd_complete_urb() to complete an output urb, calling prepare_outbound_urb() let deactive_urbs() get called to unlink all active urbs. [ 268.097066] [] deactivate_urbs+0xd4/0x108 [ 268.102633] [] snd_usb_endpoint_stop+0x30/0x58 [ 268.108636] [] snd_usb_substream_playback_trigger+0xa4/0xf4 [ 268.115765] [] snd_pcm_do_stop+0x4c/0x58 [ 268.121245] [] snd_pcm_action_single+0x40/0x88 [ 268.127245] [] snd_pcm_action+0x30/0xf0 [ 268.132632] [] snd_pcm_stop+0x24/0x2c [ 268.137851] [] xrun+0x60/0x6c [ 268.142374] [] snd_pcm_update_state+0xa8/0x10c [ 268.148374] [] snd_pcm_update_hw_ptr0+0x328/0x344 [ 268.154635] [] snd_pcm_period_elapsed+0x98/0xb0 [ 268.160723] [] prepare_playback_urb+0x46c/0x488 [ 268.166810] [] prepare_outbound_urb+0x60/0x1d4 [ 268.172805] [] snd_complete_urb+0x244/0x264 [ 268.178548] [] __usb_hcd_giveback_urb+0x94/0x104 [ 268.184721] [] usb_hcd_giveback_urb+0x3c/0x114 [ 268.190724] [] handle_tx_event+0x1304/0x1434 [ 268.196552] [] xhci_handle_event+0x5dc/0x788 [ 268.202378] [] xhci_irq+0x178/0x280 2. Userspace application stops playback from sound subsystem with below call stack: [ 28.506477] CPU: 5 PID: 1274 Comm: AudioOut_25 Not tainted 4.4.38-tegra #31 [ 28.513430] Hardware name: quill (DT) [ 28.517085] Call trace: [ 28.519531] [] dump_backtrace+0x0/0xf8 [ 28.524837] [] show_stack+0x14/0x1c [ 28.529885] [] dump_stack+0xac/0xe0 [ 28.534931] [] deactivate_urbs+0x148/0x180 [ 28.540578] [] snd_usb_endpoint_stop+0x30/0x58 [ 28.546571] [] snd_usb_substream_playback_trigger+0xa4/0xf4 [ 28.553699] [] snd_pcm_do_stop+0x4c/0x58 [ 28.559179] [] snd_pcm_action_single+0x40/0x88 [ 28.565178] [] snd_pcm_action+0x30/0xf0 [ 28.570568] [] snd_pcm_drop+0xac/0x140 [ 28.575873] [] snd_pcm_release_substream+0x28/0xb0 [ 28.582212] [] snd_pcm_release+0x3c/0x98 [ 28.587686] [] __fput+0xe0/0x1ac [ 28.592469] [] ____fput+0xc/0x14 [ 28.597253] [] task_work_run+0xa0/0xc0 [ 28.602558] [] do_notify_resume+0x48/0x60 [ 28.608123] [] work_pending+0x1c/0x20 In the call path, snd_pcm_stream spinlock has been acquired in snd_pcm_drop(). If an output urb is completed between the spinlock acquired and deactivate_urbs() clears EP_FLAG_RUNNING for the endpoint, its executing of snd_complete_urb() will be blocked for acquiring snd_pcm_stream spinlock in snd_pcm_period_elapsed() until the lock is released in snd_pcm_drop(). When snd_complete_urb() continues, all jobs for deactivate_urbs() are finished. Signed-off-by: Henry Lin --- sound/usb/endpoint.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index a2ab8e8d3a93..4a9a2f6ef5a4 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -388,6 +388,9 @@ static void snd_complete_urb(struct urb *urb) } prepare_outbound_urb(ep, ctx); + /* can be stopped during prepare callback */ + if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) + goto exit_clear; } else { retire_inbound_urb(ep, ctx); /* can be stopped during retire callback */ -- 2.17.1