if_vtnet: let vtnet_rx_vq_intr() and vtnet_rxq_tq_intr() share code
Since the two functions are similar, introduce a common function (vtnet_rx_vq_process()) to share common code. This also improves locking, by ensuring vrxs_rescheduled is accessed under the RXQ lock, and taskqueue_enqueue() is not called under the lock (therefore avoiding a spurious duplicate lock warning). Reported by: jrtc27 MFC after: 2 weeks
This commit is contained in:
parent
99282790b7
commit
ef6fdb3312
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362204
@ -128,6 +128,7 @@ static int vtnet_rxq_merged_eof(struct vtnet_rxq *, struct mbuf *, int);
|
|||||||
static void vtnet_rxq_input(struct vtnet_rxq *, struct mbuf *,
|
static void vtnet_rxq_input(struct vtnet_rxq *, struct mbuf *,
|
||||||
struct virtio_net_hdr *);
|
struct virtio_net_hdr *);
|
||||||
static int vtnet_rxq_eof(struct vtnet_rxq *);
|
static int vtnet_rxq_eof(struct vtnet_rxq *);
|
||||||
|
static void vtnet_rx_vq_process(struct vtnet_rxq *rxq, int tries);
|
||||||
static void vtnet_rx_vq_intr(void *);
|
static void vtnet_rx_vq_intr(void *);
|
||||||
static void vtnet_rxq_tq_intr(void *, int);
|
static void vtnet_rxq_tq_intr(void *, int);
|
||||||
|
|
||||||
@ -1915,20 +1916,17 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vtnet_rx_vq_intr(void *xrxq)
|
vtnet_rx_vq_process(struct vtnet_rxq *rxq, int tries)
|
||||||
{
|
{
|
||||||
struct vtnet_softc *sc;
|
struct vtnet_softc *sc;
|
||||||
struct vtnet_rxq *rxq;
|
|
||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
int tries, more;
|
int more;
|
||||||
#ifdef DEV_NETMAP
|
#ifdef DEV_NETMAP
|
||||||
int nmirq;
|
int nmirq;
|
||||||
#endif /* DEV_NETMAP */
|
#endif /* DEV_NETMAP */
|
||||||
|
|
||||||
rxq = xrxq;
|
|
||||||
sc = rxq->vtnrx_sc;
|
sc = rxq->vtnrx_sc;
|
||||||
ifp = sc->vtnet_ifp;
|
ifp = sc->vtnet_ifp;
|
||||||
tries = 0;
|
|
||||||
|
|
||||||
if (__predict_false(rxq->vtnrx_id >= sc->vtnet_act_vq_pairs)) {
|
if (__predict_false(rxq->vtnrx_id >= sc->vtnet_act_vq_pairs)) {
|
||||||
/*
|
/*
|
||||||
@ -1976,58 +1974,32 @@ vtnet_rx_vq_intr(void *xrxq)
|
|||||||
* This is an occasional condition or race (when !more),
|
* This is an occasional condition or race (when !more),
|
||||||
* so retry a few times before scheduling the taskqueue.
|
* so retry a few times before scheduling the taskqueue.
|
||||||
*/
|
*/
|
||||||
if (tries++ < VTNET_INTR_DISABLE_RETRIES)
|
if (tries-- > 0)
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
VTNET_RXQ_UNLOCK(rxq);
|
|
||||||
rxq->vtnrx_stats.vrxs_rescheduled++;
|
rxq->vtnrx_stats.vrxs_rescheduled++;
|
||||||
|
VTNET_RXQ_UNLOCK(rxq);
|
||||||
taskqueue_enqueue(rxq->vtnrx_tq, &rxq->vtnrx_intrtask);
|
taskqueue_enqueue(rxq->vtnrx_tq, &rxq->vtnrx_intrtask);
|
||||||
} else
|
} else
|
||||||
VTNET_RXQ_UNLOCK(rxq);
|
VTNET_RXQ_UNLOCK(rxq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vtnet_rxq_tq_intr(void *xrxq, int pending)
|
vtnet_rx_vq_intr(void *xrxq)
|
||||||
{
|
{
|
||||||
struct vtnet_softc *sc;
|
|
||||||
struct vtnet_rxq *rxq;
|
struct vtnet_rxq *rxq;
|
||||||
struct ifnet *ifp;
|
|
||||||
int more;
|
|
||||||
#ifdef DEV_NETMAP
|
|
||||||
int nmirq;
|
|
||||||
#endif /* DEV_NETMAP */
|
|
||||||
|
|
||||||
rxq = xrxq;
|
rxq = xrxq;
|
||||||
sc = rxq->vtnrx_sc;
|
vtnet_rx_vq_process(rxq, VTNET_INTR_DISABLE_RETRIES);
|
||||||
ifp = sc->vtnet_ifp;
|
}
|
||||||
|
|
||||||
VTNET_RXQ_LOCK(rxq);
|
static void
|
||||||
|
vtnet_rxq_tq_intr(void *xrxq, int pending)
|
||||||
|
{
|
||||||
|
struct vtnet_rxq *rxq;
|
||||||
|
|
||||||
#ifdef DEV_NETMAP
|
rxq = xrxq;
|
||||||
nmirq = netmap_rx_irq(ifp, rxq->vtnrx_id, &more);
|
vtnet_rx_vq_process(rxq, 0);
|
||||||
if (nmirq != NM_IRQ_PASS) {
|
|
||||||
VTNET_RXQ_UNLOCK(rxq);
|
|
||||||
if (nmirq == NM_IRQ_RESCHED) {
|
|
||||||
taskqueue_enqueue(rxq->vtnrx_tq, &rxq->vtnrx_intrtask);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* DEV_NETMAP */
|
|
||||||
|
|
||||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
|
||||||
VTNET_RXQ_UNLOCK(rxq);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
more = vtnet_rxq_eof(rxq);
|
|
||||||
if (more || vtnet_rxq_enable_intr(rxq) != 0) {
|
|
||||||
if (!more)
|
|
||||||
vtnet_rxq_disable_intr(rxq);
|
|
||||||
rxq->vtnrx_stats.vrxs_rescheduled++;
|
|
||||||
taskqueue_enqueue(rxq->vtnrx_tq, &rxq->vtnrx_intrtask);
|
|
||||||
}
|
|
||||||
|
|
||||||
VTNET_RXQ_UNLOCK(rxq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user