Received: by 2002:ac0:e34a:0:0:0:0:0 with SMTP id g10csp501706imn; Tue, 26 Jul 2022 01:27:47 -0700 (PDT) X-Google-Smtp-Source: AGRyM1v05QSaD7vSoBX6lJygbmJZ3DvStuFvN3lTIRXAOUhWgsv2+0kbCMPmR/9ZZNcmDrvl3Tl3 X-Received: by 2002:a17:902:f60c:b0:16d:1af0:6656 with SMTP id n12-20020a170902f60c00b0016d1af06656mr16040267plg.153.1658824067154; Tue, 26 Jul 2022 01:27:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658824067; cv=none; d=google.com; s=arc-20160816; b=y6NVUMRJuBnbdPLXyTTsaRb5ccL/ymZDNRF1hQcxwfH7NlBWzInKA+cUvCqkRp6dwv gtLGGE+f8p/7hZxvJmtyFh5OsazOqFdYeqbSTOfs33atuqxAtn8RZ65JdXEiLsFOtwrp nZ7BR7poVp2vMj5B4rP2WjFR2Gip7KVwc/zDErsaJxIt/yI726xCzfSFG8vBXRk16sw6 jwXzQyPbOqTADmfrHqvop4vmGk50HGbPTFZYvlMNjm85AVYUcYUS6ALH7pLkuBhVxEwq YzWXeAAtRevJdI+4rCewoZf0mC9RH/ZM4ji/YEGwnLQe++t6DJy9D8fT5iiWjDwTyA3G MciA== 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 :message-id:date:subject:cc:to:from; bh=mOc/EPJ/uqCSCmU5KBOyT8r342aWJjz1czrqBRLH0q8=; b=F0KfL0Syl7Yj2Aygr6Hg0SiDc/CfwTziaQSs6L5ygyk09ABNld9C0o7+Znk6OyslBJ N+tAUjLhWMLkLDKUBb81Tc1XHM9Z0nx/+sQdjEertXVWo4mlxJ6l9vPMpcJlzy2CW1uM bBvfBmT09Wz1FSc8Yp8H2m6cUo4e6z0eCDZNheQLS0wONNjNAW8SuwalsUcVQWpMwiNr mOa3XG9KzK9UsP8NONQ4c1A5kBtPBU7u5eulZLMzfYut+oB0iVk006+Sk64DisFAIOwP /OqrDuTRFck2QLaTPso+aHQOrGWu9wlAHVaJuBEgAmr1EJDLkKfIfbo3ABW+JOjS47b0 JnOw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j192-20020a636ec9000000b0041a4cfc72fdsi17404526pgc.196.2022.07.26.01.27.32; Tue, 26 Jul 2022 01:27:47 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238384AbiGZHvB (ORCPT + 99 others); Tue, 26 Jul 2022 03:51:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237911AbiGZHu7 (ORCPT ); Tue, 26 Jul 2022 03:50:59 -0400 Received: from ZXSHCAS1.zhaoxin.com (ZXSHCAS1.zhaoxin.com [210.0.225.54]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD7241EAFF; Tue, 26 Jul 2022 00:50:57 -0700 (PDT) Received: from zxbjmbx1.zhaoxin.com (10.29.252.163) by ZXSHCAS1.zhaoxin.com (10.28.252.161) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.27; Tue, 26 Jul 2022 15:49:19 +0800 Received: from L440.zhaoxin.com (10.29.8.21) by zxbjmbx1.zhaoxin.com (10.29.252.163) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.27; Tue, 26 Jul 2022 15:49:19 +0800 From: Weitao Wang To: , , , , , , , , CC: , Subject: [PATCH v3] USB: HCD: Fix URB giveback issue in tasklet function Date: Tue, 26 Jul 2022 15:49:18 +0800 Message-ID: <20220726074918.5114-1-WeitaoWang-oc@zhaoxin.com> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.29.8.21] X-ClientProxiedBy: zxbjmbx1.zhaoxin.com (10.29.252.163) To zxbjmbx1.zhaoxin.com (10.29.252.163) X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS 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 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") Signed-off-by: Weitao Wang --- v2->v3 - Add more detail info about how to patch this issue. - Change initial value of boolean variable high_prio from 1 to true. drivers/usb/core/hcd.c | 26 +++++++++++++++----------- include/linux/usb/hcd.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 06eea8848ccc..11c8ea0cccc8 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1691,7 +1691,6 @@ static void usb_giveback_urb_bh(struct tasklet_struct *t) spin_lock_irq(&bh->lock); bh->running = true; - restart: list_replace_init(&bh->head, &local_list); spin_unlock_irq(&bh->lock); @@ -1705,10 +1704,17 @@ static void usb_giveback_urb_bh(struct tasklet_struct *t) 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); } @@ -1737,7 +1743,7 @@ static void usb_giveback_urb_bh(struct tasklet_struct *t) 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)) @@ -1748,13 +1754,10 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) 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); @@ -1763,7 +1766,7 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) if (running) ; - else if (high_prio_bh) + else if (bh->high_prio) tasklet_hi_schedule(&bh->bh); else tasklet_schedule(&bh->bh); @@ -2959,6 +2962,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, diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 2c1fc9212cf2..98d1921f02b1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -66,6 +66,7 @@ struct giveback_urb_bh { bool running; + bool high_prio; spinlock_t lock; struct list_head head; struct tasklet_struct bh; -- 2.32.0