in google/gve/gve_main.c [313:361]
int gve_napi_poll(struct napi_struct *napi, int budget)
{
struct gve_notify_block *block;
__be32 __iomem *irq_doorbell;
bool reschedule = false;
struct gve_priv *priv;
int work_done = 0;
block = container_of(napi, struct gve_notify_block, napi);
priv = block->priv;
if (block->tx) {
if (block->tx->q_num < priv->tx_cfg.num_queues)
reschedule |= gve_tx_poll(block, budget);
else if (budget)
reschedule |= gve_xdp_poll(block, budget);
}
if (!budget)
return 0;
if (block->rx) {
work_done = gve_rx_poll(block, budget);
reschedule |= work_done == budget;
}
if (reschedule)
return budget;
/* Complete processing - don't unmask irq if busy polling is enabled */
if (likely(napi_complete_done(napi, work_done))) {
irq_doorbell = gve_irq_doorbell(priv, block);
iowrite32be(GVE_IRQ_ACK | GVE_IRQ_EVENT, irq_doorbell);
/* Ensure IRQ ACK is visible before we check pending work.
* If queue had issued updates, it would be truly visible.
*/
mb();
if (block->tx)
reschedule |= gve_tx_clean_pending(priv, block->tx);
if (block->rx)
reschedule |= gve_rx_work_pending(block->rx);
if (reschedule && napi_schedule(napi))
iowrite32be(GVE_IRQ_MASK, irq_doorbell);
}
return work_done;
}