Re: Oops in xhci_endpoint_reset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 27.7.2019 23.43, Bob Gleitsmann wrote:
OK, here's the result of the bisection:

ef513be0a9057cc6baf5d29566aaaefa214ba344 is the first bad commit
commit ef513be0a9057cc6baf5d29566aaaefa214ba344
Author: Jim Lin <jilin@xxxxxxxxxx>
Date:???? Mon Jun 3 18:53:44 2019 +0800

?????? usb: xhci: Add Clear_TT_Buffer
??????
?????? USB 2.0 specification chapter 11.17.5 says "as part of endpoint halt
?????? processing for full-/low-speed endpoints connected via a TT, the host
?????? software must use the Clear_TT_Buffer request to the TT to ensure
?????? that the buffer is not in the busy state".
??????
?????? In our case, a full-speed speaker (ConferenceCam) is behind a high-
?????? speed hub (ConferenceCam Connect), sometimes once we get STALL on a
?????? request we may continue to get STALL with the folllowing requests,
?????? like Set_Interface.
??????
?????? Here we invoke usb_hub_clear_tt_buffer() to send Clear_TT_Buffer
?????? request to the hub of the device for the following Set_Interface
?????? requests to the device to get ACK successfully.
??????
?????? Signed-off-by: Jim Lin <jilin@xxxxxxxxxx>
?????? Acked-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>
?????? Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

??drivers/usb/host/xhci-ring.c | 27 ++++++++++++++++++++++++++-
??drivers/usb/host/xhci.c?????????? | 21 +++++++++++++++++++++
??drivers/usb/host/xhci.h?????????? |?? 5 +++++
??3 files changed, 52 insertions(+), 1 deletion(-)



Thanks, a quick look doesn't immediately open up the cause to me.
Most likely an endpoint or struct usb_device got dropped and freed at suspend/resume,
but we probably have some old stale pointer still in a a TD or URB to it.

could you apply the hack below, it should show more details about this issue.

grep for "Mathias" after resume, if you find it we just prevented a crash.

also adding more xhci debugging and tracing would help:

mount -t debugfs none /sys/kernel/debug
echo 'module xhci_hcd =p' >/sys/kernel/debug/dynamic_debug/control
echo 'module usbcore =p' >/sys/kernel/debug/dynamic_debug/control
echo 81920 > /sys/kernel/debug/tracing/buffer_size_kb
echo 1 > /sys/kernel/debug/tracing/events/xhci-hcd/enable
< suspend/resume >
Send output of dmesg
Send content of /sys/kernel/debug/tracing/trace

8<---

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9741cde..98a515c 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1809,14 +1809,33 @@ struct xhci_segment *trb_in_td(struct xhci_hcd *xhci,
 static void xhci_clear_hub_tt_buffer(struct xhci_hcd *xhci, struct xhci_td *td,
                struct xhci_virt_ep *ep)
 {
+       struct usb_device *udev;
+
        /*
         * As part of low/full-speed endpoint-halt processing
         * we must clear the TT buffer (USB 2.0 specification 11.17.5).
         */
+
        if (td->urb->dev->tt && !usb_pipeint(td->urb->pipe) &&
            (td->urb->dev->tt->hub != xhci_to_hcd(xhci)->self.root_hub) &&
            !(ep->ep_state & EP_CLEARING_TT)) {
+               udev = td->urb->dev;
+               if (!udev) {
+                       xhci_err(xhci, "Mathias: missing udev\n");
+                       return;
+               }
+               if (!udev->slot_id)  {
+                       xhci_err(xhci, "Mathias: missing udev->slot_id\n");
+                       return;
+               }
+
+               if (!xhci->devs[udev->slot_id])  {
+                       xhci_err(xhci, "Mathias: missing xhci->devs[udev->slot_id]\n");
+                       return;
+               }
                ep->ep_state |= EP_CLEARING_TT;
+               xhci_err(xhci, "urb->ep->hcpriv %p,  urb->hcpriv %p\n",
+                        td->urb->ep->hcpriv, td->urb->dev);
                td->urb->ep->hcpriv = td->urb->dev;
                if (usb_hub_clear_tt_buffer(td->urb))
                        ep->ep_state &= ~EP_CLEARING_TT;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 248cd7a..d7978e0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3090,8 +3090,19 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
        udev = (struct usb_device *) host_ep->hcpriv;
        vdev = xhci->devs[udev->slot_id];
        ep_index = xhci_get_endpoint_index(&host_ep->desc);
+
+       if (!vdev) {
+               xhci_warn(xhci, "Mathias: No vdev for slot id %d\n", udev->slot_id);
+               return;
+       }
        ep = &vdev->eps[ep_index];
+ if (!ep) {
+               xhci_warn(xhci, "Mathias: No ep for slot %d ep_index %d\n",
+                         udev->slot_id, ep_index);
+               return;
+       }
+
        /* Bail out if toggle is already being cleared by a endpoint reset */
        if (ep->ep_state & EP_HARD_CLEAR_TOGGLE) {
                ep->ep_state &= ~EP_HARD_CLEAR_TOGGLE;




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux