diff options
Diffstat (limited to 'sys/dev/netmap/if_vtnet_netmap.h')
| -rw-r--r-- | sys/dev/netmap/if_vtnet_netmap.h | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/sys/dev/netmap/if_vtnet_netmap.h b/sys/dev/netmap/if_vtnet_netmap.h index 4bed0e718dd49..10789c53d1f06 100644 --- a/sys/dev/netmap/if_vtnet_netmap.h +++ b/sys/dev/netmap/if_vtnet_netmap.h @@ -122,6 +122,7 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int flags) struct SOFTC_T *sc = ifp->if_softc; struct vtnet_txq *txq = &sc->vtnet_txqs[ring_nr]; struct virtqueue *vq = txq->vtntx_vq; + int interrupts = !(kring->nr_kflags & NKR_NOINTR); /* * First part: process new packets to send. @@ -179,7 +180,9 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int flags) ring->head, ring->tail, virtqueue_nused(vq), (virtqueue_dump(vq), 1)); virtqueue_notify(vq); - virtqueue_enable_intr(vq); // like postpone with 0 + if (interrupts) { + virtqueue_enable_intr(vq); // like postpone with 0 + } } @@ -209,7 +212,7 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int flags) if (nm_i != kring->nr_hwtail /* && vtnet_txq_below_threshold(txq) == 0*/) { ND(3, "disable intr, hwcur %d", nm_i); virtqueue_disable_intr(vq); - } else { + } else if (interrupts) { ND(3, "enable intr, hwcur %d", nm_i); virtqueue_postpone_intr(vq, VQ_POSTPONE_SHORT); } @@ -277,6 +280,7 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) u_int const lim = kring->nkr_num_slots - 1; u_int const head = kring->rhead; int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; + int interrupts = !(kring->nr_kflags & NKR_NOINTR); /* device-specific */ struct SOFTC_T *sc = ifp->if_softc; @@ -297,7 +301,6 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) * and vtnet_netmap_init_buffers(). */ if (netmap_no_pendintr || force_update) { - uint16_t slot_flags = kring->nkr_slot_flags; struct netmap_adapter *token; nm_i = kring->nr_hwtail; @@ -309,7 +312,7 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) break; if (likely(token == (void *)rxq)) { ring->slot[nm_i].len = len; - ring->slot[nm_i].flags = slot_flags; + ring->slot[nm_i].flags = 0; nm_i = nm_next(nm_i, lim); n++; } else { @@ -334,7 +337,9 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) kring->nr_hwcur = err; virtqueue_notify(vq); /* After draining the queue may need an intr from the hypervisor */ - vtnet_rxq_enable_intr(rxq); + if (interrupts) { + vtnet_rxq_enable_intr(rxq); + } } ND("[C] h %d c %d t %d hwcur %d hwtail %d", @@ -345,6 +350,28 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int flags) } +/* Enable/disable interrupts on all virtqueues. */ +static void +vtnet_netmap_intr(struct netmap_adapter *na, int onoff) +{ + struct SOFTC_T *sc = na->ifp->if_softc; + int i; + + for (i = 0; i < sc->vtnet_max_vq_pairs; i++) { + struct vtnet_rxq *rxq = &sc->vtnet_rxqs[i]; + struct vtnet_txq *txq = &sc->vtnet_txqs[i]; + struct virtqueue *txvq = txq->vtntx_vq; + + if (onoff) { + vtnet_rxq_enable_intr(rxq); + virtqueue_enable_intr(txvq); + } else { + vtnet_rxq_disable_intr(rxq); + virtqueue_disable_intr(txvq); + } + } +} + /* Make RX virtqueues buffers pointing to netmap buffers. */ static int vtnet_netmap_init_rx_buffers(struct SOFTC_T *sc) @@ -417,6 +444,7 @@ vtnet_netmap_attach(struct SOFTC_T *sc) na.nm_txsync = vtnet_netmap_txsync; na.nm_rxsync = vtnet_netmap_rxsync; na.nm_config = vtnet_netmap_config; + na.nm_intr = vtnet_netmap_intr; na.num_tx_rings = na.num_rx_rings = sc->vtnet_max_vq_pairs; D("max rings %d", sc->vtnet_max_vq_pairs); netmap_attach(&na); |
