> -----Original Message-----
> From: Benjamin Poirier <bpoir...@suse.com>
> Sent: Monday, June 17, 2019 1:19 PM
> To: Manish Chopra <mani...@marvell.com>; GR-Linux-NIC-Dev <GR-Linux-
> nic-...@marvell.com>; netdev@vger.kernel.org
> Subject: [PATCH net-next 01/16] qlge: Remove irq_cnt
> 
> qlge uses an irq enable/disable refcounting scheme that is:
> * poorly implemented
>       Uses a spin_lock to protect accesses to the irq_cnt atomic variable
> * buggy
>       Breaks when there is not a 1:1 sequence of irq - napi_poll, such as
>       when using SO_BUSY_POLL.
> * unnecessary
>       The purpose or irq_cnt is to reduce irq control writes when
>       multiple work items result from one irq: the irq is re-enabled
>       after all work is done.
>       Analysis of the irq handler shows that there is only one case where
>       there might be two workers scheduled at once, and those have
>       separate irq masking bits.

I believe you are talking about here for asic error recovery worker and MPI 
worker.
Which separate IRQ masking bits are you referring here ?

>  static int ql_validate_flash(struct ql_adapter *qdev, u32 size, const char 
> *str)
> @@ -2500,21 +2451,22 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
>       u32 var;
>       int work_done = 0;
> 
> -     spin_lock(&qdev->hw_lock);
> -     if (atomic_read(&qdev->intr_context[0].irq_cnt)) {
> -             netif_printk(qdev, intr, KERN_DEBUG, qdev->ndev,
> -                          "Shared Interrupt, Not ours!\n");
> -             spin_unlock(&qdev->hw_lock);
> -             return IRQ_NONE;
> -     }
> -     spin_unlock(&qdev->hw_lock);
> +     /* Experience shows that when using INTx interrupts, the device does
> +      * not always auto-mask the interrupt.
> +      * When using MSI mode, the interrupt must be explicitly disabled
> +      * (even though it is auto-masked), otherwise a later command to
> +      * enable it is not effective.
> +      */
> +     if (!test_bit(QL_MSIX_ENABLED, &qdev->flags))
> +             ql_disable_completion_interrupt(qdev, 0);

Current code is disabling completion interrupt in case of MSI-X zeroth vector.
This change will break that behavior. Shouldn't zeroth vector in case of MSI-X 
also disable completion interrupt ?
If not, please explain why ?

> 
> -     var = ql_disable_completion_interrupt(qdev, intr_context->intr);
> +     var = ql_read32(qdev, STS);
> 
>       /*
>        * Check for fatal error.
>        */
>       if (var & STS_FE) {
> +             ql_disable_completion_interrupt(qdev, 0);

Why need to do it again here ? if before this it can disable completion 
interrupt for INT-X case and MSI-X zeroth vector case ?

>               ql_queue_asic_error(qdev);
>               netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var);
>               var = ql_read32(qdev, ERR_STS);
> @@ -2534,7 +2486,6 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
>                */
>               netif_err(qdev, intr, qdev->ndev,
>                         "Got MPI processor interrupt.\n");
> -             ql_disable_completion_interrupt(qdev, intr_context->intr);

Why disable interrupt is not required here ?  While in case of Fatal error case 
above ql_disable_completion_interrupt() is being called ?
Also, in case of MSI-X zeroth vector it will not disable completion interrupt 
but at the end, it will end of qlge_isr() enabling completion interrupt.
Seems like disabling and enabling might not be in sync in case of MSI-X zeroth 
vector.


Reply via email to