From: Mathias Nyman <mathias.nyman@linux.intel.com> To: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Cc: Alan Stern <stern@rowland.harvard.edu>, Greg KH <gregkh@linuxfoundation.org>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Andy Shevchenko <andy.shevchenko@gmail.com>, Mathias Nyman <mathias.nyman@intel.com>, linux-usb@vger.kernel.org, lukaszx.szulc@intel.com, Christoph Hellwig <hch@lst.de>, Marek Szyprowski <m.szyprowski@samsung.com>, iommu@lists.linux-foundation.org Subject: usb HC busted? Date: Thu, 19 Jul 2018 18:42:19 +0300 [thread overview] Message-ID: <ab814c88-0857-5444-57da-34c21b8d7f6c@linux.intel.com> (raw) >> As first aid I could try to implement checks that make sure the flushed URBs >> trb pointers really are on the current endpoint ring, and also add some warning >> if we are we are dropping endpoints with URBs still queued. > > Yes, please. I think your first-aid will be a much better option than > the hacky patch I am using atm. > Attached a patch that checks canceled URB td/trb pointers. I haven't tested it at all (well compiles and boots, but new code never exercised) Does it work for you? >> >> But we need to fix this properly as well. >> xhci needs to be more in sync with usb core in usb_set_interface(), currently xhci >> has the altssetting up and running when usb core hasn't event started flushing endpoints. > > I am able to reproduce this on almost all cycles, so I can always test > the fix for you after you are fully back from your holiday. Nice, thanks -Mathias From a7d4af3129a91811c95ea642f6c916b1c1ca6d46 Mon Sep 17 00:00:00 2001 From: Mathias Nyman <mathias.nyman@linux.intel.com> Date: Thu, 19 Jul 2018 18:06:18 +0300 Subject: [PATCH] xhci: when dequeing a URB make sure it exists on the current endpoint ring. If the endpoint ring has been reallocated since the URB was enqueued, then URB may contain TD and TRB pointers to a already freed ring. If this the case then manuallt return the URB, and don't try to stop the ring. It would be useless. This can happened if endpoint is not flushed before it is dropped and re-added, which is the case in usb_set_interface() as xhci does things in an odd order. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> --- drivers/usb/host/xhci.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 711da33..5bedab7 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -37,6 +37,21 @@ static unsigned int quirks; module_param(quirks, uint, S_IRUGO); MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); +static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring) +{ + struct xhci_segment *seg = ring->first_seg; + + if (!td || !td->start_seg) + return false; + do { + if (seg == td->start_seg) + return true; + seg = seg->next; + } while (seg && seg != ring->first_seg); + + return false; +} + /* TODO: copied from ehci-hcd.c - can this be refactored? */ /* * xhci_handshake - spin reading hc until handshake completes or fails @@ -1467,19 +1482,16 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto done; } + /* check ring is not re-allocated since URB was enqueued */ + if (!td_on_ring(&urb_priv->td[0], ep_ring)) { + xhci_err(xhci, "Canceled URB td not found on endpoint ring"); + goto err_unlink_giveback; + } + if (xhci->xhc_state & XHCI_STATE_HALTED) { xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "HC halted, freeing TD manually."); - for (i = urb_priv->num_tds_done; - i < urb_priv->num_tds; - i++) { - td = &urb_priv->td[i]; - if (!list_empty(&td->td_list)) - list_del_init(&td->td_list); - if (!list_empty(&td->cancelled_td_list)) - list_del_init(&td->cancelled_td_list); - } - goto err_giveback; + "HC halted, freeing TD manually."); + goto err_unlink_giveback; } i = urb_priv->num_tds_done; @@ -1519,6 +1531,15 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) spin_unlock_irqrestore(&xhci->lock, flags); return ret; +err_unlink_giveback: + for (i = urb_priv->num_tds_done; i < urb_priv->num_tds; i++) { + td = &urb_priv->td[i]; + if (!list_empty(&td->td_list)) + list_del_init(&td->td_list); + if (!list_empty(&td->cancelled_td_list)) + list_del_init(&td->cancelled_td_list); + } + err_giveback: if (urb_priv) xhci_urb_free_priv(urb_priv); -- 2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Mathias Nyman <mathias.nyman-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> To: Sudip Mukherjee <sudipm.mukherjee-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Cc: Mathias Nyman <mathias.nyman-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>, Greg KH <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>, linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org, Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>, Andy Shevchenko <andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>, Alan Stern <stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org>, Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>, lukaszx.szulc-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org Subject: Re: usb HC busted? Date: Thu, 19 Jul 2018 18:42:19 +0300 [thread overview] Message-ID: <ab814c88-0857-5444-57da-34c21b8d7f6c@linux.intel.com> (raw) In-Reply-To: <20180719113455.urktqxijzoyhfoou@debian> [-- Attachment #1: Type: text/plain, Size: 894 bytes --] >> As first aid I could try to implement checks that make sure the flushed URBs >> trb pointers really are on the current endpoint ring, and also add some warning >> if we are we are dropping endpoints with URBs still queued. > > Yes, please. I think your first-aid will be a much better option than > the hacky patch I am using atm. > Attached a patch that checks canceled URB td/trb pointers. I haven't tested it at all (well compiles and boots, but new code never exercised) Does it work for you? >> >> But we need to fix this properly as well. >> xhci needs to be more in sync with usb core in usb_set_interface(), currently xhci >> has the altssetting up and running when usb core hasn't event started flushing endpoints. > > I am able to reproduce this on almost all cycles, so I can always test > the fix for you after you are fully back from your holiday. Nice, thanks -Mathias [-- Attachment #2: 0001-xhci-when-dequeing-a-URB-make-sure-it-exists-on-the-.patch --] [-- Type: text/x-patch, Size: 3036 bytes --] >From a7d4af3129a91811c95ea642f6c916b1c1ca6d46 Mon Sep 17 00:00:00 2001 From: Mathias Nyman <mathias.nyman-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> Date: Thu, 19 Jul 2018 18:06:18 +0300 Subject: [PATCH] xhci: when dequeing a URB make sure it exists on the current endpoint ring. If the endpoint ring has been reallocated since the URB was enqueued, then URB may contain TD and TRB pointers to a already freed ring. If this the case then manuallt return the URB, and don't try to stop the ring. It would be useless. This can happened if endpoint is not flushed before it is dropped and re-added, which is the case in usb_set_interface() as xhci does things in an odd order. Signed-off-by: Mathias Nyman <mathias.nyman-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> --- drivers/usb/host/xhci.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 711da33..5bedab7 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -37,6 +37,21 @@ static unsigned int quirks; module_param(quirks, uint, S_IRUGO); MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); +static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring) +{ + struct xhci_segment *seg = ring->first_seg; + + if (!td || !td->start_seg) + return false; + do { + if (seg == td->start_seg) + return true; + seg = seg->next; + } while (seg && seg != ring->first_seg); + + return false; +} + /* TODO: copied from ehci-hcd.c - can this be refactored? */ /* * xhci_handshake - spin reading hc until handshake completes or fails @@ -1467,19 +1482,16 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto done; } + /* check ring is not re-allocated since URB was enqueued */ + if (!td_on_ring(&urb_priv->td[0], ep_ring)) { + xhci_err(xhci, "Canceled URB td not found on endpoint ring"); + goto err_unlink_giveback; + } + if (xhci->xhc_state & XHCI_STATE_HALTED) { xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "HC halted, freeing TD manually."); - for (i = urb_priv->num_tds_done; - i < urb_priv->num_tds; - i++) { - td = &urb_priv->td[i]; - if (!list_empty(&td->td_list)) - list_del_init(&td->td_list); - if (!list_empty(&td->cancelled_td_list)) - list_del_init(&td->cancelled_td_list); - } - goto err_giveback; + "HC halted, freeing TD manually."); + goto err_unlink_giveback; } i = urb_priv->num_tds_done; @@ -1519,6 +1531,15 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) spin_unlock_irqrestore(&xhci->lock, flags); return ret; +err_unlink_giveback: + for (i = urb_priv->num_tds_done; i < urb_priv->num_tds; i++) { + td = &urb_priv->td[i]; + if (!list_empty(&td->td_list)) + list_del_init(&td->td_list); + if (!list_empty(&td->cancelled_td_list)) + list_del_init(&td->cancelled_td_list); + } + err_giveback: if (urb_priv) xhci_urb_free_priv(urb_priv); -- 2.7.4 [-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next reply other threads:[~2018-07-19 15:42 UTC|newest] Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-07-19 15:42 Mathias Nyman [this message] 2018-07-19 15:42 ` usb HC busted? Mathias Nyman -- strict thread matches above, loose matches on Subject: below -- 2018-07-21 10:55 Sudip Mukherjee 2018-07-21 10:55 ` Sudip Mukherjee 2018-07-20 14:09 Alan Stern 2018-07-20 14:09 ` Alan Stern 2018-07-20 12:54 Sudip Mukherjee 2018-07-20 12:54 ` Sudip Mukherjee 2018-07-20 11:46 Mathias Nyman 2018-07-20 11:46 ` Mathias Nyman 2018-07-20 11:10 Mathias Nyman 2018-07-20 11:10 ` Mathias Nyman 2018-07-19 17:32 Sudip Mukherjee 2018-07-19 17:32 ` Sudip Mukherjee 2018-07-19 14:57 Alan Stern 2018-07-19 14:57 ` Alan Stern 2018-07-19 11:34 Sudip Mukherjee 2018-07-19 11:34 ` Sudip Mukherjee 2018-07-19 10:59 Mathias Nyman 2018-07-19 10:59 ` Mathias Nyman 2018-07-17 17:01 Sudip Mukherjee 2018-07-17 17:01 ` Sudip Mukherjee 2018-07-17 15:59 Sudip Mukherjee 2018-07-17 15:59 ` Sudip Mukherjee 2018-07-17 15:52 Greg Kroah-Hartman 2018-07-17 15:52 ` Greg KH 2018-07-17 15:10 Sudip Mukherjee 2018-07-17 15:10 ` Sudip Mukherjee 2018-07-17 15:08 Alan Stern 2018-07-17 15:08 ` Alan Stern 2018-07-17 14:49 Sudip Mukherjee 2018-07-17 14:49 ` Sudip Mukherjee 2018-07-17 14:40 Sudip Mukherjee 2018-07-17 14:40 ` Sudip Mukherjee 2018-07-17 14:31 Alan Stern 2018-07-17 14:31 ` Alan Stern 2018-07-17 14:28 Alan Stern 2018-07-17 14:28 ` Alan Stern 2018-07-17 13:53 Greg Kroah-Hartman 2018-07-17 13:53 ` Greg KH 2018-07-17 13:20 Sudip Mukherjee 2018-07-17 13:20 ` Sudip Mukherjee 2018-07-17 12:04 Greg Kroah-Hartman 2018-07-17 12:04 ` Greg KH 2018-07-17 11:41 Sudip Mukherjee 2018-07-17 11:41 ` Sudip Mukherjee 2018-06-30 21:07 Sudip Mukherjee 2018-06-30 21:07 ` Sudip Mukherjee 2018-06-29 11:41 Mathias Nyman 2018-06-29 11:41 ` Mathias Nyman 2018-06-27 12:20 Sudip Mukherjee 2018-06-27 12:20 ` Sudip Mukherjee 2018-06-27 11:59 Sudip Mukherjee 2018-06-27 11:59 ` Sudip Mukherjee 2018-06-25 16:15 Sudip Mukherjee 2018-06-25 16:15 ` Sudip Mukherjee 2018-06-21 11:01 Mathias Nyman 2018-06-21 11:01 ` Mathias Nyman 2018-06-21 0:53 Sudip Mukherjee 2018-06-21 0:53 ` Sudip Mukherjee 2018-06-08 9:07 Sudip Mukherjee 2018-06-08 9:07 ` Sudip Mukherjee 2018-06-07 7:40 Mathias Nyman 2018-06-07 7:40 ` Mathias Nyman 2018-06-06 16:45 Sudip Mukherjee 2018-06-06 16:45 ` Sudip Mukherjee 2018-06-06 16:42 Sudip Mukherjee 2018-06-06 16:42 ` Sudip Mukherjee 2018-06-06 15:36 Andy Shevchenko 2018-06-06 15:36 ` Andy Shevchenko 2018-06-06 14:12 Mathias Nyman 2018-06-06 14:12 ` Mathias Nyman 2018-06-04 15:28 Sudip Mukherjee 2018-06-03 19:37 Sudip Mukherjee 2018-05-24 13:35 Mathias Nyman
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=ab814c88-0857-5444-57da-34c21b8d7f6c@linux.intel.com \ --to=mathias.nyman@linux.intel.com \ --cc=andriy.shevchenko@linux.intel.com \ --cc=andy.shevchenko@gmail.com \ --cc=gregkh@linuxfoundation.org \ --cc=hch@lst.de \ --cc=iommu@lists.linux-foundation.org \ --cc=linux-usb@vger.kernel.org \ --cc=lukaszx.szulc@intel.com \ --cc=m.szyprowski@samsung.com \ --cc=mathias.nyman@intel.com \ --cc=stern@rowland.harvard.edu \ --cc=sudipm.mukherjee@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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.