Received: by 2002:a05:6358:5282:b0:b5:90e7:25cb with SMTP id g2csp3328014rwa; Tue, 23 Aug 2022 02:57:18 -0700 (PDT) X-Google-Smtp-Source: AA6agR7Hd5NbAZHD2T4NqAD0DNCdaB2Gh/73ZLiHV0wafHh8jxzH2B9Vwumuh2oCrhMmF8aSIf8r X-Received: by 2002:a17:90b:3ec3:b0:1fa:a293:c511 with SMTP id rm3-20020a17090b3ec300b001faa293c511mr2592343pjb.156.1661248637993; Tue, 23 Aug 2022 02:57:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661248637; cv=none; d=google.com; s=arc-20160816; b=xodRd/t6TbyLStSRaqv6m7NQmqB1yzqIkMOBp37Yw+1UbPBxa7r3P74uLQfMfVOjJz 20Q3MLukKi4EsvaFVg755owK1ymQQszsLMzXGSy6/Enc1X54LKq59PIOYAy7Bw9xK4bA F1da9c2xDNVTx/+J5qCJx97VIoKj1jRv84B/43pN0hRKTogdd6lhbwqLaf9MoXCaPgmY qVtwLMXeOZ0R29VBmptuN2Zu5Vr/z+kmx/TElbjK3n4PYR+1/9gCqzZ31XDSJEWqMvXH TtKPqoob+AHQLKZN1Oe9MelyXaZLnQRlHxlbTeThsJcDrG0wra45GsGw1hIOJncAXW6C rvug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=AkMTohhhOveJIxpBStU9ts7FWQ3mzj1YoUYwMViPy6w=; b=WXKhdNg4k3QdAYm9+iu84MrfJod2mCVQwuTU7HFXGCpeeCeaAPI0khaRD+ns5orORa MiYcAE/pBpT+1jzQ4gS1klFgiEzjcNqDiBw7loxNYFJrz7BLyh15LgUCaWR7gSnHDG9Q 6Nr+Cp3wg7crzFR98bCZZos1HLzuzwueMOBIrU7cJT9dh3K6pYSAtolI0lOinuPPVTdi ABYILjSa+Y4Oh6oohNcSSYVYTULKC3GyTl+hJBByAkVK23xgQbYlJRDkvcEvTICotQP0 Jqr5MN59gZJWxa3nP2f+7AwSi14n5lnbMkF7MCs1q1v7cKL09Sa4yS0PT9FYyGRwzaXI oHNQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=JMviMhyC; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t185-20020a6381c2000000b0042a37db75f6si10972483pgd.535.2022.08.23.02.57.06; Tue, 23 Aug 2022 02:57:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=JMviMhyC; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351291AbiHWJjL (ORCPT + 99 others); Tue, 23 Aug 2022 05:39:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1351276AbiHWJiW (ORCPT ); Tue, 23 Aug 2022 05:38:22 -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 C1B6469F48; Tue, 23 Aug 2022 01:40:59 -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 6CF8EB81C62; Tue, 23 Aug 2022 08:39:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B1D1CC433D6; Tue, 23 Aug 2022 08:39:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1661243980; bh=ZUgivN8zhNC9/Vowk6oVJLvlCbVPWbn1Iq8fxa3fI6I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JMviMhyCdG+yCk0OS6r9kUhpFOBX47cgs9daJMRptZwJYZGMUK1f1sfKhoLd04VTX ZIN3AM8H3Wy00rLQEOLC2o/rwjHEaQnEhC9HSvfFaJckDncTFlPMg2KeMBPK6DRh21 JUqtWAEFC482h4QQttgEN3mg/T6xBnZivYEAnvH8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, stable , Alan Stern , Weitao Wang Subject: [PATCH 4.14 037/229] USB: HCD: Fix URB giveback issue in tasklet function Date: Tue, 23 Aug 2022 10:23:18 +0200 Message-Id: <20220823080054.902065549@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220823080053.202747790@linuxfoundation.org> References: <20220823080053.202747790@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Weitao Wang commit 26c6c2f8a907c9e3a2f24990552a4d77235791e6 upstream. Usb core introduce the mechanism of giveback of URB in tasklet context to reduce hardware interrupt handling time. On some test situation(such as FIO with 4KB block size), when tasklet callback function called to giveback URB, interrupt handler add URB node to the bh->head list also. If check bh->head list again after finish all URB giveback of local_list, then it may introduce a "dynamic balance" between giveback URB and add URB to bh->head list. This tasklet callback function may not exit for a long time, which will cause other tasklet function calls to be delayed. Some real-time applications(such as KB and Mouse) will see noticeable lag. In order to prevent the tasklet function from occupying the cpu for a long time at a time, new URBS will not be added to the local_list even though the bh->head list is not empty. But also need to ensure the left URB giveback to be processed in time, so add a member high_prio for structure giveback_urb_bh to prioritize tasklet and schelule this tasklet again if bh->head list is not empty. At the same time, we are able to prioritize tasklet through structure member high_prio. So, replace the local high_prio_bh variable with this structure member in usb_hcd_giveback_urb. Fixes: 94dfd7edfd5c ("USB: HCD: support giveback of URB in tasklet context") Cc: stable Reviewed-by: Alan Stern Signed-off-by: Weitao Wang Link: https://lore.kernel.org/r/20220726074918.5114-1-WeitaoWang-oc@zhaoxin.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 26 +++++++++++++++----------- include/linux/usb/hcd.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1814,7 +1814,6 @@ static void usb_giveback_urb_bh(unsigned spin_lock_irq(&bh->lock); bh->running = true; - restart: list_replace_init(&bh->head, &local_list); spin_unlock_irq(&bh->lock); @@ -1828,10 +1827,17 @@ static void usb_giveback_urb_bh(unsigned bh->completing_ep = NULL; } - /* check if there are new URBs to giveback */ + /* + * giveback new URBs next time to prevent this function + * from not exiting for a long time. + */ spin_lock_irq(&bh->lock); - if (!list_empty(&bh->head)) - goto restart; + if (!list_empty(&bh->head)) { + if (bh->high_prio) + tasklet_hi_schedule(&bh->bh); + else + tasklet_schedule(&bh->bh); + } bh->running = false; spin_unlock_irq(&bh->lock); } @@ -1856,7 +1862,7 @@ static void usb_giveback_urb_bh(unsigned void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) { struct giveback_urb_bh *bh; - bool running, high_prio_bh; + bool running; /* pass status to tasklet via unlinked */ if (likely(!urb->unlinked)) @@ -1867,13 +1873,10 @@ void usb_hcd_giveback_urb(struct usb_hcd return; } - if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) { + if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) bh = &hcd->high_prio_bh; - high_prio_bh = true; - } else { + else bh = &hcd->low_prio_bh; - high_prio_bh = false; - } spin_lock(&bh->lock); list_add_tail(&urb->urb_list, &bh->head); @@ -1882,7 +1885,7 @@ void usb_hcd_giveback_urb(struct usb_hcd if (running) ; - else if (high_prio_bh) + else if (bh->high_prio) tasklet_hi_schedule(&bh->bh); else tasklet_schedule(&bh->bh); @@ -2900,6 +2903,7 @@ int usb_add_hcd(struct usb_hcd *hcd, /* initialize tasklets */ init_giveback_urb_bh(&hcd->high_prio_bh); + hcd->high_prio_bh.high_prio = true; init_giveback_urb_bh(&hcd->low_prio_bh); /* enable irqs just before we start the controller, --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -65,6 +65,7 @@ struct giveback_urb_bh { bool running; + bool high_prio; spinlock_t lock; struct list_head head; struct tasklet_struct bh;