diff options
author | Mathias Nyman <mathias.nyman@linux.intel.com> | 2017-06-15 11:55:42 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-06-15 22:17:46 +0200 |
commit | c5628a2af83aeda6cc02b6c64acb91f249727b1c (patch) | |
tree | 60d8d8be1aa006f7a0834583ab456b98eafc69a0 /drivers/usb/host/xhci.c | |
parent | d590c23111505635e1beb01006612971e5ede8aa (diff) |
xhci: remove endpoint ring cache
Anurag Kumar Vulisha reported several issues with xhci endpoint
ring caching.
31 Rings are cached per device before a ring is freed.
These cached rings are not used as default if a new ring is needed.
They are only used if the driver fails to allocate memory for a ring.
The current ring cache is more a reason to why we run out memory than a
help when we actually do so.
Anurag Kumar Vulisha tried to use cached rings as a first option and
found new issues with cached ring initialization.
Cached rings were first zeroed and then manually reinitialized with link
trbs etc, but forgetting to set some important bits like cycle toggle bit.
Remove the ring cache completely as it's a faulty premature optimization
eating memory
Reported-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Tested-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2d6a98c1dc12..ddeb943dc242 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1695,8 +1695,7 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, if (xhci->quirks & XHCI_MTK_HOST) { ret = xhci_mtk_add_ep_quirk(hcd, udev, ep); if (ret < 0) { - xhci_free_or_cache_endpoint_ring(xhci, - virt_dev, ep_index); + xhci_free_endpoint_ring(xhci, virt_dev, ep_index); return ret; } } @@ -2720,23 +2719,23 @@ static int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) for (i = 1; i < 31; i++) { if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) { - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + xhci_free_endpoint_ring(xhci, virt_dev, i); xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); } } xhci_zero_in_ctx(xhci, virt_dev); /* * Install any rings for completely new endpoints or changed endpoints, - * and free or cache any old rings from changed endpoints. + * and free any old rings from changed endpoints. */ for (i = 1; i < 31; i++) { if (!virt_dev->eps[i].new_ring) continue; - /* Only cache or free the old ring if it exists. + /* Only free the old ring if it exists. * It may not if this is the first add of an endpoint. */ if (virt_dev->eps[i].ring) { - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + xhci_free_endpoint_ring(xhci, virt_dev, i); } xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; @@ -3336,7 +3335,7 @@ void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, * * Wait for the Reset Device command to finish. Remove all structures * associated with the endpoints that were disabled. Clear the input device - * structure? Cache the rings? Reset the control endpoint 0 max packet size? + * structure? Reset the control endpoint 0 max packet size? * * If the virt_dev to be reset does not exist or does not match the udev, * it means the device is lost, possibly due to the xHC restore error and @@ -3466,7 +3465,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd, spin_unlock_irqrestore(&xhci->lock, flags); } - /* Everything but endpoint 0 is disabled, so free or cache the rings. */ + /* Everything but endpoint 0 is disabled, so free the rings. */ last_freed_endpoint = 1; for (i = 1; i < 31; i++) { struct xhci_virt_ep *ep = &virt_dev->eps[i]; @@ -3480,7 +3479,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd, } if (ep->ring) { - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + xhci_free_endpoint_ring(xhci, virt_dev, i); last_freed_endpoint = i; } if (!list_empty(&virt_dev->eps[i].bw_endpoint_list)) |