diff mbox series

[v2,2/2] switchtec: Fix unintended mask of MRPC event

Message ID 1555339302-31829-3-git-send-email-wesley.sheng@microchip.com
State Accepted
Delegated to: Bjorn Helgaas
Headers show
Series Fix two bugs of switchtec module | expand

Commit Message

Wesley Sheng April 15, 2019, 2:41 p.m. UTC
When running application tool switchtec-user's `firmware update` and
`event wait` commands concurrently, sometimes the firmware update
speed reduced evidently.

It is because when the MRPC event happened right after MRPC event
occurrence check but before event mask loop reach to its header
register in event ISR, the MRPC event would be masked unintentionally.
Since there's no chance to enable it again except for a module reload,
all the following MRPC execution completion check will be deferred to
timeout.

Fix this bug by skipping the mask operation for MRPC event in event
ISR, same as what we already do for LINK event.

Fixes: 52eabba5bcdb ("switchtec: Add IOCTLs to the Switchtec driver")
Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
---
 drivers/pci/switch/switchtec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Bjorn Helgaas April 18, 2019, 1:49 p.m. UTC | #1
On Mon, Apr 15, 2019 at 10:41:42PM +0800, Wesley Sheng wrote:
> When running application tool switchtec-user's `firmware update` and
> `event wait` commands concurrently, sometimes the firmware update
> speed reduced evidently.
> 
> It is because when the MRPC event happened right after MRPC event
> occurrence check but before event mask loop reach to its header
> register in event ISR, the MRPC event would be masked unintentionally.
> Since there's no chance to enable it again except for a module reload,
> all the following MRPC execution completion check will be deferred to
> timeout.
> 
> Fix this bug by skipping the mask operation for MRPC event in event
> ISR, same as what we already do for LINK event.
> 
> Fixes: 52eabba5bcdb ("switchtec: Add IOCTLs to the Switchtec driver")
> Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com>
> ---
>  drivers/pci/switch/switchtec.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
> index 7df9a69..30f6e08 100644
> --- a/drivers/pci/switch/switchtec.c
> +++ b/drivers/pci/switch/switchtec.c
> @@ -1177,7 +1177,8 @@ static int mask_event(struct switchtec_dev *stdev, int eid, int idx)
>  	if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ))
>  		return 0;
>  
> -	if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE)
> +	if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE ||
> +	    eid == SWITCHTEC_IOCTL_EVENT_MRPC_COMP)
>  		return 0;

I'm OK with this, but I do wonder why this check is in mask_event()
instead of in switchtec_event_isr().  AFAICT it doesn't depend on
anything in the mask_all_events() -> mask_event() path, and doing it
in switchtec_event_isr() would avoid the CSR read in mask_event().

But maybe it logically belongs here.  I'll merge it as-is for now.

>  	dev_dbg(&stdev->dev, "%s: %d %d %x\n", __func__, eid, idx, hdr);
> -- 
> 2.7.4
>
diff mbox series

Patch

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 7df9a69..30f6e08 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -1177,7 +1177,8 @@  static int mask_event(struct switchtec_dev *stdev, int eid, int idx)
 	if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ))
 		return 0;
 
-	if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE)
+	if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE ||
+	    eid == SWITCHTEC_IOCTL_EVENT_MRPC_COMP)
 		return 0;
 
 	dev_dbg(&stdev->dev, "%s: %d %d %x\n", __func__, eid, idx, hdr);