Module Name:    src
Committed By:   yamaguchi
Date:           Thu Mar 23 03:02:17 UTC 2023

Modified Files:
        src/sys/dev/pci: if_vioif.c

Log Message:
vioif(4): divide IFF_OACTIVE into per-queue


To generate a diff of this commit:
cvs rdiff -u -r1.101 -r1.102 src/sys/dev/pci/if_vioif.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_vioif.c
diff -u src/sys/dev/pci/if_vioif.c:1.101 src/sys/dev/pci/if_vioif.c:1.102
--- src/sys/dev/pci/if_vioif.c:1.101	Thu Mar 23 02:57:54 2023
+++ src/sys/dev/pci/if_vioif.c	Thu Mar 23 03:02:17 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_vioif.c,v 1.101 2023/03/23 02:57:54 yamaguchi Exp $	*/
+/*	$NetBSD: if_vioif.c,v 1.102 2023/03/23 03:02:17 yamaguchi Exp $	*/
 
 /*
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.101 2023/03/23 02:57:54 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.102 2023/03/23 03:02:17 yamaguchi Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -266,6 +266,7 @@ struct vioif_netqueue {
 
 struct vioif_tx_context {
 	bool			 txc_link_active;
+	bool			 txc_no_free_slots;
 	pcq_t			*txc_intrq;
 	void			*txc_deferred_transmit;
 
@@ -730,7 +731,6 @@ vioif_init(struct ifnet *ifp)
 		sc->sc_act_nvq_pairs = 1;
 
 	SET(ifp->if_flags, IFF_RUNNING);
-	CLR(ifp->if_flags, IFF_OACTIVE);
 
 	vioif_net_intr_enable(sc, vsc);
 
@@ -860,7 +860,12 @@ vioif_watchdog(struct ifnet *ifp)
 	struct vioif_netqueue *netq;
 	int i;
 
-	if (ifp->if_flags & IFF_RUNNING) {
+	if (ISSET(ifp->if_flags, IFF_RUNNING)) {
+		if (ISSET(ifp->if_flags, IFF_DEBUG)) {
+			log(LOG_DEBUG, "%s: watchdog timed out\n",
+			    ifp->if_xname);
+		}
+
 		for (i = 0; i < sc->sc_act_nvq_pairs; i++) {
 			netq = &sc->sc_netqs[VIOIF_NETQ_TXQID(i)];
 
@@ -1496,6 +1501,7 @@ vioif_netqueue_init(struct vioif_softc *
 			goto err;
 		}
 		txc->txc_link_active = VIOIF_IS_LINK_ACTIVE(sc);
+		txc->txc_no_free_slots = false;
 		txc->txc_intrq = pcq_create(vq->vq_num, KM_SLEEP);
 		break;
 	}
@@ -1971,18 +1977,17 @@ vioif_send_common_locked(struct ifnet *i
 
 	txc = netq->netq_ctx;
 
-	if (!txc->txc_link_active)
-		return;
-
-	if (!is_transmit &&
-	    ISSET(ifp->if_flags, IFF_OACTIVE))
+	if (!txc->txc_link_active ||
+	    txc->txc_no_free_slots)
 		return;
 
 	for (;;) {
 		int slot, r;
 		r = virtio_enqueue_prep(vsc, vq, &slot);
-		if (r == EAGAIN)
+		if (r == EAGAIN) {
+			txc->txc_no_free_slots = true;
 			break;
+		}
 		if (__predict_false(r != 0))
 			panic("enqueue_prep for tx buffers");
 
@@ -2049,21 +2054,25 @@ vioif_send_common_locked(struct ifnet *i
 /* dequeue sent mbufs */
 static bool
 vioif_tx_deq_locked(struct vioif_softc *sc, struct virtio_softc *vsc,
-    struct vioif_netqueue *netq, u_int limit)
+    struct vioif_netqueue *netq, u_int limit, size_t *ndeqp)
 {
 	struct virtqueue *vq = netq->netq_vq;
 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 	struct vioif_net_map *map;
 	struct mbuf *m;
 	int slot, len;
-	bool more = false;
+	bool more;
+	size_t ndeq;
 
 	KASSERT(mutex_owned(&netq->netq_lock));
 
+	more = false;
+	ndeq = 0;
+
 	if (virtio_vq_is_enqueued(vsc, vq) == false)
-		return false;
+		goto done;
 
-	for (;;) {
+	for (;;ndeq++) {
 		if (limit-- == 0) {
 			more = true;
 			break;
@@ -2082,6 +2091,9 @@ vioif_tx_deq_locked(struct vioif_softc *
 		m_freem(m);
 	}
 
+done:
+	if (ndeqp != NULL)
+		*ndeqp = ndeq;
 	return more;
 }
 
@@ -2089,6 +2101,7 @@ static void
 vioif_tx_queue_clear(struct vioif_softc *sc, struct virtio_softc *vsc,
     struct vioif_netqueue *netq)
 {
+	struct vioif_tx_context *txc;
 	struct vioif_net_map *map;
 	struct mbuf *m;
 	unsigned int i, vq_num;
@@ -2096,9 +2109,11 @@ vioif_tx_queue_clear(struct vioif_softc 
 
 	mutex_enter(&netq->netq_lock);
 
+	txc = netq->netq_ctx;
 	vq_num = netq->netq_vq->vq_num;
+
 	for (;;) {
-		more = vioif_tx_deq_locked(sc, vsc, netq, vq_num);
+		more = vioif_tx_deq_locked(sc, vsc, netq, vq_num, NULL);
 		if (more == false)
 			break;
 	}
@@ -2113,6 +2128,9 @@ vioif_tx_queue_clear(struct vioif_softc 
 		vioif_net_unload_mbuf(vsc, map);
 		m_freem(m);
 	}
+
+	txc->txc_no_free_slots = false;
+
 	mutex_exit(&netq->netq_lock);
 }
 
@@ -2157,11 +2175,17 @@ vioif_tx_handle_locked(struct vioif_netq
 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 	bool more;
 	int enqueued;
+	size_t ndeq;
 
 	KASSERT(mutex_owned(&netq->netq_lock));
 	KASSERT(!netq->netq_stopping);
 
-	more = vioif_tx_deq_locked(sc, vsc, netq, limit);
+	more = vioif_tx_deq_locked(sc, vsc, netq, limit, &ndeq);
+	if (txc->txc_no_free_slots && ndeq > 0) {
+		txc->txc_no_free_slots = false;
+		softint_schedule(txc->txc_deferred_transmit);
+	}
+
 	if (more) {
 		vioif_net_sched_handle(sc, netq);
 		return;
@@ -2179,10 +2203,9 @@ vioif_tx_handle_locked(struct vioif_netq
 	netq->netq_running_handle = false;
 
 	/* for ALTQ */
-	if (netq == &sc->sc_netqs[VIOIF_NETQ_TXQID(0)]) {
+	if (netq == &sc->sc_netqs[VIOIF_NETQ_TXQID(0)])
 		if_schedule_deferred_start(ifp);
-		ifp->if_flags &= ~IFF_OACTIVE;
-	}
+
 	softint_schedule(txc->txc_deferred_transmit);
 }
 

Reply via email to