Regarding NAPI implementation in Linux kernel

前端 未结 1 1177
生来不讨喜
生来不讨喜 2021-01-03 06:35

I am trying to understand the NAPI enabled Network driver and have some doubts regarding the same.

If I talk about in layman\'s term whenever a network packets comes

相关标签:
1条回答
  • 2021-01-03 06:56

    Now for NAPI enabled Ethernet driver initially whenever packets comes at interface ,it is notified to CPU and appropriate Ethernet driver code (Interrupt handler) is executed .Inside the interrupt handler code we check if type of interrupt is received packet.

    What it mean by disabling further interrupts?

    Normally a driver would clear the condition causing the interrupt. The NAPI driver, however, may also disable the receive interrupt when the ISR is done.
    The assumption is that the arrival of one Ethernet frame may be the start of a burst or flood of frames. So instead of exiting interrupt mode and likely immediately reentering interrupt mode, why not test (i.e. poll) if more frames have already arrived?

    Is it mean packets are still captured by device

    Yes.
    Each arriving frame is stored by the Ethernet controller in a frame buffer.

    and kept in device memory

    It's not typically "device memory".
    It is typically a set of buffers (e.g. ring buffer) allocated in main memory assigned to the Ethernet controller.

    but not notified to CPU about the availability of these packets?

    Since the receive interrupt has been disabled, the NAPI driver is not notified of this event.
    But since the driver is busy processing the previous frame, the interrupt request could not be serviced immediately anyway.

    Also ,what it mean by CPU is pooling the device ,

    Presumably you are actually asking about "polling"?
    Polling simply means that the program (i.e. the driver) interrogates (i.e. reads and tests) status bit(s) for the condition it is waiting for.
    If the condition is met, then it will process the event in a manner similar to an interrupt for that event.
    If the condition is not met, then it may loop (in the generic case). But the NAPI driver, when the poll indicates that no more frames have arrived, will assume that the packet burst or flood is over, and will resume interrupt mode.

    is it like CPU after every few second will run snull_poll() method and copy whatever number of packets are in device memory to DMA Buffer and pushed to Upper layer?

    The NAPI driver would not delay or suspend itself for a "few second"s before polling.
    The assumption is that Ethernet frames could be flooding the port, so the poll would be performed as soon as processing on the current frame is complete.

    A possible bug in a NAPI driver is called "rotting packet".
    When the driver transitions from the poll mode back to interrupt mode, a frame could arrive during this transition and be undetected by the driver.
    Not until another frame arrives (and generates an interrupt) would the previous frame be "found" and processed by the NAPI driver.

    BTW
    You consistently write statements or questions similar to "the CPU does ..." or "notified to CPU".
    The CPU is always (when not sleeping or powered off) executing machine instructions.
    You should be concerned about to which logical entity (i.e. which program or source code module) those instructions belong.
    You're asking software questions, so the fact that an interrupt causes a known, certain sequence by the CPU is a given and need not be mentioned.

    ADDENDUM

    I am just trying to understand drivers/net/ethernet/smsc/smsc911x.c in Linux source code.

    The SMSC LAN911x Ethernet chips are more sophisticated than what I'm used to and have been describing above. Besides the MAC, these chips also have an integrated PHY, and have TX and RX FIFOs instead of using buffer ring or lists in main memory.

    As per your suggestion I have started reading the SMSCLan9118 datasheet and trying to map it with smsc911x_irqhandler function where interrupt status (INT_STS) and interrupt enable (INT_EN) registers have been read but don't get how
    if (likely(intsts & inten & INT_STS_RSFL_))
    condition is checked here in line 1627.

    INT_STS is defined in the header file as

    #define INT_STS                         0x58
    

    and the table in Section 5.3, System Control and Status Registers, in the datasheet lists the register at (relative) address 0x58 as

    58h INT_STS Interrupt Status 
    

    So the smsc911x device driver uses the exact same register name as the HW datasheet.
    This 32-bit register is read using this register offset in the ISR using:

    u32 intsts = smsc911x_reg_read(pdata, INT_STS);
    

    So the 32 bits of the interrupt status (in variable intsts) is Boolean ANDed with the 32 bits of the interrupt mask (in variable inten).
    This produces the interrupt status bits that the driver are actually interested in. This may also be good defensive programming in case the HW sets status bits anyway for interrupt conditions that have not been enabled (in the INT_EN register).
    Then that if statement does another Boolean AND to extract the one bit (INT_STS_RSFL_) that is being checked.

    5.3.3 INT_STS—Interrupt Status Register
    
    RX Status FIFO Level Interrupt (RSFL).
    Generated when the RX Status FIFO reaches the programmed level
    

    The likely() operator is for compiler optimization to utilize branch prediction capabilities in the CPU. The driver's author is directing the compiler to optimize the code for a true result of the enclosed logic expression (e.g. the ANDing of three integers, which would indicate an interrupt condition that needs servicing).

    Also on recieving the packet on interface which bit is set on which register.

    My take on reading the LAN9118 datasheet is that there really is no interrupt specifically for the receipt of a frame.
    Instead the host can be notified when the RX FIFO exceeds a threshold.

    5.3.6 FIFO_INT—FIFO Level Interrupts
    
    RX Status Level.
    The value in this field sets the level, in number of DWORDs, at which the RX Status FIFO Level interrupt (RSFL) will be generated. 
    When the RX Status FIFO used space is greater than this value an RX Status FIFO Level interrupt (RSFL) will be generated. 
    

    The smsc911x driver apparently uses this threshold at its default value of zero.
    Each entry in the RX Status FIFO occupies a DWORD. The default value of this threshold is 0x00 (i.e. interrupt on "first" frame). If this threshold is more than zero, then there is the possibility of "rotting packets".

    0 讨论(0)
提交回复
热议问题