git: 3c52d24acb42 - main - iavf: Reschedule pending virtchnl replies after the processing budget

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Fri, 18 Sep 2026 12:00:41 UTC
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=3c52d24acb422f5d80f50612bd990ce760a19de8

commit 3c52d24acb422f5d80f50612bd990ce760a19de8
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-09-18 11:51:55 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-09-18 12:00:22 +0000

    iavf: Reschedule pending virtchnl replies after the processing budget
    
    The VC worker ignores the pending count returned by iavf_process_adminq.
    If a pass exhausts its message budget, replies can remain in the receive
    ring without another interrupt to schedule the worker.  During init,
    the iflib admin task cannot provide a backstop because init holds the
    context lock while waiting for ENABLE_QUEUES to complete.
    
    Reschedule the VC worker after a successful pass with messages remaining.
    Keep the per-pass budget and do not retry AdminQ errors.  Stop
    self-rescheduling once detach clears INITIALIZED; the existing polling
    and reset-recovery gates continue to exclude asynchronous processing.
    
    Validation: reproduced the timeout on a three queue E835 VF under
    Hyper-V.  Temporary tracing showed a successful ENABLE_QUEUES reply
    already in the guest receive ring after a three-message pass left two
    messages pending.  With the fix and no tracing, a GENERIC kernel with
    WITNESS and INVARIANTS passed three batches of 30 down/up and MTU
    1500/9000 cycles without enable/disable timeouts.
    
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
---
 sys/dev/iavf/if_iavf_iflib.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sys/dev/iavf/if_iavf_iflib.c b/sys/dev/iavf/if_iavf_iflib.c
index 0838eabbec1f..f0d1f39ee20c 100644
--- a/sys/dev/iavf/if_iavf_iflib.c
+++ b/sys/dev/iavf/if_iavf_iflib.c
@@ -434,9 +434,19 @@ static void
 iavf_vc_task(void *arg, int pending __unused)
 {
 	struct iavf_sc *sc = (struct iavf_sc *)arg;
-	u16 var;
+	enum iavf_status status;
+	u16 remaining = 0;
 
-	iavf_process_adminq(sc, &var);
+	status = iavf_process_adminq(sc, &remaining);
+	/*
+	 * A budget-limited pass may leave replies without another interrupt.
+	 * Keep processing them here: init can hold the iflib context lock
+	 * while waiting for a reply, preventing the iflib admin task from
+	 * making progress. Do not perpetuate the task during detach.
+	 */
+	if (status == IAVF_SUCCESS && remaining != 0 &&
+	    iavf_test_state(&sc->state, IAVF_STATE_INITIALIZED))
+		taskqueue_enqueue(sc->vc_tq, &sc->vc_task);
 }
 
 /**