Message ID | 20201210184700.v2.3.Id0d31b5f3ddf5e734d2ab11161ac5821921b1e1e@changeid (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Release allocated periodic bandwidth data from reset_bandwidth() | expand |
On Thu, Dec 10, 2020 at 06:47:47PM +0800, Ikjoon Jang wrote: > xhci-mtk has hooks on add_endpoint() and drop_endpoint() from xhci > to handle its own sw bandwidth managements and stores bandwidth data > into internal table every time add_endpoint() is called, > so when bandwidth allocation fails at one endpoint, all earlier > allocation from the same interface could still remain at the table. > > This patch adds two more hooks from check_bandwidth() and > reset_bandwidth(), and make mtk-xhci to releases all failed endpoints > from reset_bandwidth(). > > Fixes: 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller") > Signed-off-by: Ikjoon Jang <ikjn@chromium.org> Shouldn't this be the first patch in the series? You don't want a fix to be dependent on code style changes, otherwise it is really really hard to backport it to older kernels that might need this fix, right? Can you re-order these patches please? thanks, greg k-h
Hi Ikjoon,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on balbi-usb/testing/next peter.chen-usb/ci-for-usb-next v5.10-rc7 next-20201210]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Ikjoon-Jang/Release-allocated-periodic-bandwidth-data-from-reset_bandwidth/20201210-185329
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: xtensa-randconfig-r011-20201209 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/a99b1fe33b427dd2ca384c78d50b6d05fb04e56d
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Ikjoon-Jang/Release-allocated-periodic-bandwidth-data-from-reset_bandwidth/20201210-185329
git checkout a99b1fe33b427dd2ca384c78d50b6d05fb04e56d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/usb/host/xhci-mtk-sch.c: In function 'xhci_mtk_add_ep_quirk':
>> drivers/usb/host/xhci-mtk-sch.c:606:27: warning: variable 'sch_bw' set but not used [-Wunused-but-set-variable]
606 | struct mu3h_sch_bw_info *sch_bw;
| ^~~~~~
vim +/sch_bw +606 drivers/usb/host/xhci-mtk-sch.c
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 597
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 598 int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 599 struct usb_host_endpoint *ep)
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 600 {
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 601 struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
a99b1fe33b427dd Ikjoon Jang 2020-12-10 602 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 603 struct xhci_ep_ctx *ep_ctx;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 604 struct xhci_slot_ctx *slot_ctx;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 605 struct xhci_virt_device *virt_dev;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 @606 struct mu3h_sch_bw_info *sch_bw;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 607 struct mu3h_sch_ep_info *sch_ep;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 608 unsigned int ep_index;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 609
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 610 virt_dev = xhci->devs[udev->slot_id];
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 611 ep_index = xhci_get_endpoint_index(&ep->desc);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 612 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 613 ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 614
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 615 xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n",
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 616 __func__, usb_endpoint_type(&ep->desc), udev->speed,
734d3ddd81902d8 Felipe Balbi 2016-09-28 617 usb_endpoint_maxp(&ep->desc),
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 618 usb_endpoint_dir_in(&ep->desc), ep);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 619
b765a16a11fad6b Chunfeng Yun 2016-01-26 620 if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) {
b765a16a11fad6b Chunfeng Yun 2016-01-26 621 /*
b765a16a11fad6b Chunfeng Yun 2016-01-26 622 * set @bpkts to 1 if it is LS or FS periodic endpoint, and its
b765a16a11fad6b Chunfeng Yun 2016-01-26 623 * device does not connected through an external HS hub
b765a16a11fad6b Chunfeng Yun 2016-01-26 624 */
b765a16a11fad6b Chunfeng Yun 2016-01-26 625 if (usb_endpoint_xfer_int(&ep->desc)
b765a16a11fad6b Chunfeng Yun 2016-01-26 626 || usb_endpoint_xfer_isoc(&ep->desc))
b765a16a11fad6b Chunfeng Yun 2016-01-26 627 ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(1));
b765a16a11fad6b Chunfeng Yun 2016-01-26 628
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 629 return 0;
b765a16a11fad6b Chunfeng Yun 2016-01-26 630 }
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 631
06cc7c739674e71 Ikjoon Jang 2020-12-10 632 sch_bw = get_bw_info(mtk, udev, ep);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 633
95b516c18621d16 Chunfeng Yun 2018-09-20 634 sch_ep = create_sch_ep(udev, ep, ep_ctx);
95b516c18621d16 Chunfeng Yun 2018-09-20 635 if (IS_ERR_OR_NULL(sch_ep))
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 636 return -ENOMEM;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 637
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 638 setup_sch_info(udev, ep_ctx, sch_ep);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 639
a99b1fe33b427dd Ikjoon Jang 2020-12-10 640 list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_list_new);
08e469de87a2534 Chunfeng Yun 2018-09-20 641
a99b1fe33b427dd Ikjoon Jang 2020-12-10 642 return 0;
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 643 }
a99b1fe33b427dd Ikjoon Jang 2020-12-10 644 EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk);
0cbd4b34cda9dfd Chunfeng Yun 2015-11-24 645
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On Thu, Dec 10, 2020 at 6:57 PM Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > On Thu, Dec 10, 2020 at 06:47:47PM +0800, Ikjoon Jang wrote: > > xhci-mtk has hooks on add_endpoint() and drop_endpoint() from xhci > > to handle its own sw bandwidth managements and stores bandwidth data > > into internal table every time add_endpoint() is called, > > so when bandwidth allocation fails at one endpoint, all earlier > > allocation from the same interface could still remain at the table. > > > > This patch adds two more hooks from check_bandwidth() and > > reset_bandwidth(), and make mtk-xhci to releases all failed endpoints > > from reset_bandwidth(). > > > > Fixes: 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller") > > Signed-off-by: Ikjoon Jang <ikjn@chromium.org> > > Shouldn't this be the first patch in the series? You don't want a fix > to be dependent on code style changes, otherwise it is really really > hard to backport it to older kernels that might need this fix, right? yes, you're right. This patchset also requires "4b0f7a77fb3c usb: xhci-mtk: supports bandwidth scheduling with multi-TT", which doesn't have a Fixes tag. I think I can change Fixes to point to that commit (4b0f7a77fb3c), as this unreleased bandwidth data is much more impactful to TT bandwidth. Thanks! > > Can you re-order these patches please? > > thanks, > > greg k-h
diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 439391f1dc78..102d8e0a50f1 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -583,6 +583,8 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) mtk->sch_array = sch_array; + INIT_LIST_HEAD(&mtk->bw_ep_list_new); + return 0; } EXPORT_SYMBOL_GPL(xhci_mtk_sch_init); @@ -597,16 +599,14 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) { struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); - struct xhci_hcd *xhci; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_ep_ctx *ep_ctx; struct xhci_slot_ctx *slot_ctx; struct xhci_virt_device *virt_dev; struct mu3h_sch_bw_info *sch_bw; struct mu3h_sch_ep_info *sch_ep; unsigned int ep_index; - int ret = 0; - xhci = hcd_to_xhci(hcd); virt_dev = xhci->devs[udev->slot_id]; ep_index = xhci_get_endpoint_index(&ep->desc); slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); @@ -637,42 +637,37 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, setup_sch_info(udev, ep_ctx, sch_ep); - ret = check_sch_bw(udev, sch_bw, sch_ep); - if (ret) { - xhci_err(xhci, "Not enough bandwidth!\n"); - if (is_fs_or_ls(udev->speed)) - drop_tt(udev); - - kfree(sch_ep); - return -ENOSPC; - } + list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_list_new); - list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); + return 0; +} +EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); - ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) - | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); - ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) - | EP_BREPEAT(sch_ep->repeat)); +static void xhci_mtk_drop_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, + struct mu3h_sch_ep_info *sch_ep) +{ + struct mu3h_sch_bw_info *sch_bw = get_bw_info(mtk, udev, sch_ep->ep); - xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", - sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, - sch_ep->offset, sch_ep->repeat); + update_bus_bw(sch_bw, sch_ep, 0); + list_del(&sch_ep->endpoint); - return 0; + if (sch_ep->sch_tt) { + list_del(&sch_ep->tt_endpoint); + drop_tt(udev); + } + kfree(sch_ep); } -EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, - struct usb_host_endpoint *ep) + struct usb_host_endpoint *ep) { struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); - struct xhci_hcd *xhci; - struct xhci_slot_ctx *slot_ctx; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_virt_device *virt_dev; + struct xhci_slot_ctx *slot_ctx; struct mu3h_sch_bw_info *sch_bw; - struct mu3h_sch_ep_info *sch_ep; + struct mu3h_sch_ep_info *sch_ep, *tmp; - xhci = hcd_to_xhci(hcd); virt_dev = xhci->devs[udev->slot_id]; slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); @@ -686,17 +681,72 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, sch_bw = get_bw_info(mtk, udev, ep); - list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { + list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { if (sch_ep->ep == ep) { - update_bus_bw(sch_bw, sch_ep, 0); - list_del(&sch_ep->endpoint); - if (is_fs_or_ls(udev->speed)) { - list_del(&sch_ep->tt_endpoint); - drop_tt(udev); - } - kfree(sch_ep); + xhci_mtk_drop_ep(mtk, udev, sch_ep); break; } } } EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); + +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, *tmp; + + dev_dbg(&udev->dev, "%s\n", __func__); + + list_for_each_entry(sch_ep, &mtk->bw_ep_list_new, endpoint) { + int ret; + struct mu3h_sch_bw_info *sch_bw; + + sch_bw = get_bw_info(mtk, udev, sch_ep->ep); + + ret = check_sch_bw(udev, sch_bw, sch_ep); + if (ret) { + xhci_err(xhci, "Not enough bandwidth!\n"); + return ret; + } + } + + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { + struct mu3h_sch_bw_info *sch_bw; + 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) + | EP_BCSCOUNT(sch_ep->cs_count) + | EP_BBM(sch_ep->burst_mode)); + ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) + | EP_BREPEAT(sch_ep->repeat)); + + xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", + sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, + sch_ep->offset, sch_ep->repeat); + } + + return 0; +} +EXPORT_SYMBOL_GPL(xhci_mtk_check_bandwidth); + +void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); + struct mu3h_sch_ep_info *sch_ep, *tmp; + + dev_dbg(&udev->dev, "%s\n", __func__); + + list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_list_new, endpoint) { + xhci_mtk_drop_ep(mtk, udev, sch_ep); + } +} +EXPORT_SYMBOL_GPL(xhci_mtk_reset_bandwidth); diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index 8be8c5f7ff62..05ca989985fc 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -130,6 +130,7 @@ struct mu3c_ippc_regs { struct xhci_hcd_mtk { struct device *dev; struct usb_hcd *hcd; + struct list_head bw_ep_list_new; struct mu3h_sch_bw_info *sch_array; struct mu3c_ippc_regs __iomem *ippc_regs; bool has_ippc; @@ -165,6 +166,8 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); +int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); +void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); #else static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, @@ -178,6 +181,16 @@ static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, { } +static inline int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, + struct usb_device *udev) +{ + return 0; +} + +static inline void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, + struct usb_device *udev) +{ +} #endif #endif /* _XHCI_MTK_H_ */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2bf6c526ac7a..5a9e01b33688 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2854,6 +2854,12 @@ static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); virt_dev = xhci->devs[udev->slot_id]; + if (xhci->quirks & XHCI_MTK_HOST) { + ret = xhci_mtk_check_bandwidth(hcd, udev); + if (ret < 0) + return ret; + } + command = xhci_alloc_command(xhci, true, GFP_KERNEL); if (!command) return -ENOMEM; @@ -2941,6 +2947,9 @@ static void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) return; xhci = hcd_to_xhci(hcd); + if (xhci->quirks & XHCI_MTK_HOST) + xhci_mtk_reset_bandwidth(hcd, udev); + xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); virt_dev = xhci->devs[udev->slot_id]; /* Free any rings allocated for added endpoints */
xhci-mtk has hooks on add_endpoint() and drop_endpoint() from xhci to handle its own sw bandwidth managements and stores bandwidth data into internal table every time add_endpoint() is called, so when bandwidth allocation fails at one endpoint, all earlier allocation from the same interface could still remain at the table. This patch adds two more hooks from check_bandwidth() and reset_bandwidth(), and make mtk-xhci to releases all failed endpoints from reset_bandwidth(). Fixes: 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller") Signed-off-by: Ikjoon Jang <ikjn@chromium.org> --- Changes in v2: - fix wrong offset in mediatek hw flags - fix 0-day warnings drivers/usb/host/xhci-mtk-sch.c | 120 ++++++++++++++++++++++---------- drivers/usb/host/xhci-mtk.h | 13 ++++ drivers/usb/host/xhci.c | 9 +++ 3 files changed, 107 insertions(+), 35 deletions(-)