iflib: netmap: honor netmap_irx_irq return values
In the receive interrupt routine, always call netmap_rx_irq(). The latter function will return != NM_IRQ_PASS if netmap is not active on that specific receive queue, so that the driver can go on with iflib_rxeof(). Note that netmap supports partial opening, where only a subset of the RX or TX rings can be open in netmap mode. Checking the IFCAP_NETMAP flag is not enough to make sure that the queue is indeed in netmap mode. Moreover, in case netmap_rx_irq() returns NM_IRQ_RESCHED, it means that netmap expects the driver to call netmap_rx_irq() again as soon as possible. Currently, this may happen when the device is attached to a VALE switch. Reviewed by: gallatin MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D25167
This commit is contained in:
parent
3163f6aa26
commit
e136e9c88f
@ -3790,6 +3790,10 @@ _task_fn_rx(void *context)
|
||||
if_ctx_t ctx = rxq->ifr_ctx;
|
||||
uint8_t more;
|
||||
uint16_t budget;
|
||||
#ifdef DEV_NETMAP
|
||||
u_int work = 0;
|
||||
int nmirq;
|
||||
#endif
|
||||
|
||||
#ifdef IFLIB_DIAGNOSTICS
|
||||
rxq->ifr_cpu_exec_count[curcpu]++;
|
||||
@ -3798,12 +3802,10 @@ _task_fn_rx(void *context)
|
||||
if (__predict_false(!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)))
|
||||
return;
|
||||
#ifdef DEV_NETMAP
|
||||
if (if_getcapenable(ctx->ifc_ifp) & IFCAP_NETMAP) {
|
||||
u_int work = 0;
|
||||
if (netmap_rx_irq(ctx->ifc_ifp, rxq->ifr_id, &work)) {
|
||||
more = 0;
|
||||
goto skip_rxeof;
|
||||
}
|
||||
nmirq = netmap_rx_irq(ctx->ifc_ifp, rxq->ifr_id, &work);
|
||||
if (nmirq != NM_IRQ_PASS) {
|
||||
more = (nmirq == NM_IRQ_RESCHED) ? IFLIB_RXEOF_MORE : 0;
|
||||
goto skip_rxeof;
|
||||
}
|
||||
#endif
|
||||
budget = ctx->ifc_sysctl_rx_budget;
|
||||
|
Loading…
x
Reference in New Issue
Block a user