From patchwork Mon May 16 19:36:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kroah-Hartman X-Patchwork-Id: 573857 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08C3EC433FE for ; Mon, 16 May 2022 19:43:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346146AbiEPTnp (ORCPT ); Mon, 16 May 2022 15:43:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345780AbiEPTnG (ORCPT ); Mon, 16 May 2022 15:43:06 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6B173FBE5; Mon, 16 May 2022 12:42:10 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 6393FB81609; Mon, 16 May 2022 19:42:09 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BA3B6C385AA; Mon, 16 May 2022 19:42:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1652730128; bh=uJon7n2KG4EVfB6CqDE0IyqMCdZhKt43s78eokQXmD4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0rtDNpTnrA/IYcc881he27LsoFiAbkvSfTeIYK43xVivdMzYPk/PBT5FEcqRdIw0a z9JkBAn+LT5xlIXnO4VNYihDUJW9XHcUpOJFU43ev3oY/whHwnpOtGMdXnSguwnCL3 wnCMus72Tk2yhhewrbU+1ugtQ+QDmgzz9Xh2czEA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sergey Ryazanov , Oliver Neukum Subject: [PATCH 4.19 21/32] usb: cdc-wdm: fix reading stuck on device close Date: Mon, 16 May 2022 21:36:35 +0200 Message-Id: <20220516193615.402305369@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516193614.773450018@linuxfoundation.org> References: <20220516193614.773450018@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Sergey Ryazanov commit 01e01f5c89773c600a9f0b32c888de0146066c3a upstream. cdc-wdm tracks whether a response reading request is in-progress and blocks the next request from being sent until the previous request is completed. As soon as last user closes the cdc-wdm device file, the driver cancels any ongoing requests, resets the pending response counter, but leaves the response reading in-progress flag (WDM_RESPONDING) untouched. So if the user closes the device file during the response receive request is being performed, no more data will be obtained from the modem. The request will be cancelled, effectively preventing the WDM_RESPONDING flag from being reseted. Keeping the flag set will prevent a new response receive request from being sent, permanently blocking the read path. The read path will staying blocked until the module will be reloaded or till the modem will be re-attached. This stuck has been observed with a Huawei E3372 modem attached to an OpenWrt router and using the comgt utility to set up a network connection. Fix this issue by clearing the WDM_RESPONDING flag on the device file close. Without this fix, the device reading stuck can be easily reproduced in a few connection establishing attempts. With this fix, a load test for modem connection re-establishing worked for several hours without any issues. Fixes: 922a5eadd5a3 ("usb: cdc-wdm: Fix race between autosuspend and reading from the device") Signed-off-by: Sergey Ryazanov Cc: stable Acked-by: Oliver Neukum Link: https://lore.kernel.org/r/20220501175828.8185-1-ryazanov.s.a@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 1 + 1 file changed, 1 insertion(+) --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -755,6 +755,7 @@ static int wdm_release(struct inode *ino poison_urbs(desc); spin_lock_irq(&desc->iuspin); desc->resp_count = 0; + clear_bit(WDM_RESPONDING, &desc->flags); spin_unlock_irq(&desc->iuspin); desc->manage_power(desc->intf, 0); unpoison_urbs(desc);