static int xenvif_poll(struct napi_struct *napi, int budget) { struct xenvif_queue *queue = container_of(napi, struct xenvif_queue, napi); int work_done; /* This vif is rogue, we pretend we've there is nothing to do * for this vif to deschedule it from NAPI. But this interface * will be turned off in thread context later. */ if (unlikely(queue->vif->disabled)) { napi_complete(napi); return 0; } work_done = xenvif_tx_action(queue, budget); if (work_done < budget) { napi_complete_done(napi, work_done); /* If the queue is rate-limited, it shall be * rescheduled in the timer callback. */ if (likely(!queue->rate_limited)) xenvif_napi_schedule_or_enable_events(queue); } return work_done; }
int xenvif_poll(struct napi_struct *napi, int budget) { struct xenvif_queue *queue = container_of(napi, struct xenvif_queue, napi); int work_done; /* This vif is rogue, we pretend we've there is nothing to do * for this vif to deschedule it from NAPI. But this interface * will be turned off in thread context later. * Also, if a guest doesn't post enough slots to receive data on one of * its queues, the carrier goes down and NAPI is descheduled here so * the guest can't send more packets until it's ready to receive. */ if (unlikely(queue->vif->disabled || !netif_carrier_ok(queue->vif->dev))) { napi_complete(napi); return 0; } work_done = xenvif_tx_action(queue, budget); if (work_done < budget) { napi_complete(napi); xenvif_napi_schedule_or_enable_events(queue); } return work_done; }
static int xenvif_poll(struct napi_struct *napi, int budget) { struct xenvif *vif = container_of(napi, struct xenvif, napi); int work_done; /* This vif is rogue, we pretend we've there is nothing to do * for this vif to deschedule it from NAPI. But this interface * will be turned off in thread context later. */ if (unlikely(vif->disabled)) { napi_complete(napi); return 0; } work_done = xenvif_tx_action(vif, budget); if (work_done < budget) { int more_to_do = 0; unsigned long flags; /* It is necessary to disable IRQ before calling * RING_HAS_UNCONSUMED_REQUESTS. Otherwise we might * lose event from the frontend. * * Consider: * RING_HAS_UNCONSUMED_REQUESTS * <frontend generates event to trigger napi_schedule> * __napi_complete * * This handler is still in scheduled state so the * event has no effect at all. After __napi_complete * this handler is descheduled and cannot get * scheduled again. We lose event in this case and the ring * will be completely stalled. */ local_irq_save(flags); RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, more_to_do); if (!more_to_do) __napi_complete(napi); local_irq_restore(flags); } return work_done; }
static int xenvif_poll(struct napi_struct *napi, int budget) { struct xenvif *vif = container_of(napi, struct xenvif, napi); int work_done; /* This vif is rogue, we pretend we've there is nothing to do * for this vif to deschedule it from NAPI. But this interface * will be turned off in thread context later. */ if (unlikely(vif->disabled)) { napi_complete(napi); return 0; } work_done = xenvif_tx_action(vif, budget); if (work_done < budget) { napi_complete(napi); xenvif_napi_schedule_or_enable_events(vif); } return work_done; }