LKML Archive on lore.kernel.org help / color / mirror / Atom feed
From: Ikjoon Jang <ikjn@chromium.org> To: linux-usb@vger.kernel.org, Chunfeng Yun <chunfeng.yun@mediatek.com> Cc: linux-mediatek@lists.infradead.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Matthias Brugger <matthias.bgg@gmail.com>, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Mathias Nyman <mathias.nyman@intel.com>, Ikjoon Jang <ikjn@chromium.org> Subject: [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover Date: Mon, 9 Aug 2021 16:59:29 +0800 [thread overview] Message-ID: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid> (raw) 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 should be rolled over but the current implementation doesn't. This patch applies a 6 bits mask to the microframe index to handle its rollover 64 slots and prevent out-of-bounds array access. Signed-off-by: Ikjoon Jang <ikjn@chromium.org> --- drivers/usb/host/xhci-mtk-sch.c | 79 +++++++++------------------------ drivers/usb/host/xhci-mtk.h | 1 + 2 files changed, 23 insertions(+), 57 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 46cbf5d54f4f..ef16cd124343 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -411,18 +411,13 @@ 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++) { - u32 base = offset + i * sch_ep->esit; + u32 bw, max_bw = 0; + int i, j, idx; + for (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) { for (j = 0; j < sch_ep->num_budget_microframes; j++) { - bw = sch_bw->bus_bw[base + j] + + idx = XHCI_MTK_BW_IDX(i + offset + j); + bw = sch_bw->bus_bw[idx] + sch_ep->bw_budget_table[j]; if (bw > max_bw) max_bw = bw; @@ -434,20 +429,16 @@ 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; + int i, j, idx; - num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; - for (i = 0; i < num_esit; i++) { - base = sch_ep->offset + i * sch_ep->esit; + for (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) { for (j = 0; j < sch_ep->num_budget_microframes; j++) { + idx = XHCI_MTK_BW_IDX(i + sch_ep->offset + j); if (used) - sch_bw->bus_bw[base + j] += + sch_bw->bus_bw[idx] += sch_ep->bw_budget_table[j]; else - sch_bw->bus_bw[base + j] -= + sch_bw->bus_bw[idx] -= sch_ep->bw_budget_table[j]; } } @@ -456,22 +447,18 @@ 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; - int base; - int i, j; + u32 bw; + int i, j, idx; 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 (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) { for (j = 0; j < uframes; j++) { - tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe; - if (tmp > FS_PAYLOAD_MAX) + idx = XHCI_MTK_BW_IDX(i + offset + j); + bw = tt->fs_bus_bw[idx] + sch_ep->bw_cost_per_microframe; + if (bw > FS_PAYLOAD_MAX) return -ESCH_BW_OVERFLOW; } } @@ -544,14 +531,11 @@ 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; int bw_updated; - int i, j; + int i, j, idx; 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; - if (used) bw_updated = sch_ep->bw_cost_per_microframe; else @@ -560,11 +544,11 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) 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++) - tt->fs_bus_bw[base + j] += bw_updated; + for (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) { + for (j = 0; j < uframes; j++) { + idx = XHCI_MTK_BW_IDX(i + offset + j); + tt->fs_bus_bw[idx] += bw_updated; + } } if (used) @@ -586,25 +570,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; @@ -621,9 +589,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 ddcf25524f67..f627941c4860 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -23,6 +23,7 @@ * bandwidth to it. */ #define XHCI_MTK_MAX_ESIT 64 +#define XHCI_MTK_BW_IDX(idx) ((idx) & 63) /** * @fs_bus_bw: array to keep track of bandwidth already used for FS -- 2.32.0.605.g8dce9f2422-goog
next reply other threads:[~2021-08-09 8:59 UTC|newest] Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-08-09 8:59 Ikjoon Jang [this message] 2021-08-09 9:11 ` [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover Greg Kroah-Hartman 2021-08-09 9:42 ` Ikjoon Jang 2021-08-11 9:01 ` Chunfeng Yun (云春峰) 2021-08-12 9:31 ` Ikjoon Jang 2021-08-12 11:49 ` Chunfeng Yun (云春峰) 2021-08-12 13:47 ` Ikjoon Jang 2021-08-18 2:43 ` Ikjoon Jang 2021-08-20 3:37 ` Chunfeng Yun (云春峰)
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid \ --to=ikjn@chromium.org \ --cc=chunfeng.yun@mediatek.com \ --cc=gregkh@linuxfoundation.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mediatek@lists.infradead.org \ --cc=linux-usb@vger.kernel.org \ --cc=mathias.nyman@intel.com \ --cc=matthias.bgg@gmail.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).