From patchwork Thu Aug 26 02:51:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?= X-Patchwork-Id: 12458913 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8BE0C432BE for ; Thu, 26 Aug 2021 03:00:27 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 84E47610A6 for ; Thu, 26 Aug 2021 03:00:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 84E47610A6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:CC :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=DjCRwjtCOfBTm/8JkahEpHmA5UT7g5iIwlop2sVvf0E=; b=lVrW5M8iEGJ4FF ixjWAHhtFu21WBkHfzD7jRAAwCuxmKC6lIG6qNEXq05BqhtabDQHkktF+4QkrosysdTJQqZwk0JmU fDsja0vqbjjXVLyL8lxmDWKlMq8R14AaJji34soGAmS/jpsTX7iVLChVIEg+y1WfDvbCcyFTGWg8y BGkRkAXEpzlAl25+et1Gd/hgw9jqy03EtUhytEOpNY/heDI379QGy7ZZE6NjZHYAMY18cQW/WgvH6 6IIVGnakQO5Fq4NAnVKdwwMyV+gsV2I49bil/GXTMzaZINUHgxBVaIQatTzEmaVfOF2wQc0pRbKZq p8/qSdLTet/w+FZuOlgA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5at-008zXR-53; Thu, 26 Aug 2021 02:58:19 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5aP-008zOQ-B0; Thu, 26 Aug 2021 02:57:51 +0000 X-UUID: 5e05649fb82f4e088b57b071e5118b36-20210825 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=p9i4YiIS7Lw15WLlNv7dk0L02rgKPYBgvalVs3OcbX4=; b=t699I/AQBW+Zz8r1tub+RKnPH0yS4YymaCNg/9BYR9D1bki574I/NiR8skzRdjTB1Ab2ZosC4awmcXd0jvabwQLzxqjllHJ/Imt3CQ5n3SYzQd80WVjxEHTfBvogOGXJyTSeeSg9fEDxlWxsvzCbs0CgvJAVC3vOtNpsnYhAqpo=; X-UUID: 5e05649fb82f4e088b57b071e5118b36-20210825 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 399012743; Wed, 25 Aug 2021 19:57:45 -0700 Received: from mtkexhb02.mediatek.inc (172.21.101.103) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 25 Aug 2021 19:52:07 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkexhb02.mediatek.inc (172.21.101.103) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 26 Aug 2021 10:52:00 +0800 Received: from mtkslt301.mediatek.inc (10.21.14.114) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 26 Aug 2021 10:51:59 +0800 From: Chunfeng Yun To: Mathias Nyman , Greg Kroah-Hartman CC: Chunfeng Yun , Matthias Brugger , , , , , Ikjoon Jang , Eddie Hung , Yaqii wu Subject: [PATCH next v2 1/6] Revert "usb: xhci-mtk: relax TT periodic bandwidth allocation" Date: Thu, 26 Aug 2021 10:51:39 +0800 Message-ID: <20210826025144.51992-1-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210825_195749_476229_C9969904 X-CRM114-Status: GOOD ( 13.02 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org As discussed in following patch: https://patchwork.kernel.org/patch/12420339 No need calculate number of uframes again, but should use value form check_sch_tt(), if we plan to remove extra CS, also can do it in check_sch_tt(). So revert this patch, and prepare to send new patch for it. This reverts commit 548011957d1d72e0b662300c8b32b81d593b796e. Cc: Ikjoon Jang Signed-off-by: Chunfeng Yun --- v2: no changes --- drivers/usb/host/xhci-mtk-sch.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 46cbf5d54f4f..f9b4d27ce449 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -459,17 +459,16 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) u32 num_esit, tmp; int base; int i, j; - u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; - - if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP) - offset++; - for (i = 0; i < num_esit; i++) { base = offset + i * sch_ep->esit; - for (j = 0; j < uframes; j++) { + /* + * Compared with hs bus, no matter what ep type, + * the hub will always delay one uframe to send data + */ + for (j = 0; j < sch_ep->cs_count; j++) { tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe; if (tmp > FS_PAYLOAD_MAX) return -ESCH_BW_OVERFLOW; @@ -547,8 +546,6 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) u32 base, num_esit; int bw_updated; int i, j; - int offset = sch_ep->offset; - u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; @@ -557,13 +554,10 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) else bw_updated = -sch_ep->bw_cost_per_microframe; - if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP) - offset++; - for (i = 0; i < num_esit; i++) { - base = offset + i * sch_ep->esit; + base = sch_ep->offset + i * sch_ep->esit; - for (j = 0; j < uframes; j++) + for (j = 0; j < sch_ep->cs_count; j++) tt->fs_bus_bw[base + j] += bw_updated; } From patchwork Thu Aug 26 02:51:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?= X-Patchwork-Id: 12458917 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27067C432BE for ; Thu, 26 Aug 2021 03:00:46 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C5127610A4 for ; Thu, 26 Aug 2021 03:00:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org C5127610A4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=aMoTD8HDIETnGLJF/Bp+DN1vfq7UtnV9cLai07cySDU=; b=3LUb3V92oz+o6W aqqGZ8h1MfoQxN5TRh1hqb6NqYJ0tULnG5r557H/edpQnYIoh2PwFzPY6/u6anRa7BkZ06BYCj9iA dK/I1YTN8tlNeZNUTqqhJu0yQJOlg4mSaUSpVhIvttg0bSbMAVVLiCC5H8BNmyot/VoTiGPOXvvW0 GRuow3bA0JzAUj0XT1a8xKRVme9I55Pc/kXNm3TWmmDFH+pMF56fTWmHDpikx0sRh7aGxcuEm55L3 HcwU5bty5/2cPbNhabH+uQrwkDSRVN2+4gQ7Vd+6ciWxARouzMjDFRIBKz4GXDE2idMiIKGUFvkUj duKLuucf+5t3XnxUvhng==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5bB-008zcK-MI; Thu, 26 Aug 2021 02:58:38 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5aQ-008zO5-SV; Thu, 26 Aug 2021 02:57:53 +0000 X-UUID: df9e097d81344f7291b7acfc7afd9811-20210825 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=lIdq3qzE+iJPOzfaWirdUMwpftXRfwC/+xRG0UkD3TU=; b=Xbsv2n4Y4un2KL4v+017rxGwHGTl6ji5mOJi262d3mCpD6BgErpzFZ9QK68jAxPvjTPStv9cVwJssXsIs61WDfAlwVdCGOY0hvFpHj27zvQR6U8b95stRQfsMZ1Se0gNIwBbnIl1CXNp3m3/ygVFOh1WwClS3S/f1XudSE8QN8o=; X-UUID: df9e097d81344f7291b7acfc7afd9811-20210825 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 2091147465; Wed, 25 Aug 2021 19:57:45 -0700 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 25 Aug 2021 19:52:07 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 26 Aug 2021 10:52:00 +0800 Received: from mtkslt301.mediatek.inc (10.21.14.114) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 26 Aug 2021 10:51:59 +0800 From: Chunfeng Yun To: Mathias Nyman , Greg Kroah-Hartman CC: Chunfeng Yun , Matthias Brugger , , , , , Ikjoon Jang , Eddie Hung , Yaqii wu Subject: [PATCH next v2 2/6] Revert "usb: xhci-mtk: Do not use xhci's virt_dev in drop_endpoint" Date: Thu, 26 Aug 2021 10:51:40 +0800 Message-ID: <20210826025144.51992-2-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com> References: <20210826025144.51992-1-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210825_195750_999185_F9E4CBA5 X-CRM114-Status: GOOD ( 23.20 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org I find the patch introduce some issues, e.g. 1. oops happens when xhci_gen_setup() failed, and hash is not init but try to destroy it; 2. memory leakage happens when fail to insert ep, need free sch_ep, or insert ep after insert int list; 3. memory leakage happens when fail to allocate sch_array, need destroy rhashtable; 4. it's better to check ep->hcpriv when drop ep; so prefer to revert this patch, and resend it after the issues are fixed. This reverts commit b8731209958a1dffccc2888121f4c0280c990550. Cc: Ikjoon Jang Signed-off-by: Chunfeng Yun --- v2: append new version patch of this one [5/6] suggested by Ikjoon --- drivers/usb/host/xhci-mtk-sch.c | 140 ++++++++++++++------------------ drivers/usb/host/xhci-mtk.h | 15 ++-- 2 files changed, 69 insertions(+), 86 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index f9b4d27ce449..cffcaf4dfa9f 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -80,7 +80,7 @@ decode_ep(struct usb_host_endpoint *ep, enum usb_device_speed speed) interval /= 1000; } - snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s", + snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s\n", usb_speed_string(speed), usb_endpoint_num(epd), usb_endpoint_dir_in(epd) ? "in" : "out", usb_ep_type_string(usb_endpoint_type(epd)), @@ -129,12 +129,6 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev, int bw_index; virt_dev = xhci->devs[udev->slot_id]; - if (WARN_ONCE(!virt_dev, "xhci-mtk: usb %s has no virt_dev\n", - dev_name(&udev->dev))) - return NULL; - if (WARN_ONCE(!virt_dev->real_port, "xhci-mtk: usb %s has invalid port number\n", - dev_name(&udev->dev))) - return NULL; if (udev->speed >= USB_SPEED_SUPER) { if (usb_endpoint_dir_out(&ep->desc)) @@ -200,6 +194,7 @@ static struct mu3h_sch_tt *find_tt(struct usb_device *udev) } return ERR_PTR(-ENOMEM); } + INIT_LIST_HEAD(&tt->ep_list); *ptt = tt; } @@ -229,7 +224,7 @@ static void drop_tt(struct usb_device *udev) } tt = *ptt; - if (!tt || tt->nr_eps > 0) + if (!tt || !list_empty(&tt->ep_list)) return; /* never allocated , or still in use*/ *ptt = NULL; @@ -241,19 +236,13 @@ static void drop_tt(struct usb_device *udev) } } -static struct mu3h_sch_ep_info *create_sch_ep(struct xhci_hcd_mtk *mtk, - struct usb_device *udev, struct usb_host_endpoint *ep, - struct xhci_ep_ctx *ep_ctx) +static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, + struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) { struct mu3h_sch_ep_info *sch_ep; struct mu3h_sch_tt *tt = NULL; u32 len_bw_budget_table; size_t mem_size; - struct mu3h_sch_bw_info *bw_info; - - bw_info = get_bw_info(mtk, udev, ep); - if (!bw_info) - return ERR_PTR(-ENODEV); if (is_fs_or_ls(udev->speed)) len_bw_budget_table = TT_MICROFRAMES_MAX; @@ -277,10 +266,11 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct xhci_hcd_mtk *mtk, } } - sch_ep->bw_info = bw_info; sch_ep->sch_tt = tt; sch_ep->ep = ep; sch_ep->speed = udev->speed; + INIT_LIST_HEAD(&sch_ep->endpoint); + INIT_LIST_HEAD(&sch_ep->tt_endpoint); return sch_ep; } @@ -562,9 +552,9 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) } if (used) - tt->nr_eps++; - else if (!WARN_ONCE(tt->nr_eps < 1, "unbalanced sch_tt's ep count")) - tt->nr_eps--; + list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list); + else + list_del(&sch_ep->tt_endpoint); } static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw, @@ -595,9 +585,9 @@ static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep) return boundary; } -static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) +static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw, + struct mu3h_sch_ep_info *sch_ep) { - struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info; const u32 esit_boundary = get_esit_boundary(sch_ep); const u32 bw_boundary = get_bw_boundary(sch_ep->speed); u32 offset; @@ -643,33 +633,23 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) return load_ep_bw(sch_bw, sch_ep, true); } -static const struct rhashtable_params sch_ep_table_param = { - .key_len = sizeof(struct usb_host_endpoint *), - .key_offset = offsetof(struct mu3h_sch_ep_info, ep), - .head_offset = offsetof(struct mu3h_sch_ep_info, ep_link), -}; - -static void destroy_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, - struct mu3h_sch_ep_info *sch_ep) +static void destroy_sch_ep(struct usb_device *udev, + struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) { /* only release ep bw check passed by check_sch_bw() */ if (sch_ep->allocated) - load_ep_bw(sch_ep->bw_info, sch_ep, false); + load_ep_bw(sch_bw, sch_ep, false); if (sch_ep->sch_tt) drop_tt(udev); list_del(&sch_ep->endpoint); - rhashtable_remove_fast(&mtk->sch_ep_table, &sch_ep->ep_link, - sch_ep_table_param); kfree(sch_ep); } -static bool need_bw_sch(struct usb_device *udev, - struct usb_host_endpoint *ep) +static bool need_bw_sch(struct usb_host_endpoint *ep, + enum usb_device_speed speed, int has_tt) { - bool has_tt = udev->tt && udev->tt->hub->parent; - /* only for periodic endpoints */ if (usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_bulk(&ep->desc)) @@ -680,7 +660,7 @@ static bool need_bw_sch(struct usb_device *udev, * a TT are also ignored, root-hub will schedule them directly, * but need set @bpkts field of endpoint context to 1. */ - if (is_fs_or_ls(udev->speed) && !has_tt) + if (is_fs_or_ls(speed) && !has_tt) return false; /* skip endpoint with zero maxpkt */ @@ -695,12 +675,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); struct mu3h_sch_bw_info *sch_array; int num_usb_bus; - int ret; - - /* mu3h_sch_ep_info table, 'usb_host_endpoint*' as a key */ - ret = rhashtable_init(&mtk->sch_ep_table, &sch_ep_table_param); - if (ret) - return ret; + int i; /* ss IN and OUT are separated */ num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports; @@ -709,6 +684,9 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) if (sch_array == NULL) return -ENOMEM; + for (i = 0; i < num_usb_bus; i++) + INIT_LIST_HEAD(&sch_array[i].bw_ep_list); + mtk->sch_array = sch_array; INIT_LIST_HEAD(&mtk->bw_ep_chk_list); @@ -718,7 +696,6 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk) { - rhashtable_destroy(&mtk->sch_ep_table); kfree(mtk->sch_array); } @@ -736,7 +713,9 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); - if (!need_bw_sch(udev, ep)) { + xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); + + if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) { /* * set @bpkts to 1 if it is LS or FS periodic endpoint, and its * device does not connected through an external HS hub @@ -748,22 +727,14 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, return 0; } - xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); - - sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx); + sch_ep = create_sch_ep(udev, ep, ep_ctx); if (IS_ERR_OR_NULL(sch_ep)) return -ENOMEM; - if (rhashtable_insert_fast(&mtk->sch_ep_table, &sch_ep->ep_link, - sch_ep_table_param)) - return -EEXIST; - setup_sch_info(ep_ctx, sch_ep); list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list); - xhci_dbg(xhci, "added sch_ep %p : %p\n", sch_ep, ep); - return 0; } @@ -772,20 +743,25 @@ static void drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, { struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct mu3h_sch_ep_info *sch_ep; - void *key = ep; + struct xhci_virt_device *virt_dev; + struct mu3h_sch_bw_info *sch_bw; + struct mu3h_sch_ep_info *sch_ep, *tmp; - if (!need_bw_sch(udev, ep)) - return; + virt_dev = xhci->devs[udev->slot_id]; xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); - sch_ep = rhashtable_lookup_fast(&mtk->sch_ep_table, &key, - sch_ep_table_param); - if (sch_ep) - destroy_sch_ep(mtk, udev, sch_ep); - else - xhci_dbg(xhci, "ep %p is not on the bw table\n", ep); + if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) + return; + + sch_bw = get_bw_info(mtk, udev, ep); + + list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { + if (sch_ep->ep == ep) { + destroy_sch_ep(udev, sch_bw, sch_ep); + break; + } + } } int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) @@ -793,22 +769,30 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; - struct mu3h_sch_ep_info *sch_ep; + struct mu3h_sch_bw_info *sch_bw; + struct mu3h_sch_ep_info *sch_ep, *tmp; int ret; xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) { - struct xhci_ep_ctx *ep_ctx; - struct usb_host_endpoint *ep = sch_ep->ep; - unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); + sch_bw = get_bw_info(mtk, udev, sch_ep->ep); - ret = check_sch_bw(sch_ep); + ret = check_sch_bw(sch_bw, sch_ep); if (ret) { xhci_err(xhci, "Not enough bandwidth! (%s)\n", sch_error_string(-ret)); return -ENOSPC; } + } + + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { + struct xhci_ep_ctx *ep_ctx; + struct usb_host_endpoint *ep = sch_ep->ep; + unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); + + sch_bw = get_bw_info(mtk, udev, ep); + list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts) @@ -822,23 +806,22 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) sch_ep->offset, sch_ep->repeat); } - ret = xhci_check_bandwidth(hcd, udev); - if (!ret) - INIT_LIST_HEAD(&mtk->bw_ep_chk_list); - - return ret; + return xhci_check_bandwidth(hcd, udev); } void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) { struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct mu3h_sch_bw_info *sch_bw; struct mu3h_sch_ep_info *sch_ep, *tmp; xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); - list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) - destroy_sch_ep(mtk, udev, sch_ep); + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { + sch_bw = get_bw_info(mtk, udev, sch_ep->ep); + destroy_sch_ep(udev, sch_bw, sch_ep); + } xhci_reset_bandwidth(hcd, udev); } @@ -867,7 +850,8 @@ int xhci_mtk_drop_ep(struct usb_hcd *hcd, struct usb_device *udev, if (ret) return ret; - drop_ep_quirk(hcd, udev, ep); + if (ep->hcpriv) + drop_ep_quirk(hcd, udev, ep); return 0; } diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index ddcf25524f67..ace432356c41 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -10,7 +10,6 @@ #define _XHCI_MTK_H_ #include -#include #include "xhci.h" @@ -26,34 +25,36 @@ /** * @fs_bus_bw: array to keep track of bandwidth already used for FS - * @nr_eps: number of endpoints using this TT + * @ep_list: Endpoints using this TT */ struct mu3h_sch_tt { u32 fs_bus_bw[XHCI_MTK_MAX_ESIT]; - int nr_eps; + struct list_head ep_list; }; /** * struct mu3h_sch_bw_info: schedule information for bandwidth domain * * @bus_bw: array to keep track of bandwidth already used at each uframes + * @bw_ep_list: eps in the bandwidth domain * * treat a HS root port as a bandwidth domain, but treat a SS root port as * two bandwidth domains, one for IN eps and another for OUT eps. */ struct mu3h_sch_bw_info { u32 bus_bw[XHCI_MTK_MAX_ESIT]; + struct list_head bw_ep_list; }; /** * struct mu3h_sch_ep_info: schedule information for endpoint * - * @bw_info: bandwidth domain which this endpoint belongs * @esit: unit is 125us, equal to 2 << Interval field in ep-context * @num_budget_microframes: number of continuous uframes * (@repeat==1) scheduled within the interval * @bw_cost_per_microframe: bandwidth cost per microframe - * @endpoint: linked into bw_ep_chk_list, used by check_bandwidth hook + * @endpoint: linked into bandwidth domain which it belongs to + * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to * @sch_tt: mu3h_sch_tt linked into * @ep_type: endpoint type * @maxpkt: max packet size of endpoint @@ -81,12 +82,11 @@ struct mu3h_sch_ep_info { u32 num_budget_microframes; u32 bw_cost_per_microframe; struct list_head endpoint; - struct mu3h_sch_bw_info *bw_info; + struct list_head tt_endpoint; struct mu3h_sch_tt *sch_tt; u32 ep_type; u32 maxpkt; struct usb_host_endpoint *ep; - struct rhash_head ep_link; enum usb_device_speed speed; bool allocated; /* @@ -134,7 +134,6 @@ struct xhci_hcd_mtk { struct device *dev; struct usb_hcd *hcd; struct mu3h_sch_bw_info *sch_array; - struct rhashtable sch_ep_table; struct list_head bw_ep_chk_list; struct mu3c_ippc_regs __iomem *ippc_regs; int num_u2_ports; From patchwork Thu Aug 26 02:51:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?= X-Patchwork-Id: 12458903 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB5B3C43214 for ; Thu, 26 Aug 2021 02:54:32 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A85C9610C9 for ; Thu, 26 Aug 2021 02:54:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A85C9610C9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=fxRv0fv6fiRVN4XfbNZdVE0Gu9wu0AKBCIOriREOwUQ=; b=H18WtWLKSi3Xcy NP8Mj+3xF0iDRWYw6aESgzjUczZGEHQ4FVdb6QmvWDh3vuKgeWCLIBVXFLGkhNf7Gg45aRw6WCOUg dhe/u8uSsBr6CFy+zVhDALTmpd1BaH81a1g1t40TVMy/YwCym2HfUfgddsvNvkPYLmRC59dXEmJ7J YnXalDpkeVmp63xmrixwDKEJDEmhrpOdgei1S1GvzMh2Z6h0Ecxr0wqM1AFsAodTprhjGSE3JsNtQ Rkp1Ln0LgGf6c96DJW5pYM65twfKutHTodDRnnAcrIH0CKVGoQkERNARDqtOIxfGIbQmwt3FHYvmU b0fx/seLNiQ8b1g6IxCw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5V9-008xnn-UT; Thu, 26 Aug 2021 02:52:24 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5Us-008xjb-Bw; Thu, 26 Aug 2021 02:52:10 +0000 X-UUID: 8472f3e41805441aac7e603ae06eb29c-20210825 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=ZXDJ0TE6N08HnmOOJMB2bdokcDG9hkhnn+Apj3hRgRU=; b=TRZbafnXytUgdJnPfhAnI8z/J5yh0FYiVKY8rlYi3zEtbxE7gt0oBMJ3lfzGZbwmbnNVhRyMpCD30Pr+2oCJN8DL8p8uYAmiN3UtISFEmZMudpnB5pEEZEDb/Z5eT7LVaJjHyjbjY8IJL8MMUA7vFcq1qWM8nsFkUMS1L2BcPLY=; X-UUID: 8472f3e41805441aac7e603ae06eb29c-20210825 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 839315995; Wed, 25 Aug 2021 19:52:03 -0700 Received: from MTKMBS06N1.mediatek.inc (172.21.101.129) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 25 Aug 2021 19:52:01 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs06n1.mediatek.inc (172.21.101.129) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 26 Aug 2021 10:52:00 +0800 Received: from mtkslt301.mediatek.inc (10.21.14.114) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 26 Aug 2021 10:51:59 +0800 From: Chunfeng Yun To: Mathias Nyman , Greg Kroah-Hartman CC: Chunfeng Yun , Matthias Brugger , , , , , Ikjoon Jang , Eddie Hung , Yaqii wu Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by bw_budget_table Date: Thu, 26 Aug 2021 10:51:41 +0800 Message-ID: <20210826025144.51992-3-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com> References: <20210826025144.51992-1-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210825_195206_506486_1CC4182A X-CRM114-Status: GOOD ( 13.31 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Use @bw_budget_table[] to update fs bus bandwidth due to not all microframes consume @bw_cost_per_microframe, see setup_sch_info(). Signed-off-by: Chunfeng Yun --- v2: new patch, move from another series --- drivers/usb/host/xhci-mtk-sch.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index cffcaf4dfa9f..83abd28269ca 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) * Compared with hs bus, no matter what ep type, * the hub will always delay one uframe to send data */ - for (j = 0; j < sch_ep->cs_count; j++) { - tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe; + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j]; if (tmp > FS_PAYLOAD_MAX) return -ESCH_BW_OVERFLOW; } @@ -534,21 +534,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) { struct mu3h_sch_tt *tt = sch_ep->sch_tt; u32 base, num_esit; - int bw_updated; int i, j; num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; - if (used) - bw_updated = sch_ep->bw_cost_per_microframe; - else - bw_updated = -sch_ep->bw_cost_per_microframe; - for (i = 0; i < num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; - for (j = 0; j < sch_ep->cs_count; j++) - tt->fs_bus_bw[base + j] += bw_updated; + for (j = 0; j < sch_ep->num_budget_microframes; j++) + if (used) + tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j]; + else + tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j]; } if (used) From patchwork Thu Aug 26 02:51:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?= X-Patchwork-Id: 12458915 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 247D6C432BE for ; Thu, 26 Aug 2021 03:00:31 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CD0EA610A4 for ; Thu, 26 Aug 2021 03:00:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CD0EA610A4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QMA4pbyEebSfkWQdy8sOpnbOPfzLCGxfLy21G7kU6ro=; b=xSCrf0IE3cDeh0 CHwKSZGUBQGpUCArnEyQ7mmZW4aOPph+zTkXz5mkzdMN168l20/j/Pau5sETAvFI1urdNh1SutN6p FjfARRTkRZogN1YlR22VvYOLnSPzdUNLcIobG+3TYJqWVDa/odYPJXzJl9IEswanC+rUCgz4o9YuL C19vc8XqMW5gN0/he+kW+yBn8JAN4aSC5EfoABXD+FEzj7DdDq/JZ5A0s4CbNX0KWH9DnLp+aY/af MKAlOk4kFKXBbIuUNdpKLq783BqYlZaSeI2wFWS/6YEHkfrV/OhFS6OE56VvUNcvcyYrdTrDyuOsZ Z97qgC0MeleZthovGFAQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5aZ-008zQy-EX; Thu, 26 Aug 2021 02:57:59 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5aO-008zO5-HD; Thu, 26 Aug 2021 02:57:50 +0000 X-UUID: edde8020baa445fcadc197d2758c63bf-20210825 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=6XtOPNS3POWy2Xr0MrmzunCfC0hrpQH6ItGCXj6Y49I=; b=BUCsTSs+j5D5uUKb85rlXCN95lhUALKFCU6ihvewVdLVk/23dcepnJjUDIRej5JxdIxlbVrqzU25jqxRUZw0FS7hnlo8wRvvEMT831nCYNCVSOeF+UcxwKBk/7fJc++OaYX6cwHM7UCTzJI5ZzurnrKIGJghjpdzy/l/oPXp6rI=; X-UUID: edde8020baa445fcadc197d2758c63bf-20210825 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1084293157; Wed, 25 Aug 2021 19:57:45 -0700 Received: from mtkmbs05n2.mediatek.inc (172.21.101.140) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 25 Aug 2021 19:52:01 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 26 Aug 2021 10:52:00 +0800 Received: from mtkslt301.mediatek.inc (10.21.14.114) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 26 Aug 2021 10:52:00 +0800 From: Chunfeng Yun To: Mathias Nyman , Greg Kroah-Hartman CC: Chunfeng Yun , Matthias Brugger , , , , , Ikjoon Jang , Eddie Hung , Yaqii wu Subject: [PATCH next v2 4/6] usb: xhci-mtk: add a member of num_esit Date: Thu, 26 Aug 2021 10:51:42 +0800 Message-ID: <20210826025144.51992-4-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com> References: <20210826025144.51992-1-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210825_195748_637334_73222064 X-CRM114-Status: GOOD ( 14.81 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a member num_esit to save the number of esit, then no need caculate it in some functions. Signed-off-by: Chunfeng Yun --- v2: new patch, move from another series --- drivers/usb/host/xhci-mtk-sch.c | 20 +++++++------------- drivers/usb/host/xhci-mtk.h | 2 ++ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 83abd28269ca..54c521524bfc 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -297,6 +297,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info)); sch_ep->esit = get_esit(ep_ctx); + sch_ep->num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; sch_ep->ep_type = ep_type; sch_ep->maxpkt = maxpkt; sch_ep->offset = 0; @@ -401,14 +402,12 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep, u32 offset) { - u32 num_esit; u32 max_bw = 0; u32 bw; int i; int j; - num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; - for (i = 0; i < num_esit; i++) { + for (i = 0; i < sch_ep->num_esit; i++) { u32 base = offset + i * sch_ep->esit; for (j = 0; j < sch_ep->num_budget_microframes; j++) { @@ -424,13 +423,11 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep, bool used) { - u32 num_esit; u32 base; int i; int j; - num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; - for (i = 0; i < num_esit; i++) { + for (i = 0; i < sch_ep->num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; for (j = 0; j < sch_ep->num_budget_microframes; j++) { if (used) @@ -446,12 +443,11 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) { struct mu3h_sch_tt *tt = sch_ep->sch_tt; - u32 num_esit, tmp; + u32 tmp; int base; int i, j; - num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; - for (i = 0; i < num_esit; i++) { + for (i = 0; i < sch_ep->num_esit; i++) { base = offset + i * sch_ep->esit; /* @@ -533,12 +529,10 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) { struct mu3h_sch_tt *tt = sch_ep->sch_tt; - u32 base, num_esit; + u32 base; int i, j; - num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; - - for (i = 0; i < num_esit; i++) { + for (i = 0; i < sch_ep->num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; for (j = 0; j < sch_ep->num_budget_microframes; j++) diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index ace432356c41..eb05aaf6edbe 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -50,6 +50,7 @@ struct mu3h_sch_bw_info { * struct mu3h_sch_ep_info: schedule information for endpoint * * @esit: unit is 125us, equal to 2 << Interval field in ep-context + * @num_esit: number of @esit in a period * @num_budget_microframes: number of continuous uframes * (@repeat==1) scheduled within the interval * @bw_cost_per_microframe: bandwidth cost per microframe @@ -79,6 +80,7 @@ struct mu3h_sch_bw_info { */ struct mu3h_sch_ep_info { u32 esit; + u32 num_esit; u32 num_budget_microframes; u32 bw_cost_per_microframe; struct list_head endpoint; From patchwork Thu Aug 26 02:51:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?= X-Patchwork-Id: 12458905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0381C432BE for ; Thu, 26 Aug 2021 02:54:50 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BC18F60FE6 for ; Thu, 26 Aug 2021 02:54:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BC18F60FE6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=hQXXAaMY+s2JWG9/8idivAHfrjBqpdGSdQa6viAIXLU=; b=lRCEB+5qgHEFdJ nwlOFC0YyNRUCwf9K1L3kVHZH370K0f0NIMDaVUNHc3+ca59RFwbN52zver8zPLGNfpob+TzNdFwX gzdDpq0QXyyzYbedvj0C2MoC7x2p+Hzq2r4uucMI+WYayGqlW8pT5sqwDM6Oiny9szr+5Tb3v8WHC tq7KjT75x+rFToEhyFNnpWZOU7QRoQVNBID9F/Qq09dC2cSIwnsBwsyiyQIHLG+rw9jIewwpqZX1Q GnVkiN2gaQobxkTPDfR/NzgOS2l0TNr1yAHQzyOHfUTtO6ze95mCTjb/+42O7nkJv0aP9I8sxhN/7 0UKf/FVU7Lho2fePGL/Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5VN-008xqd-1T; Thu, 26 Aug 2021 02:52:37 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5Uw-008xjb-Ai; Thu, 26 Aug 2021 02:52:14 +0000 X-UUID: 80158051abae4eaa8198e06cfc42ba3b-20210825 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=v8UZVmjXkzX/yxquU05a/xUFgMJsgZMIDod3DcQBpfY=; b=DbKHnN4qSCu6ifuCZmZ6wc8c0ki04p4Wq7jgqjvVF2E6HjRSFsrniviNnGzMPniTCjTjYdMPks8dP5kiDnhxrtXYdAq8feWup15IIaK4ppotoW0jq9ANi8si2a4XwLzQ8H+uWpmdBZVpmBrfMtJbkFpie6wiGtLVAuySwIII9UI=; X-UUID: 80158051abae4eaa8198e06cfc42ba3b-20210825 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 29573607; Wed, 25 Aug 2021 19:52:03 -0700 Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 25 Aug 2021 19:52:02 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 26 Aug 2021 10:52:00 +0800 Received: from mtkslt301.mediatek.inc (10.21.14.114) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 26 Aug 2021 10:52:00 +0800 From: Chunfeng Yun To: Mathias Nyman , Greg Kroah-Hartman CC: Chunfeng Yun , Matthias Brugger , , , , , Ikjoon Jang , Eddie Hung , Yaqii wu Subject: [PATCH next v2 5/6] usb: xhci-mtk: Do not use xhci's virt_dev in drop_endpoint Date: Thu, 26 Aug 2021 10:51:43 +0800 Message-ID: <20210826025144.51992-5-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com> References: <20210826025144.51992-1-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210825_195210_416179_C60C5983 X-CRM114-Status: GOOD ( 22.26 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org xhci-mtk depends on xhci's internal virt_dev when it retrieves its internal data from usb_host_endpoint both in add_endpoint and drop_endpoint callbacks. But when setup packet was retired by transaction errors in xhci_setup_device() path, a virt_dev for the slot is newly created with real_port 0. This leads to xhci-mtks's NULL pointer dereference from drop_endpoint callback as xhci-mtk assumes that virt_dev's real_port is always started from one. The similar problems were addressed by [1] but that can't cover the failure cases from setup_device. This patch drops the usages of xhci's virt_dev in xhci-mtk's drop_endpoint callback by adopting hashtable for searching mtk's schedule entity from a given usb_host_endpoint pointer instead of searching a linked list. So mtk's drop_endpoint callback doesn't have to rely on virt_dev at all. [1] f351f4b63dac ("usb: xhci-mtk: fix oops when unbind driver") Signed-off-by: Ikjoon Jang Signed-off-by: Chunfeng Yun --- v2: use fixed size hash table instead of rhashtable; fix some issues as described in this series [2/6] --- drivers/usb/host/xhci-mtk-sch.c | 100 ++++++++++++++++---------------- drivers/usb/host/xhci-mtk.h | 11 +++- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 54c521524bfc..f3c6f078f82d 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -80,7 +80,7 @@ decode_ep(struct usb_host_endpoint *ep, enum usb_device_speed speed) interval /= 1000; } - snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s\n", + snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s", usb_speed_string(speed), usb_endpoint_num(epd), usb_endpoint_dir_in(epd) ? "in" : "out", usb_ep_type_string(usb_endpoint_type(epd)), @@ -129,6 +129,10 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev, int bw_index; virt_dev = xhci->devs[udev->slot_id]; + if (!virt_dev->real_port) { + WARN_ONCE(1, "%s invalid real_port\n", dev_name(&udev->dev)); + return NULL; + } if (udev->speed >= USB_SPEED_SUPER) { if (usb_endpoint_dir_out(&ep->desc)) @@ -236,14 +240,20 @@ static void drop_tt(struct usb_device *udev) } } -static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, - struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) +static struct mu3h_sch_ep_info * +create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, + struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) { struct mu3h_sch_ep_info *sch_ep; + struct mu3h_sch_bw_info *bw_info; struct mu3h_sch_tt *tt = NULL; u32 len_bw_budget_table; size_t mem_size; + bw_info = get_bw_info(mtk, udev, ep); + if (!bw_info) + return ERR_PTR(-ENODEV); + if (is_fs_or_ls(udev->speed)) len_bw_budget_table = TT_MICROFRAMES_MAX; else if ((udev->speed >= USB_SPEED_SUPER) @@ -266,11 +276,13 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, } } + sch_ep->bw_info = bw_info; sch_ep->sch_tt = tt; sch_ep->ep = ep; sch_ep->speed = udev->speed; INIT_LIST_HEAD(&sch_ep->endpoint); INIT_LIST_HEAD(&sch_ep->tt_endpoint); + INIT_HLIST_NODE(&sch_ep->hentry); return sch_ep; } @@ -576,9 +588,9 @@ static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep) return boundary; } -static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw, - struct mu3h_sch_ep_info *sch_ep) +static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) { + struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info; const u32 esit_boundary = get_esit_boundary(sch_ep); const u32 bw_boundary = get_bw_boundary(sch_ep->speed); u32 offset; @@ -624,23 +636,26 @@ static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw, return load_ep_bw(sch_bw, sch_ep, true); } -static void destroy_sch_ep(struct usb_device *udev, - struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) +static void destroy_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, + struct mu3h_sch_ep_info *sch_ep) { /* only release ep bw check passed by check_sch_bw() */ if (sch_ep->allocated) - load_ep_bw(sch_bw, sch_ep, false); + load_ep_bw(sch_ep->bw_info, sch_ep, false); if (sch_ep->sch_tt) drop_tt(udev); list_del(&sch_ep->endpoint); + hlist_del(&sch_ep->hentry); kfree(sch_ep); } -static bool need_bw_sch(struct usb_host_endpoint *ep, - enum usb_device_speed speed, int has_tt) +static bool need_bw_sch(struct usb_device *udev, + struct usb_host_endpoint *ep) { + bool has_tt = udev->tt && udev->tt->hub->parent; + /* only for periodic endpoints */ if (usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_bulk(&ep->desc)) @@ -651,7 +666,7 @@ static bool need_bw_sch(struct usb_host_endpoint *ep, * a TT are also ignored, root-hub will schedule them directly, * but need set @bpkts field of endpoint context to 1. */ - if (is_fs_or_ls(speed) && !has_tt) + if (is_fs_or_ls(udev->speed) && !has_tt) return false; /* skip endpoint with zero maxpkt */ @@ -666,7 +681,6 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); struct mu3h_sch_bw_info *sch_array; int num_usb_bus; - int i; /* ss IN and OUT are separated */ num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports; @@ -675,12 +689,10 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) if (sch_array == NULL) return -ENOMEM; - for (i = 0; i < num_usb_bus; i++) - INIT_LIST_HEAD(&sch_array[i].bw_ep_list); - mtk->sch_array = sch_array; INIT_LIST_HEAD(&mtk->bw_ep_chk_list); + hash_init(mtk->sch_ep_hash); return 0; } @@ -704,9 +716,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); - xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); - - if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) { + if (!need_bw_sch(udev, ep)) { /* * set @bpkts to 1 if it is LS or FS periodic endpoint, and its * device does not connected through an external HS hub @@ -718,13 +728,16 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, return 0; } - sch_ep = create_sch_ep(udev, ep, ep_ctx); + xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); + + sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx); if (IS_ERR_OR_NULL(sch_ep)) return -ENOMEM; setup_sch_info(ep_ctx, sch_ep); list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list); + hash_add(mtk->sch_ep_hash, &sch_ep->hentry, (unsigned long)ep); return 0; } @@ -734,22 +747,18 @@ static void drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, { struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct xhci_virt_device *virt_dev; - struct mu3h_sch_bw_info *sch_bw; - struct mu3h_sch_ep_info *sch_ep, *tmp; - - virt_dev = xhci->devs[udev->slot_id]; - - xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); + struct mu3h_sch_ep_info *sch_ep; + struct hlist_node *hn; - if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) + if (!need_bw_sch(udev, ep)) return; - sch_bw = get_bw_info(mtk, udev, ep); + xhci_err(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); - list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { + hash_for_each_possible_safe(mtk->sch_ep_hash, sch_ep, + hn, hentry, (unsigned long)ep) { if (sch_ep->ep == ep) { - destroy_sch_ep(udev, sch_bw, sch_ep); + destroy_sch_ep(mtk, udev, sch_ep); break; } } @@ -760,30 +769,22 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; - struct mu3h_sch_bw_info *sch_bw; - struct mu3h_sch_ep_info *sch_ep, *tmp; + struct mu3h_sch_ep_info *sch_ep; int ret; xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) { - sch_bw = get_bw_info(mtk, udev, sch_ep->ep); + struct xhci_ep_ctx *ep_ctx; + struct usb_host_endpoint *ep = sch_ep->ep; + unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); - ret = check_sch_bw(sch_bw, sch_ep); + ret = check_sch_bw(sch_ep); if (ret) { xhci_err(xhci, "Not enough bandwidth! (%s)\n", sch_error_string(-ret)); return -ENOSPC; } - } - - list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { - struct xhci_ep_ctx *ep_ctx; - struct usb_host_endpoint *ep = sch_ep->ep; - unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); - - sch_bw = get_bw_info(mtk, udev, ep); - list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts) @@ -797,22 +798,23 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) sch_ep->offset, sch_ep->repeat); } - return xhci_check_bandwidth(hcd, udev); + ret = xhci_check_bandwidth(hcd, udev); + if (!ret) + INIT_LIST_HEAD(&mtk->bw_ep_chk_list); + + return ret; } void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) { struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct mu3h_sch_bw_info *sch_bw; struct mu3h_sch_ep_info *sch_ep, *tmp; xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); - list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { - sch_bw = get_bw_info(mtk, udev, sch_ep->ep); - destroy_sch_ep(udev, sch_bw, sch_ep); - } + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) + destroy_sch_ep(mtk, udev, sch_ep); xhci_reset_bandwidth(hcd, udev); } diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index eb05aaf6edbe..dc5e83f5c5cc 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -10,11 +10,15 @@ #define _XHCI_MTK_H_ #include +#include #include "xhci.h" #define BULK_CLKS_NUM 5 +/* support at most 64 ep, use 32 size hash table */ +#define SCH_EP_HASH_BITS 5 + /** * To simplify scheduler algorithm, set a upper limit for ESIT, * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT, @@ -36,14 +40,12 @@ struct mu3h_sch_tt { * struct mu3h_sch_bw_info: schedule information for bandwidth domain * * @bus_bw: array to keep track of bandwidth already used at each uframes - * @bw_ep_list: eps in the bandwidth domain * * treat a HS root port as a bandwidth domain, but treat a SS root port as * two bandwidth domains, one for IN eps and another for OUT eps. */ struct mu3h_sch_bw_info { u32 bus_bw[XHCI_MTK_MAX_ESIT]; - struct list_head bw_ep_list; }; /** @@ -54,8 +56,10 @@ struct mu3h_sch_bw_info { * @num_budget_microframes: number of continuous uframes * (@repeat==1) scheduled within the interval * @bw_cost_per_microframe: bandwidth cost per microframe + * @hentry: hash table entry * @endpoint: linked into bandwidth domain which it belongs to * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to + * @bw_info: bandwidth domain which this endpoint belongs * @sch_tt: mu3h_sch_tt linked into * @ep_type: endpoint type * @maxpkt: max packet size of endpoint @@ -84,7 +88,9 @@ struct mu3h_sch_ep_info { u32 num_budget_microframes; u32 bw_cost_per_microframe; struct list_head endpoint; + struct hlist_node hentry; struct list_head tt_endpoint; + struct mu3h_sch_bw_info *bw_info; struct mu3h_sch_tt *sch_tt; u32 ep_type; u32 maxpkt; @@ -137,6 +143,7 @@ struct xhci_hcd_mtk { struct usb_hcd *hcd; struct mu3h_sch_bw_info *sch_array; struct list_head bw_ep_chk_list; + DECLARE_HASHTABLE(sch_ep_hash, SCH_EP_HASH_BITS); struct mu3c_ippc_regs __iomem *ippc_regs; int num_u2_ports; int num_u3_ports; From patchwork Thu Aug 26 02:51:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?= X-Patchwork-Id: 12458901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA46FC432BE for ; Thu, 26 Aug 2021 02:54:29 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7250D60FD9 for ; Thu, 26 Aug 2021 02:54:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7250D60FD9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=lRnXLiLUi3EFvW/LxM7be0tJjGx+E6rM/GPNhZqbh/c=; b=0O6588ZP/4PBbL NVSh3ZWBjlORnpHBgBKrJJV6g7sOdtKKV2dsybb4iQO7xew39pgeafBscmfYF+VMXkYthMQOKPfDx xIPmbqawJZSkxmhQuJbRy3gzb/nwfWh8bQBTOKYtz4P/byCzciDcCLV6+9FAgZpaNM1MgyS5uO7cK 8uFuq5564501UDiHlnyf3Kd3APrrmv6LzBUcsCG0F86VCcinNWj145Fw3iuaTpwosqAxb8nl3fCcI af3WrDSOlYP0LkeOye6rJFyPXk7zl1cqAjp4d7D1UbIjcyaVEXkdVZqNF+g/zgly6IdvawLdS3RWw ioV5msdvv+wYceTZBonQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5Uz-008xlX-Aw; Thu, 26 Aug 2021 02:52:13 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJ5Us-008xjf-Bx; Thu, 26 Aug 2021 02:52:10 +0000 X-UUID: d5891ae7043c482cbfc734871ace3e63-20210825 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=zWMfwq6LT7ELHLNKOrvThK+ed+W/Mag+7UYGS5dgdeQ=; b=Eu4RezDsNnlcQMzHg1o98RtIpMCCq4h5hgZfqsICbQGZNP6zJM3PGgeuJXsTR2SIEx+iAPLt2yrx5tawywdpCv1tZCZxEbybx4uD/vEieCprJHEQgFSJp8i2dmPP/Np59EHIe2C+1jYOJKdzD7xa6lHRiXToTabmUtDYAbtlLQs=; X-UUID: d5891ae7043c482cbfc734871ace3e63-20210825 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1259738813; Wed, 25 Aug 2021 19:52:03 -0700 Received: from mtkmbs10n2.mediatek.inc (172.21.101.183) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 25 Aug 2021 19:52:02 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs10n2.mediatek.inc (172.21.101.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.2.792.3; Thu, 26 Aug 2021 10:52:00 +0800 Received: from mtkslt301.mediatek.inc (10.21.14.114) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 26 Aug 2021 10:52:00 +0800 From: Chunfeng Yun To: Mathias Nyman , Greg Kroah-Hartman CC: Chunfeng Yun , Matthias Brugger , , , , , Ikjoon Jang , Eddie Hung , Yaqii wu Subject: [PATCH next v2 6/6] usb: xhci-mtk: allow bandwidth table rollover Date: Thu, 26 Aug 2021 10:51:44 +0800 Message-ID: <20210826025144.51992-6-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com> References: <20210826025144.51992-1-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210825_195206_506304_77347C83 X-CRM114-Status: GOOD ( 17.68 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org xhci-mtk has 64 slots for periodic bandwidth calculations and each slot represents byte budgets on a microframe. When an endpoint's allocation sits on the boundary of the table, byte budgets' slot can be rolled over but the current implementation doesn't. This patch allows the microframe index rollover and prevent out-of-bounds array access. Signed-off-by: Ikjoon Jang Signed-off-by: Chunfeng Yun --- v2: new patch --- drivers/usb/host/xhci-mtk-sch.c | 51 +++++++++++---------------------- drivers/usb/host/xhci-mtk.h | 3 +- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index f3c6f078f82d..134f4789bd89 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -416,15 +416,14 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, { u32 max_bw = 0; u32 bw; - int i; - int j; + int i, j, k; for (i = 0; i < sch_ep->num_esit; i++) { u32 base = offset + i * sch_ep->esit; for (j = 0; j < sch_ep->num_budget_microframes; j++) { - bw = sch_bw->bus_bw[base + j] + - sch_ep->bw_budget_table[j]; + k = XHCI_MTK_BW_INDEX(base + j); + bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j]; if (bw > max_bw) max_bw = bw; } @@ -436,18 +435,16 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep, bool used) { u32 base; - int i; - int j; + int i, j, k; for (i = 0; i < sch_ep->num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; for (j = 0; j < sch_ep->num_budget_microframes; j++) { + k = XHCI_MTK_BW_INDEX(base + j); if (used) - sch_bw->bus_bw[base + j] += - sch_ep->bw_budget_table[j]; + sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j]; else - sch_bw->bus_bw[base + j] -= - sch_ep->bw_budget_table[j]; + sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j]; } } } @@ -457,7 +454,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) struct mu3h_sch_tt *tt = sch_ep->sch_tt; u32 tmp; int base; - int i, j; + int i, j, k; for (i = 0; i < sch_ep->num_esit; i++) { base = offset + i * sch_ep->esit; @@ -467,7 +464,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) * the hub will always delay one uframe to send data */ for (j = 0; j < sch_ep->num_budget_microframes; j++) { - tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j]; + k = XHCI_MTK_BW_INDEX(base + j); + tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j]; if (tmp > FS_PAYLOAD_MAX) return -ESCH_BW_OVERFLOW; } @@ -542,16 +540,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) { struct mu3h_sch_tt *tt = sch_ep->sch_tt; u32 base; - int i, j; + int i, j, k; for (i = 0; i < sch_ep->num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; - for (j = 0; j < sch_ep->num_budget_microframes; j++) + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + k = XHCI_MTK_BW_INDEX(base + j); if (used) - tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j]; + tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j]; else - tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j]; + tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j]; + } } if (used) @@ -573,25 +573,9 @@ static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw, return 0; } -static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep) -{ - u32 boundary = sch_ep->esit; - - if (sch_ep->sch_tt) { /* LS/FS with TT */ - /* tune for CS */ - if (sch_ep->ep_type != ISOC_OUT_EP) - boundary++; - else if (boundary > 1) /* normally esit >= 8 for FS/LS */ - boundary--; - } - - return boundary; -} - static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) { struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info; - const u32 esit_boundary = get_esit_boundary(sch_ep); const u32 bw_boundary = get_bw_boundary(sch_ep->speed); u32 offset; u32 worst_bw; @@ -608,9 +592,6 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep) if (ret) continue; - if ((offset + sch_ep->num_budget_microframes) > esit_boundary) - break; - worst_bw = get_max_bw(sch_bw, sch_ep, offset); if (worst_bw > bw_boundary) continue; diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index dc5e83f5c5cc..7cc0123eada0 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -25,7 +25,8 @@ * round down to the limit value, that means allocating more * bandwidth to it. */ -#define XHCI_MTK_MAX_ESIT 64 +#define XHCI_MTK_MAX_ESIT (1 << 6) +#define XHCI_MTK_BW_INDEX(x) ((x) & (XHCI_MTK_MAX_ESIT - 1)) /** * @fs_bus_bw: array to keep track of bandwidth already used for FS