[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 2/2] ohci: clear pending SOF on suspend
From: |
Thomas Huth |
Subject: |
Re: [Qemu-devel] [PATCH v2 2/2] ohci: clear pending SOF on suspend |
Date: |
Fri, 8 Jan 2016 08:51:06 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 |
On 06.01.2016 20:45, Laurent Vivier wrote:
> On overcommitted CPU, kernel can be so slow that an interrupt can
> be triggered by the device whereas the driver is not ready to receive
> it. This drives us into an infinite loop.
>
> On suspend, if a SOF interrupt is raised between the stop of the
> device processing and the change of the device internal state to
> OHCI_USB_SUSPEND (QEMU stops SOF timer on this state change), this
> interrupt is never acknowledged.
>
> This patch clears pending SOF interrupt on OHCI_USB_SUSPEND setting.
>
> Some details:
>
> - ohci_irq(): the OHCI interrupt handler, acknowledges the SOF IRQ
> only if the state of the driver (rh_state) is OHCI_STATE_RUNNING.
> So if this interrupt happens and the driver is not in this state,
> the function is called again and again, moving the system to a
> CPU starvation.
>
> - ohci_rh_suspend(): the function stop the operation and acknowledge
> pending interrupts (but doesn't disable it). Later in the function,
> the device is moved to OHCI_SUSPEND_STATE, and the driver to
> OHCI_RH_SUSPENDED. If between the moment when the interrupt is
> acknowledged and the moment when the device is suspended a new
> interrupt is raised, it will be never acknowledged because the
> driver is now not in OHCI_RH_RUNNING state.
>
> Signed-off-by: Laurent Vivier <address@hidden>
> ---
> hw/usb/hcd-ohci.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
> index a44fab2..b99e44f 100644
> --- a/hw/usb/hcd-ohci.c
> +++ b/hw/usb/hcd-ohci.c
> @@ -1446,6 +1446,9 @@ static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
> break;
> case OHCI_USB_SUSPEND:
> ohci_bus_stop(ohci);
> + /* clear pending SF otherwise linux driver loops in ohci_irq() */
> + ohci->intr_status &= ~OHCI_INTR_SF;
> + ohci_intr_update(ohci);
> break;
> case OHCI_USB_RESUME:
> trace_usb_ohci_resume(ohci->name);
>
Reviewed-by: Thomas Huth <address@hidden>