• Mathias Nyman's avatar
    xhci: fix deadlock at host remove by running watchdog correctly · d6169d04
    Mathias Nyman authored
    If a URB is killed while the host is removed we can end up in a situation
    where the hub thread takes the roothub device lock, and waits for
    the URB to be given back by xhci-hcd, blocking the host remove code.
    
    xhci-hcd tries to stop the endpoint and give back the urb, but can't
    as the host is removed from PCI bus at the same time, preventing the normal
    way of giving back urb.
    
    Instead we need to rely on the stop command timeout function to give back
    the urb. This xhci_stop_endpoint_command_watchdog() timeout function
    used a XHCI_STATE_DYING flag to indicate if the timeout function is already
    running, but later this flag has been taking into use in other places to
    mark that xhci is dying.
    
    Remove checks for XHCI_STATE_DYING in xhci_urb_dequeue. We are still
    checking that reading from pci state does not return 0xffffffff or that
    host is not halted before trying to stop the endpoint.
    
    This whole area of stopping endpoints, giving back URBs, and the wathdog
    timeout need rework, this fix focuses on solving a specific deadlock
    issue that we can then send to stable before any major rework.
    
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    d6169d04
xhci.c 149 KB