[gPXE] interrupt disabling in pxenv_undi_isr()

Michael Brown mbrown at fensystems.co.uk
Tue May 18 14:41:46 EDT 2010


On Tuesday 18 May 2010 16:00:17 Alex Zeffertt wrote:
> I've noticed in pxe_undi.c that when the NBP calls PXENV_UNDI_ISR:START
> interrupts get disabled.  They are only re-enabled when the NBP calls
> PXENV_UNDI_ISR:GET_NEXT and this returns DONE because there are no more
>  packets.
> 
> What happens if a packet is received by the NIC between when
> PXENV_UNDI_ISR:GET_NEXT calls netdev_poll() and when
>  PXENV_UNDI_ISR:GET_NEXT returns DONE?
> 
> Would the NBP lose the interrupt and not know that it needs to call
> PXENV_UNDI_ISR:START again?

No.  If the driver is written correctly, then this mechanism is race-free.  

If a packet arrives after the driver's poll() routine has acknowledged the 
interrupt, then it will re-assert the interrupt condition within the NIC.  
This will result in a fresh interrupt as soon as interrupts are re-enabled, so 
no events are lost.

For this to function correctly, the driver and hardware must exhibit the 
following properties:

1. It must be possible for the hardware to support the notion of a pending 
interrupt that is masked out and so not asserted onto the PCI bus.  Most cards 
will support this; the typical legacy interrupt mechanism is to have an 
internal read-clear (or write-clear) register that represents the state of 
whether or not the card *wants* to assert an interrupt, and this is gated by 
the overall interrupt mask register before it reaches the PCI INT# line.

2. The driver's poll() routine must be written so that the interrupt 
acknowledgement happens *before* descriptor rings etc are checked.

Some cards use more sophisticated interrupt mechanisms (e.g. involving writing 
a consumer counter value to an internal register, rather than simply 
acknowledging all events); separate reasoning will apply here but the end 
result should still be race-free operation.

Michael


More information about the gPXE mailing list