From: Roger Quadros <rogerq@ti.com> To: Manu Gautam <mgautam@codeaurora.org>, <balbi@kernel.org> Cc: <linux-usb@vger.kernel.org>, <linux-kernel@vger.kernel.org> Subject: Re: [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume Date: Thu, 15 Feb 2018 09:45:06 +0200 [thread overview] Message-ID: <d3963657-e902-771c-967f-e35315c110e0@ti.com> (raw) In-Reply-To: <b9089d1d-a773-ae05-b9ea-8dec0328cb29@ti.com> Felipe, On 25/01/18 18:11, Roger Quadros wrote: > Hi, > > On 24/01/18 14:19, Roger Quadros wrote: >> On 23/01/18 14:41, Roger Quadros wrote: >>> Hi Manu, >>> >>> On 23/01/18 05:45, Manu Gautam wrote: >>>> Hi, >>>> >>>> >>>> On 1/22/2018 6:31 PM, Roger Quadros wrote: >>>>> Adding/removing host/gadget controller before .pm_complete() >>>>> causes a lock-up. Let's prevent any dual-role state change >>>>> between .pm_prepare() and .pm_complete() to fix this. >>>> >>>> What kind of lock-up are you seeing? Some hardware lockup or software deadlock? >>>> IMO using a freezable_wq for drd_work should address that? >>>> >>> >>> I was seeing a software deadlock. freezable_wq is a good idea. I'll try it out. >> >> using freezable_wq doesn't get rid of the deadlock. >> If I use freezable_wq plus add some delay before I do a dwc3_host_init() >> in the work function then it starts to work. >> >> As dependence on delay looks fragile so I'll stick to the current implementation >> based on .pm_prepare/complete(). >> > > So I was able to reproduce the lock up with my series as well. On further investigation > this is what I see. > > There are 2 different scenarios. > > 1) controller in host mode prior to system suspend and switches to device mode during resume. > > In this case when we call dwc3_host_exit() before tasks are thawed > xhci_plat_remove() seems to lock up at the second usb_remove_hcd() call. > This issue is resolved by using system_freezable_wq for the _dwc3_set_mode() function. > > > 2) controller in device mode prior to system suspend and switches to host mode during resume. > > In this case we sleep indefinitely in _dwc3_set_mode due to > dwc3_set_mode()->dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq() > > This is not resolved by moving the dwc3_set_mode() call to .pm_complete() nor via the system_freezable_wq. > > One way I could fix this is like so. > > Felipe, could you please suggest a better way? > Maybe we need to do this in dwc3_gadget_exit() before calling usb_del_gadget_udc() ? Once you let me know your opinion I can revise this series. Thanks. > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index b417d9a..0c903c1 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -109,6 +109,7 @@ static void __dwc3_set_mode(struct work_struct *work) > struct dwc3 *dwc = work_to_dwc(work); > unsigned long flags; > int ret; > + int epnum; > > if (!dwc->desired_dr_role) > return; > @@ -124,6 +125,17 @@ static void __dwc3_set_mode(struct work_struct *work) > dwc3_host_exit(dwc); > break; > case DWC3_GCTL_PRTCAP_DEVICE: > + spin_lock_irqsave(&dwc->lock, flags); > + for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) { > + struct dwc3_ep *dep = dwc->eps[epnum]; > + > + if (!dep) > + continue; > + > + dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; > + } > + spin_unlock_irqrestore(&dwc->lock, flags); > + > dwc3_gadget_exit(dwc); > dwc3_event_buffers_cleanup(dwc); > break; > -- cheers, -roger Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
WARNING: multiple messages have this Message-ID (diff)
From: Roger Quadros <rogerq@ti.com> To: Manu Gautam <mgautam@codeaurora.org>, balbi@kernel.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume Date: Thu, 15 Feb 2018 09:45:06 +0200 [thread overview] Message-ID: <d3963657-e902-771c-967f-e35315c110e0@ti.com> (raw) Felipe, On 25/01/18 18:11, Roger Quadros wrote: > Hi, > > On 24/01/18 14:19, Roger Quadros wrote: >> On 23/01/18 14:41, Roger Quadros wrote: >>> Hi Manu, >>> >>> On 23/01/18 05:45, Manu Gautam wrote: >>>> Hi, >>>> >>>> >>>> On 1/22/2018 6:31 PM, Roger Quadros wrote: >>>>> Adding/removing host/gadget controller before .pm_complete() >>>>> causes a lock-up. Let's prevent any dual-role state change >>>>> between .pm_prepare() and .pm_complete() to fix this. >>>> >>>> What kind of lock-up are you seeing? Some hardware lockup or software deadlock? >>>> IMO using a freezable_wq for drd_work should address that? >>>> >>> >>> I was seeing a software deadlock. freezable_wq is a good idea. I'll try it out. >> >> using freezable_wq doesn't get rid of the deadlock. >> If I use freezable_wq plus add some delay before I do a dwc3_host_init() >> in the work function then it starts to work. >> >> As dependence on delay looks fragile so I'll stick to the current implementation >> based on .pm_prepare/complete(). >> > > So I was able to reproduce the lock up with my series as well. On further investigation > this is what I see. > > There are 2 different scenarios. > > 1) controller in host mode prior to system suspend and switches to device mode during resume. > > In this case when we call dwc3_host_exit() before tasks are thawed > xhci_plat_remove() seems to lock up at the second usb_remove_hcd() call. > This issue is resolved by using system_freezable_wq for the _dwc3_set_mode() function. > > > 2) controller in device mode prior to system suspend and switches to host mode during resume. > > In this case we sleep indefinitely in _dwc3_set_mode due to > dwc3_set_mode()->dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq() > > This is not resolved by moving the dwc3_set_mode() call to .pm_complete() nor via the system_freezable_wq. > > One way I could fix this is like so. > > Felipe, could you please suggest a better way? > Maybe we need to do this in dwc3_gadget_exit() before calling usb_del_gadget_udc() ? Once you let me know your opinion I can revise this series. Thanks. > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index b417d9a..0c903c1 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -109,6 +109,7 @@ static void __dwc3_set_mode(struct work_struct *work) > struct dwc3 *dwc = work_to_dwc(work); > unsigned long flags; > int ret; > + int epnum; > > if (!dwc->desired_dr_role) > return; > @@ -124,6 +125,17 @@ static void __dwc3_set_mode(struct work_struct *work) > dwc3_host_exit(dwc); > break; > case DWC3_GCTL_PRTCAP_DEVICE: > + spin_lock_irqsave(&dwc->lock, flags); > + for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) { > + struct dwc3_ep *dep = dwc->eps[epnum]; > + > + if (!dep) > + continue; > + > + dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; > + } > + spin_unlock_irqrestore(&dwc->lock, flags); > + > dwc3_gadget_exit(dwc); > dwc3_event_buffers_cleanup(dwc); > break; >
next prev parent reply other threads:[~2018-02-15 7:45 UTC|newest] Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-01-22 13:01 [PATCH 0/2] usb: dwc3: Fix dual role during system suspend/resume Roger Quadros 2018-01-22 13:01 ` [PATCH 1/2] usb: dwc3: omap: don't miss events during suspend/resume Roger Quadros 2018-01-22 13:01 ` [1/2] " Roger Quadros 2018-01-22 13:01 ` [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume Roger Quadros 2018-01-22 13:01 ` [2/2] " Roger Quadros 2018-01-23 3:45 ` [PATCH 2/2] " Manu Gautam 2018-01-23 3:45 ` [2/2] " Manu Gautam 2018-01-23 12:41 ` [PATCH 2/2] " Roger Quadros 2018-01-23 12:41 ` [2/2] " Roger Quadros 2018-01-24 12:19 ` [PATCH 2/2] " Roger Quadros 2018-01-24 12:19 ` [2/2] " Roger Quadros 2018-01-25 16:11 ` [PATCH 2/2] " Roger Quadros 2018-01-25 16:11 ` [2/2] " Roger Quadros 2018-02-15 7:45 ` Roger Quadros [this message] 2018-02-15 7:45 ` Roger Quadros 2018-02-12 8:54 ` [PATCH 2/2] " Felipe Balbi 2018-02-12 8:54 ` [2/2] " Felipe Balbi 2018-02-12 10:48 ` [PATCH 2/2] " Roger Quadros 2018-02-12 10:48 ` [2/2] " Roger Quadros
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=d3963657-e902-771c-967f-e35315c110e0@ti.com \ --to=rogerq@ti.com \ --cc=balbi@kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-usb@vger.kernel.org \ --cc=mgautam@codeaurora.org \ /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.