All of lore.kernel.org
 help / color / mirror / Atom feed
From: Felipe Balbi <felipe.balbi@linux.intel.com>
To: Pawel Laszczak <pawell@cadence.com>,
	"devicetree\@vger.kernel.org" <devicetree@vger.kernel.org>
Cc: "gregkh\@linuxfoundation.org" <gregkh@linuxfoundation.org>,
	"linux-usb\@vger.kernel.org" <linux-usb@vger.kernel.org>,
	"hdegoede\@redhat.com" <hdegoede@redhat.com>,
	"heikki.krogerus\@linux.intel.com"
	<heikki.krogerus@linux.intel.com>,
	"robh+dt\@kernel.org" <robh+dt@kernel.org>,
	"rogerq\@ti.com" <rogerq@ti.com>,
	"linux-kernel\@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"jbergsagel\@ti.com" <jbergsagel@ti.com>,
	"nsekhar\@ti.com" <nsekhar@ti.com>, "nm\@ti.com" <nm@ti.com>,
	Suresh Punnoose <sureshp@cadence.com>,
	"peter.chen\@nxp.com" <peter.chen@nxp.com>,
	Jayshri Dajiram Pawar <jpawar@cadence.com>,
	Rahul Kumar <kurahul@cadence.com>
Subject: RE: [PATCH v9 5/6] usb:cdns3 Add Cadence USB3 DRD Driver
Date: Mon, 12 Aug 2019 11:19:19 +0300	[thread overview]
Message-ID: <87imr2u77c.fsf@gmail.com> (raw)
In-Reply-To: <BYAPR07MB470926DA6241B54FC5AF3C2ADDD30@BYAPR07MB4709.namprd07.prod.outlook.com>

[-- Attachment #1: Type: text/plain, Size: 4883 bytes --]


Hi,

Pawel Laszczak <pawell@cadence.com> writes:
>>> I have such situation in which one interrupt line is shared with ehci and cdns3 driver.
>>> In such case this function returns error code.
>>
>>which function returns error code?
>
> devm_request_threaded_irq, of course if I set IRQF_SHARED | IRQF_ONESHOT.
> As I remember it was EBUSY error.

oh, right. That's probably because the handlers must agree on IRQ flags.

>>> So probably I will need to mask only the reported interrupts.
>>
>>you should mask all interrupts from your device, otherwise you top-halt
>>may still end up reentrant.
>>
>>> I can't mask all interrupt using controller register because I can miss some of them.
>>
>>why would you miss them? They would be left in the register until you
>>unmask them and the line is raised again.
>
> I consult this with author of controller. 
> We have:
> USB_IEN  and USB_ISTS for  generic interrupts
> EP_IEN and EP_ISTS for endpoint interrupts 
>
> Both these group works different.
> For endpoint I can disable all interrupt and I don't miss any of them. 
> So it's normal behavior.
>
> But USB_ISTS work little different. If we mask all interrupt in USB_IEN
> then when new event occurs the EP_ISTS will not be updated. 

wait a minute. When you mask USB_ISTS, then EP_ISTS isn't updated? Is
this a quirk on the controller or a design choice?

> It's not standard and not expected behavior but it works in this way. 

Yeah, sounds rather odd.

>>>>>>> +	/* check USB device interrupt */
>>>>>>> +	reg = readl(&priv_dev->regs->usb_ists);
>>>>>>> +
>>>>>>> +	if (reg) {
>>>>>>> +		writel(reg, &priv_dev->regs->usb_ists);
>>>>>>> +		cdns3_check_usb_interrupt_proceed(priv_dev, reg);
>>>>>>> +		ret = IRQ_HANDLED;
>>>>>>
>>>>>>now, because you _don't_ mask this interrupt, you're gonna have
>>>>>>issues. Say we actually get both device and endpoint interrupts while
>>>>>>the thread is already running with previous endpoint interrupts. Now
>>>>>>we're gonna reenter the top half, because device interrupts are *not*
>>>>>>masked, which will read usb_ists and handle it here.
>>>>>
>>>>> Endpoint interrupts are masked in cdns3_device_irq_handler and stay masked
>>>>> until they are not handled in threaded handler.
>>>>
>>>>Quick question, then: these ISTS registers, are they masked interrupt
>>>>status or raw interrupt status?
>>>
>>> Yes it's masked, but after masking them the new interrupts will not be reported
>>> In ISTS registers. Form this reason I can mask only reported interrupt.
>>
>>and what happens when you unmask the registers? Do they get reported?
>
> No they are not reported in case of USB_ISTS register.
> They should be reported in case EP_ISTS, but I need to test it. 

okay, please _do_ test and verify the behavior. The description above
sounds really surprising to me. Does it really mean that if you mask all
USB_ISTS and then disconnect the cable while interrupt is masked, you
won't know cable was disconnected?

>>>>>>> +		struct cdns3_aligned_buf *buf, *tmp;
>>>>>>> +
>>>>>>> +		list_for_each_entry_safe(buf, tmp, &priv_dev->aligned_buf_list,
>>>>>>> +					 list) {
>>>>>>> +			if (!buf->in_use) {
>>>>>>> +				list_del(&buf->list);
>>>>>>> +
>>>>>>> +				spin_unlock_irqrestore(&priv_dev->lock, flags);
>>>>>>
>>>>>>creates the possibility of a race condition
>>>>> Why? In this place the buf can't be used.
>>>>
>>>>but you're reenabling interrupts, right?
>>>
>>> Yes, driver frees not used buffers here.
>>> I think that it's the safest place for this purpose.
>>
>>I guess you missed the point a little. Since you reenable interrupts
>>just to free the buffer, you end up creating the possibility for a race
>>condition. Specially since you don't mask all interrupt events. The
>>moment you reenable interrupts, one of your not-unmasked interrupt
>>sources could trigger, then top-half gets scheduled which tries to wake
>>up the IRQ thread again and things go boom.
>
> Ok, I think I understand.  So I have 3 options:
> 1. Mask the USB_IEN and EP_IEN interrupts, but then I can lost some USB_ISTS
> events. It's dangerous options. 

sure sounds dangerous, but also sounds quite "peculiar" :-)

> 2. Remove implementation of handling unaligned buffers and assume that 
>     upper layer will worry about this. What with vendor specific drivers that 
>     can be used by companies and not upstreamed  ? 
>     It could be good to have such safety mechanism even if it is not currently used.

dunno. It may become dead code that's NEVER used :-)

> 3. Delegate this part of code for instance to separate thread that will be called 
>    In free time. 

Yet another thread? Can't you just run this right before giving back the
USB request? So, don't do it from IRQ handler, but from giveback path?

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Felipe Balbi <felipe.balbi@linux.intel.com>
To: Pawel Laszczak <pawell@cadence.com>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>
Cc: "gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
	"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
	"hdegoede@redhat.com" <hdegoede@redhat.com>,
	"heikki.krogerus@linux.intel.com"
	<heikki.krogerus@linux.intel.com>,
	"robh+dt@kernel.org" <robh+dt@kernel.org>,
	"rogerq@ti.com" <rogerq@ti.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"jbergsagel@ti.com" <jbergsagel@ti.com>,
	"nsekhar@ti.com" <nsekhar@ti.com>, "nm@ti.com" <nm@ti.com>,
	Suresh Punnoose <sureshp@cadence.com>,
	"peter.chen@nxp.com" <peter.chen@nxp.com>,
	Jayshri Dajiram Pawar <jpawar@cadence.com>,
	Rahul Kumar <kurahul@cadence.com>
Subject: RE: [PATCH v9 5/6] usb:cdns3 Add Cadence USB3 DRD Driver
Date: Mon, 12 Aug 2019 11:19:19 +0300	[thread overview]
Message-ID: <87imr2u77c.fsf@gmail.com> (raw)
In-Reply-To: <BYAPR07MB470926DA6241B54FC5AF3C2ADDD30@BYAPR07MB4709.namprd07.prod.outlook.com>

[-- Attachment #1: Type: text/plain, Size: 4883 bytes --]


Hi,

Pawel Laszczak <pawell@cadence.com> writes:
>>> I have such situation in which one interrupt line is shared with ehci and cdns3 driver.
>>> In such case this function returns error code.
>>
>>which function returns error code?
>
> devm_request_threaded_irq, of course if I set IRQF_SHARED | IRQF_ONESHOT.
> As I remember it was EBUSY error.

oh, right. That's probably because the handlers must agree on IRQ flags.

>>> So probably I will need to mask only the reported interrupts.
>>
>>you should mask all interrupts from your device, otherwise you top-halt
>>may still end up reentrant.
>>
>>> I can't mask all interrupt using controller register because I can miss some of them.
>>
>>why would you miss them? They would be left in the register until you
>>unmask them and the line is raised again.
>
> I consult this with author of controller. 
> We have:
> USB_IEN  and USB_ISTS for  generic interrupts
> EP_IEN and EP_ISTS for endpoint interrupts 
>
> Both these group works different.
> For endpoint I can disable all interrupt and I don't miss any of them. 
> So it's normal behavior.
>
> But USB_ISTS work little different. If we mask all interrupt in USB_IEN
> then when new event occurs the EP_ISTS will not be updated. 

wait a minute. When you mask USB_ISTS, then EP_ISTS isn't updated? Is
this a quirk on the controller or a design choice?

> It's not standard and not expected behavior but it works in this way. 

Yeah, sounds rather odd.

>>>>>>> +	/* check USB device interrupt */
>>>>>>> +	reg = readl(&priv_dev->regs->usb_ists);
>>>>>>> +
>>>>>>> +	if (reg) {
>>>>>>> +		writel(reg, &priv_dev->regs->usb_ists);
>>>>>>> +		cdns3_check_usb_interrupt_proceed(priv_dev, reg);
>>>>>>> +		ret = IRQ_HANDLED;
>>>>>>
>>>>>>now, because you _don't_ mask this interrupt, you're gonna have
>>>>>>issues. Say we actually get both device and endpoint interrupts while
>>>>>>the thread is already running with previous endpoint interrupts. Now
>>>>>>we're gonna reenter the top half, because device interrupts are *not*
>>>>>>masked, which will read usb_ists and handle it here.
>>>>>
>>>>> Endpoint interrupts are masked in cdns3_device_irq_handler and stay masked
>>>>> until they are not handled in threaded handler.
>>>>
>>>>Quick question, then: these ISTS registers, are they masked interrupt
>>>>status or raw interrupt status?
>>>
>>> Yes it's masked, but after masking them the new interrupts will not be reported
>>> In ISTS registers. Form this reason I can mask only reported interrupt.
>>
>>and what happens when you unmask the registers? Do they get reported?
>
> No they are not reported in case of USB_ISTS register.
> They should be reported in case EP_ISTS, but I need to test it. 

okay, please _do_ test and verify the behavior. The description above
sounds really surprising to me. Does it really mean that if you mask all
USB_ISTS and then disconnect the cable while interrupt is masked, you
won't know cable was disconnected?

>>>>>>> +		struct cdns3_aligned_buf *buf, *tmp;
>>>>>>> +
>>>>>>> +		list_for_each_entry_safe(buf, tmp, &priv_dev->aligned_buf_list,
>>>>>>> +					 list) {
>>>>>>> +			if (!buf->in_use) {
>>>>>>> +				list_del(&buf->list);
>>>>>>> +
>>>>>>> +				spin_unlock_irqrestore(&priv_dev->lock, flags);
>>>>>>
>>>>>>creates the possibility of a race condition
>>>>> Why? In this place the buf can't be used.
>>>>
>>>>but you're reenabling interrupts, right?
>>>
>>> Yes, driver frees not used buffers here.
>>> I think that it's the safest place for this purpose.
>>
>>I guess you missed the point a little. Since you reenable interrupts
>>just to free the buffer, you end up creating the possibility for a race
>>condition. Specially since you don't mask all interrupt events. The
>>moment you reenable interrupts, one of your not-unmasked interrupt
>>sources could trigger, then top-half gets scheduled which tries to wake
>>up the IRQ thread again and things go boom.
>
> Ok, I think I understand.  So I have 3 options:
> 1. Mask the USB_IEN and EP_IEN interrupts, but then I can lost some USB_ISTS
> events. It's dangerous options. 

sure sounds dangerous, but also sounds quite "peculiar" :-)

> 2. Remove implementation of handling unaligned buffers and assume that 
>     upper layer will worry about this. What with vendor specific drivers that 
>     can be used by companies and not upstreamed  ? 
>     It could be good to have such safety mechanism even if it is not currently used.

dunno. It may become dead code that's NEVER used :-)

> 3. Delegate this part of code for instance to separate thread that will be called 
>    In free time. 

Yet another thread? Can't you just run this right before giving back the
USB request? So, don't do it from IRQ handler, but from giveback path?

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

  reply	other threads:[~2019-08-12  8:19 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-05 10:57 [PATCH v9 0/6] Introduced new Cadence USBSS DRD Driver Pawel Laszczak
2019-07-05 10:57 ` Pawel Laszczak
2019-07-05 10:57 ` [PATCH v9 1/6] dt-bindings: add binding for USBSS-DRD controller Pawel Laszczak
2019-07-05 10:57   ` Pawel Laszczak
2019-07-05 10:57 ` [PATCH v9 2/6] usb:gadget Separated decoding functions from dwc3 driver Pawel Laszczak
2019-07-05 10:57   ` Pawel Laszczak
2019-07-05 11:27   ` Greg KH
2019-07-05 11:39     ` Pawel Laszczak
2019-07-05 11:49       ` Greg KH
2019-07-05 12:03         ` Pawel Laszczak
2019-07-05 11:39   ` Felipe Balbi
2019-07-05 11:39     ` Felipe Balbi
2019-07-05 11:44     ` Pawel Laszczak
2019-08-07 10:17       ` Roger Quadros
2019-08-07 10:22         ` Felipe Balbi
2019-08-07 10:22           ` Felipe Balbi
2019-08-08  3:07           ` Pawel Laszczak
2019-07-05 10:57 ` [PATCH v9 3/6] usb:gadget Patch simplify usb_decode_set_clear_feature function Pawel Laszczak
2019-07-05 10:57   ` Pawel Laszczak
2019-07-05 10:57 ` [PATCH v9 4/6] usb:gadget Simplify usb_decode_get_set_descriptor function Pawel Laszczak
2019-07-05 10:57   ` Pawel Laszczak
2019-07-05 10:57 ` [PATCH v9 5/6] usb:cdns3 Add Cadence USB3 DRD Driver Pawel Laszczak
2019-07-05 10:57   ` Pawel Laszczak
2019-07-05 11:55   ` Felipe Balbi
2019-07-05 11:55     ` Felipe Balbi
2019-07-07 17:56     ` Pawel Laszczak
2019-07-08  6:29       ` Felipe Balbi
2019-07-08  6:29         ` Felipe Balbi
2019-07-08 10:59         ` Pawel Laszczak
2019-07-08 11:15           ` Felipe Balbi
2019-07-08 11:15             ` Felipe Balbi
2019-07-08 11:45             ` Pawel Laszczak
2019-07-08 11:59               ` Felipe Balbi
2019-07-08 11:59                 ` Felipe Balbi
2019-07-08 12:39                 ` Pawel Laszczak
2019-07-09  4:23         ` Pawel Laszczak
2019-07-09  6:36           ` Felipe Balbi
2019-07-09  6:36             ` Felipe Balbi
2019-07-09  7:07             ` Pawel Laszczak
2019-07-09  7:07               ` Pawel Laszczak
2019-07-09  7:22               ` Felipe Balbi
2019-07-09  7:22                 ` Felipe Balbi
2019-07-09  7:29                 ` Pawel Laszczak
2019-07-10  8:25       ` Pawel Laszczak
2019-07-08  7:11   ` Felipe Balbi
2019-07-08  7:11     ` Felipe Balbi
2019-07-15 11:00     ` Pawel Laszczak
2019-08-07 10:34       ` Felipe Balbi
2019-08-07 10:34         ` Felipe Balbi
2019-08-10 20:39         ` Pawel Laszczak
2019-08-12  1:55           ` Peter Chen
2019-08-12  4:43             ` Pawel Laszczak
2019-08-12  5:24           ` Felipe Balbi
2019-08-12  5:24             ` Felipe Balbi
2019-08-12  7:13             ` Pawel Laszczak
2019-08-12  8:19               ` Felipe Balbi [this message]
2019-08-12  8:19                 ` Felipe Balbi
2019-08-12  9:13                 ` Pawel Laszczak
2019-08-12  9:45                   ` Felipe Balbi
2019-08-12  9:45                     ` Felipe Balbi
2019-08-12 10:26                     ` Pawel Laszczak
2019-08-12 10:34                       ` Felipe Balbi
2019-08-12 10:34                         ` Felipe Balbi
2019-08-12 14:20                         ` Alan Stern
2019-07-05 10:57 ` [PATCH v9 6/6] usb:cdns3 Fix for stuck packets in on-chip OUT buffer Pawel Laszczak
2019-07-05 10:57   ` Pawel Laszczak

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=87imr2u77c.fsf@gmail.com \
    --to=felipe.balbi@linux.intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hdegoede@redhat.com \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=jbergsagel@ti.com \
    --cc=jpawar@cadence.com \
    --cc=kurahul@cadence.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=nm@ti.com \
    --cc=nsekhar@ti.com \
    --cc=pawell@cadence.com \
    --cc=peter.chen@nxp.com \
    --cc=robh+dt@kernel.org \
    --cc=rogerq@ti.com \
    --cc=sureshp@cadence.com \
    /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: link
Be 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.