Search Linux Wireless

RE: [PATCH v2] rtw88: pci: enable MSI interrupt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

A few scattered comments below.

> From: Daniel Drake [mailto:drake@xxxxxxxxxxxx]
> 
> On Tue, Aug 27, 2019 at 8:11 PM Tony Chuang <yhchuang@xxxxxxxxxxx>
> wrote:
> > Because there's a race condition between SW/HW when clearing the ISR.
> > If interrupt comes after reading ISR and before write-1-clear, the interrupt
> > controller would have interrupt status raised, and never issue interrupt
> > signal to host when other new interrupts status are raised.
> >
> > To avoid this, driver requires to protect the ISR write-1-clear process by
> > disabling the IMR.
> 
> Just to be clear with an example of two interrupts in quick
> succession, first ROK then MGNTDOK. I would expect the hardware to
> behave as follows:
> 
> 1. Interrupts are enabled in HIMR reg. MSI is in use.
> --- Hardware needs to flag RX condition. It sets IMR_ROK flag in HISR,
> then raises a MSI interrupt.
> --- Interrupt controller receives this and begins handling it:
> 2. rtw88 interrupt handler begins execution
> 3. rtw_pci_irq_recognized()  reads HISR values. ROK is the only bit set.
> --- Hardware needs to flag MGNTDOK condition, so it sets the MGNTDOK
> bit in HISR and raises another interrupt.
> --- Interrupt controller queues this interrupt since it's in the
> middle of handling the original ROK interrupt.
> 4. Back in rtw_pci_irq_recognized(), the HISR values from earlier are
> written back to clear them. In this case just the ROK bit is written
> back to unset the interrupt. MGNTDOK interrupt is left pending (not
> yet noticed by the driver)
> 5. Interrupt handler continues & finishes handling the RX event.
> 6. With the first interrupt done, interrupt controller handles the
> queued interrupt and causes rtw88 interrupt handler to execute again
> 7. rtw88 interrupt handler handles and MGNTDOK interrupt.
> 
> 
> But are you saying it does not do this, and the behaviour (without
> your change) is instead:
> 
> 1. Interrupts are enabled in HIMR reg. MSI is in use.
> --- Hardware needs to flag RX condition. It sets IMR_ROK flag in HISR,
> then raises a MSI interrupt.
> --- Interrupt controller receives this and begins handling it:
> 2. rtw88 interrupt handler begins execution
> 3. rtw_pci_irq_recognized()  reads HISR values. ROK is the only bit set.
> --- Hardware needs to flag MGNTDOK condition, so it sets the MGNTDOK
> bit in HISR. However it does NOT raise an interrupt since other bits
> in HISR were still set at this time.
> 4. Back in rtw_pci_irq_recognized(), the HISR values from earlier are
> written back. In this case just the ROK bit is written back to unset
> the interrupt. MGNTDOK interrupt is left pending (not yet noticed by
> the driver)
> 5. Interrupt handler continues & finishes handling the RX event.
> 6. MGNTDOK interrupt is left pending, and no more interrupts will be
> generated by the hardware because even if it sets more HISR bits, the
> MGNTDOK bit was already set so it doesn't raise more interrupts.
> 
> i.e. you're effectively saying that the hardware will *only* generate
> an interrupt when *all* HISR bits were zero immediately before the new
> interrupt HISR bit is set?

Yes, that's what I am saying about. I know it looks strange, but I think
this is Realtek's design. And as far as I know this has been used for 9-10
years.

> 
> 
> And then with your change applied it would look like this:
> 
> 1. Interrupts are enabled in HIMR reg. MSI is in use.
> --- Hardware needs to flag RX condition. It sets IMR_ROK flag in HISR,
> then raises a MSI interrupt.
> --- Interrupt controller receives this and begins handling it:
> 2. rtw88 interrupt handler begins execution
> 3. Interrupts are disabled in HIMR reg.
> 4. rtw_pci_irq_recognized()  reads HISR values. ROK is the only bit set.
> --- Hardware needs to flag MGNTDOK condition, however because
> interrupts are disabled in HIMR, it simply queues this condition
> internally, without affecting HISR values, without generating another
> interrupt.

This might be a little different here, I think the MGNTDOK flag is still set.
But new interrupt will not be generated, until HIMR is re-enabled, and I
think re-enabling the HIMR could trigger the hardware to check if any
HISR bit is set, and then generate interrupt.

> 4. Back in rtw_pci_irq_recognized(), the HISR values from earlier are
> written back. In this case just the ROK bit is written back to unset
> the interrupt. HISR is now value 0.
> 5. Interrupt handler handles the RX event.
> 6. Interrupt handler re-enables interrupts in HIMR just before finishing.
> --- In response, hardware checks its internal queue and realises that
> a MGNTDOK condition is pending. It sets the MGNTDOK bit in HISR and
> raises a new interrupt.
> 
> Is that right? It seems like strange behaviour on the hardware side.
> 

Indeed it is a little strange but it works like that, if I don't disable HIMR,
interrupt could be lost and never gets into interrupt handler again.
If so, the interrupt will be stopped, and TX/RX path will be freezed.

> 
> Thanks,
> Daniel
> 

Thanks,
Yan-Hsuan




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux