Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/virtio/network/if_vtnet.c
Show First 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | |||||
static int vtnet_rxq_merged_eof(struct vtnet_rxq *, struct mbuf *, int); | 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_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); | ||||
static int vtnet_txq_intr_threshold(struct vtnet_txq *); | |||||
static int vtnet_txq_below_threshold(struct vtnet_txq *); | static int vtnet_txq_below_threshold(struct vtnet_txq *); | ||||
static int vtnet_txq_notify(struct vtnet_txq *); | static int vtnet_txq_notify(struct vtnet_txq *); | ||||
static void vtnet_txq_free_mbufs(struct vtnet_txq *); | static void vtnet_txq_free_mbufs(struct vtnet_txq *); | ||||
static int vtnet_txq_offload_ctx(struct vtnet_txq *, struct mbuf *, | static int vtnet_txq_offload_ctx(struct vtnet_txq *, struct mbuf *, | ||||
int *, int *, int *); | int *, int *, int *); | ||||
static int vtnet_txq_offload_tso(struct vtnet_txq *, struct mbuf *, int, | static int vtnet_txq_offload_tso(struct vtnet_txq *, struct mbuf *, int, | ||||
int, struct virtio_net_hdr *); | int, struct virtio_net_hdr *); | ||||
static struct mbuf * | static struct mbuf * | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
static void vtnet_update_link_status(struct vtnet_softc *); | static void vtnet_update_link_status(struct vtnet_softc *); | ||||
static int vtnet_ifmedia_upd(struct ifnet *); | static int vtnet_ifmedia_upd(struct ifnet *); | ||||
static void vtnet_ifmedia_sts(struct ifnet *, struct ifmediareq *); | static void vtnet_ifmedia_sts(struct ifnet *, struct ifmediareq *); | ||||
static void vtnet_get_macaddr(struct vtnet_softc *); | static void vtnet_get_macaddr(struct vtnet_softc *); | ||||
static void vtnet_set_macaddr(struct vtnet_softc *); | static void vtnet_set_macaddr(struct vtnet_softc *); | ||||
static void vtnet_attached_set_macaddr(struct vtnet_softc *); | static void vtnet_attached_set_macaddr(struct vtnet_softc *); | ||||
static void vtnet_vlan_tag_remove(struct mbuf *); | static void vtnet_vlan_tag_remove(struct mbuf *); | ||||
static void vtnet_set_rx_process_limit(struct vtnet_softc *); | static void vtnet_set_rx_process_limit(struct vtnet_softc *); | ||||
static void vtnet_set_tx_intr_threshold(struct vtnet_softc *); | |||||
static void vtnet_setup_rxq_sysctl(struct sysctl_ctx_list *, | static void vtnet_setup_rxq_sysctl(struct sysctl_ctx_list *, | ||||
struct sysctl_oid_list *, struct vtnet_rxq *); | struct sysctl_oid_list *, struct vtnet_rxq *); | ||||
static void vtnet_setup_txq_sysctl(struct sysctl_ctx_list *, | static void vtnet_setup_txq_sysctl(struct sysctl_ctx_list *, | ||||
struct sysctl_oid_list *, struct vtnet_txq *); | struct sysctl_oid_list *, struct vtnet_txq *); | ||||
static void vtnet_setup_queue_sysctl(struct vtnet_softc *); | static void vtnet_setup_queue_sysctl(struct vtnet_softc *); | ||||
static void vtnet_setup_sysctl(struct vtnet_softc *); | static void vtnet_setup_sysctl(struct vtnet_softc *); | ||||
▲ Show 20 Lines • Show All 854 Lines • ▼ Show 20 Lines | if (sc->vtnet_flags & VTNET_FLAG_VLAN_FILTER) { | ||||
sc->vtnet_vlan_attach = EVENTHANDLER_REGISTER(vlan_config, | sc->vtnet_vlan_attach = EVENTHANDLER_REGISTER(vlan_config, | ||||
vtnet_register_vlan, sc, EVENTHANDLER_PRI_FIRST); | vtnet_register_vlan, sc, EVENTHANDLER_PRI_FIRST); | ||||
sc->vtnet_vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, | sc->vtnet_vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, | ||||
vtnet_unregister_vlan, sc, EVENTHANDLER_PRI_FIRST); | vtnet_unregister_vlan, sc, EVENTHANDLER_PRI_FIRST); | ||||
} | } | ||||
vtnet_set_rx_process_limit(sc); | vtnet_set_rx_process_limit(sc); | ||||
vtnet_set_tx_intr_threshold(sc); | |||||
DEBUGNET_SET(ifp, vtnet); | DEBUGNET_SET(ifp, vtnet); | ||||
pa.pa_version = PFIL_VERSION; | pa.pa_version = PFIL_VERSION; | ||||
pa.pa_flags = PFIL_IN; | pa.pa_flags = PFIL_IN; | ||||
pa.pa_type = PFIL_TYPE_ETHERNET; | pa.pa_type = PFIL_TYPE_ETHERNET; | ||||
pa.pa_headname = ifp->if_xname; | pa.pa_headname = ifp->if_xname; | ||||
sc->vtnet_pfil = pfil_head_register(&pa); | sc->vtnet_pfil = pfil_head_register(&pa); | ||||
▲ Show 20 Lines • Show All 917 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct vtnet_rxq *rxq; | struct vtnet_rxq *rxq; | ||||
rxq = xrxq; | rxq = xrxq; | ||||
vtnet_rx_vq_process(rxq, 0); | vtnet_rx_vq_process(rxq, 0); | ||||
} | } | ||||
static int | static int | ||||
vtnet_txq_below_threshold(struct vtnet_txq *txq) | vtnet_txq_intr_threshold(struct vtnet_txq *txq) | ||||
{ | { | ||||
struct vtnet_softc *sc; | struct vtnet_softc *sc; | ||||
struct virtqueue *vq; | int threshold; | ||||
sc = txq->vtntx_sc; | sc = txq->vtntx_sc; | ||||
/* | |||||
* The Tx interrupt is disabled until the queue free count falls | |||||
* below our threshold. Completed frames are drained from the Tx | |||||
* virtqueue before transmitting new frames and in the watchdog | |||||
* callout, so the frequency of Tx interrupts is greatly reduced, | |||||
* at the cost of not freeing mbufs as quickly as they otherwise | |||||
* would be. | |||||
*/ | |||||
threshold = virtqueue_size(txq->vtntx_vq) / 4; | |||||
/* | |||||
* Without indirect descriptors, leave enough room for the most | |||||
* segments we handle. | |||||
*/ | |||||
if ((sc->vtnet_flags & VTNET_FLAG_INDIRECT) == 0 && | |||||
threshold < sc->vtnet_tx_nsegs) | |||||
threshold = sc->vtnet_tx_nsegs; | |||||
return (threshold); | |||||
} | |||||
static int | |||||
vtnet_txq_below_threshold(struct vtnet_txq *txq) | |||||
{ | |||||
struct virtqueue *vq; | |||||
vq = txq->vtntx_vq; | vq = txq->vtntx_vq; | ||||
return (virtqueue_nfree(vq) <= sc->vtnet_tx_intr_thresh); | return (virtqueue_nfree(vq) <= txq->vtntx_intr_threshold); | ||||
} | } | ||||
static int | static int | ||||
vtnet_txq_notify(struct vtnet_txq *txq) | vtnet_txq_notify(struct vtnet_txq *txq) | ||||
{ | { | ||||
struct virtqueue *vq; | struct virtqueue *vq; | ||||
vq = txq->vtntx_vq; | vq = txq->vtntx_vq; | ||||
▲ Show 20 Lines • Show All 1,009 Lines • ▼ Show 20 Lines | |||||
vtnet_init_tx_queues(struct vtnet_softc *sc) | vtnet_init_tx_queues(struct vtnet_softc *sc) | ||||
{ | { | ||||
struct vtnet_txq *txq; | struct vtnet_txq *txq; | ||||
int i; | int i; | ||||
for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { | for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { | ||||
txq = &sc->vtnet_txqs[i]; | txq = &sc->vtnet_txqs[i]; | ||||
txq->vtntx_watchdog = 0; | txq->vtntx_watchdog = 0; | ||||
txq->vtntx_intr_threshold = vtnet_txq_intr_threshold(txq); | |||||
#ifdef DEV_NETMAP | #ifdef DEV_NETMAP | ||||
netmap_reset(NA(sc->vtnet_ifp), NR_TX, i, 0); | netmap_reset(NA(sc->vtnet_ifp), NR_TX, i, 0); | ||||
#endif /* DEV_NETMAP */ | #endif /* DEV_NETMAP */ | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 673 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
int limit; | int limit; | ||||
limit = vtnet_tunable_int(sc, "rx_process_limit", | limit = vtnet_tunable_int(sc, "rx_process_limit", | ||||
vtnet_rx_process_limit); | vtnet_rx_process_limit); | ||||
if (limit < 0) | if (limit < 0) | ||||
limit = INT_MAX; | limit = INT_MAX; | ||||
sc->vtnet_rx_process_limit = limit; | sc->vtnet_rx_process_limit = limit; | ||||
} | |||||
static void | |||||
vtnet_set_tx_intr_threshold(struct vtnet_softc *sc) | |||||
{ | |||||
int size, thresh; | |||||
size = virtqueue_size(sc->vtnet_txqs[0].vtntx_vq); | |||||
/* | |||||
* The Tx interrupt is disabled until the queue free count falls | |||||
* below our threshold. Completed frames are drained from the Tx | |||||
* virtqueue before transmitting new frames and in the watchdog | |||||
* callout, so the frequency of Tx interrupts is greatly reduced, | |||||
* at the cost of not freeing mbufs as quickly as they otherwise | |||||
* would be. | |||||
* | |||||
* N.B. We assume all the Tx queues are the same size. | |||||
*/ | |||||
thresh = size / 4; | |||||
/* | |||||
* Without indirect descriptors, leave enough room for the most | |||||
* segments we handle. | |||||
*/ | |||||
if ((sc->vtnet_flags & VTNET_FLAG_INDIRECT) == 0 && | |||||
thresh < sc->vtnet_tx_nsegs) | |||||
thresh = sc->vtnet_tx_nsegs; | |||||
sc->vtnet_tx_intr_thresh = thresh; | |||||
} | } | ||||
static void | static void | ||||
vtnet_setup_rxq_sysctl(struct sysctl_ctx_list *ctx, | vtnet_setup_rxq_sysctl(struct sysctl_ctx_list *ctx, | ||||
struct sysctl_oid_list *child, struct vtnet_rxq *rxq) | struct sysctl_oid_list *child, struct vtnet_rxq *rxq) | ||||
{ | { | ||||
struct sysctl_oid *node; | struct sysctl_oid *node; | ||||
struct sysctl_oid_list *list; | struct sysctl_oid_list *list; | ||||
▲ Show 20 Lines • Show All 343 Lines • Show Last 20 Lines |