• Amit Cohen's avatar
    mlxsw: pci: Use NAPI for event processing · 3b0b3019
    Amit Cohen authored
    Spectrum ASICs only support a single interrupt, that means that all the
    events are handled by one IRQ (interrupt request) handler. Once an
    interrupt is received, we schedule tasklet to handle events from EQ and
    then schedule tasklets to handle completions from CQs. Tasklet runs in
    softIRQ (software IRQ) context, and will be run on the same CPU which
    scheduled it. That means that today we use only one CPU to handle all the
    packets (both network packets and EMADs) from hardware.
    
    This can be improved using NAPI. The idea is to use NAPI instance per
    CQ, which is mapped 1:1 to DQ (RDQ or SDQ). NAPI poll method can be run
    in kernel thread, so then the driver will be able to handle WQEs in several
    CPUs. Convert the existing code to use NAPI APIs.
    
    Add NAPI instance as part of 'struct mlxsw_pci_queue' and initialize it
    as part of CQs initialization. Set the appropriate poll method and dummy
    net device, according to queue number, similar to tasklet setup. For CQs
    which are used for completions of RDQ, use Rx poll method and
    'napi_dev_rx', which is set as 'threaded'. It means that Rx poll method
    will run in kernel context, so several RDQs will be handled in parallel.
    For CQs which are used for completions of SDQ, use Tx poll method and
    'napi_dev_tx', this method will run in softIRQ context, as it is
    recommended in NAPI documentation, as Tx packets' processing is short task.
    
    Convert mlxsw_pci_cq_{rx,tx}_tasklet() to poll methods. Handle 'budget'
    argument - ignore it in Tx poll method, as it is recommended to not limit
    Tx processing. For Rx processing, handle up to 'budget' completions.
    Return 'work_done' which is the amount of completions that were handled.
    
    Handle the following cases:
    1. After processing 'budget' completions, the driver still has work to do:
       Return work-done = budget. In that case, the NAPI instance will be
       polled again (without the need to be rescheduled). Do not re-arm the
       queue, as NAPI will handle the reschedule, so we do not have to involve
       hardware to send an additional interrupt for the completions that should
       be processed.
    
    2. Event processing has been completed:
       Call napi_complete_done() to mark NAPI processing as completed, which
       means that the poll method will not be rescheduled. Re-arm the queue,
       as all completions were handled.
    
       In case that poll method handled exactly 'budget' completions, return
       work-done = budget -1, to distinguish from the case that driver still
       has completions to handle. Otherwise, return the amount of completions
       that were handled.
    Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
    Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
    Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    3b0b3019
pci.c 61.6 KB