Re: [PATCH 2/2] xhci: Don't free endpoints in xhci_mem_cleanup()

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

 



On Fri, Jun 01, 2012 at 10:06:24AM +0200, Takashi Iwai wrote:
> This patch fixes a few issues introduced in the recent fix
> [f8a9e72d: USB: fix resource leak in xhci power loss path]
> 
> - The endpoints listed in bw table are just links and each entry is an
>  array member of dev->eps[].  But the commit above adds a kfree() call
>  to these instances, and thus it results in memory corruption.

I tested your patch, hoping it would fix some warnings I had seen when
the xHCI driver was unloaded, but it didn't help.  I still think this
patch is correct, but we're still leaking some memory from the xHCI
driver.

When I plug in a multi-TT USB 2.0 hub, and then unload the xHCI driver,
I get the warning "Slot 2 endpoint 2 not removed from BW list!":

Jun  7 17:31:08 maggie kernel: [  218.431583] usb usb1: USB disconnect, device number 1
Jun  7 17:31:08 maggie kernel: [  218.431585] usb 1-2: USB disconnect, device number 3
Jun  7 17:31:08 maggie kernel: [  218.431587] usb 1-2: unregistering device
Jun  7 17:31:08 maggie kernel: [  218.431588] usb 1-2: unregistering interface 1-2:1.0
Jun  7 17:31:08 maggie kernel: [  218.432118] usb 1-2: usb_disable_device nuking all URBs
Jun  7 17:31:08 maggie kernel: [  218.433030] xhci_hcd 0000:00:14.0: Slot 2 endpoint 2 not removed from BW list!
Jun  7 17:31:08 maggie kernel: [  218.433106] usb usb1: unregistering device
Jun  7 17:31:08 maggie kernel: [  218.433109] usb usb1: unregistering interface 1-0:1.0
Jun  7 17:31:08 maggie kernel: [  218.433594] usb usb1: usb_disable_device nuking all URBs
Jun  7 17:31:08 maggie kernel: [  218.433598] xHCI xhci_drop_endpoint called for root hub
Jun  7 17:31:08 maggie kernel: [  218.433600] xHCI xhci_check_bandwidth called for root hub
Jun  7 17:31:08 maggie kernel: [  218.434216] xhci_hcd 0000:00:14.0: // Halt the HC

That warning comes from this code in xhci-mem.c:xhci_free_virt_device():

        for (i = 0; i < 31; ++i) {
                if (dev->eps[i].ring)
                        xhci_ring_free(xhci, dev->eps[i].ring);
                if (dev->eps[i].stream_info)
                        xhci_free_stream_info(xhci,
                                        dev->eps[i].stream_info);
                /* Endpoints on the TT/root port lists should have been removed
                 * when usb_disable_device() was called for the device.
                 * We can't drop them anyway, because the udev might have gone
                 * away by this point, and we can't tell what speed it was.
                 */
                if (!list_empty(&dev->eps[i].bw_endpoint_list))
                        xhci_warn(xhci, "Slot %u endpoint %u "
                                        "not removed from BW list!\n",
                                        slot_id, i);

Even though the endpoint bandwidth list head should be removed later in
xhci_mem_cleanup(), I wondered why it wouldn't have been removed by the
USB in usb_disable_device().  That's the way it's supposed to work:
when a USB device is disconnected, we free any resources associated with
its endpoints by calling xhci_drop_endpoint() and
xhci_check_bandwidth().

Long story short, all xHCI functions check whether the xHC is halted
before issuing any commands.  When the xHCI driver is unloaded, the USB
core first disables the USB 3.0 roothub portion of the xHCI host, and
then disables the USB 2.0 roothub portion.  When it's called with the
USB 3.0 roothub, xhci_stop() will halt the xHCI host controller and
return.  The driver will get cleaned up when xhci_stop() is called with
the USB 2.0 roothub later.

After the SS roothub is disabled, but the HS roothub is still enabled,
the USB core comes and tries to clean up all connected USB 2.0 devices.
This includes calling usb_disable_device().  Howevrer,
xhci_check_bandwidth() will return immediately because the xHCI host is
halted, and we will leak memory resources.

That's why resources weren't being deallocated when the driver was
unloaded.  This is sort of a separate issue, so I'll still accept your
patch, and send a second patch to fix the driver unload issue.

Sarah Sharp
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

  Powered by Linux