[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/3] Conditionally restart the RX ring from packet return


  • To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Date: Sat, 11 Jul 2026 13:52:34 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID"
  • Cc: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Delivery-date: Sat, 11 Jul 2026 11:52:50 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

Currently, the RX ring is restarted on packet return regardless of
whether there are sufficient resources to afford it. In cases where the
packet cache has been exhausted, restarting the RX ring will be
counterproductive.

Make ReceiverRingFill return STATUS_SUCCESS only if the RX ring has
been filled without errors. Base the decision of restarting the RX ring
from __ReceiverRingReturnPacket on this return status.

Move __ReceiverRingReturnPacket below ReceiverRingFill as the former now
makes use of the latter.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
 src/xenvif/receiver.c | 95 +++++++++++++++++++++++--------------------
 1 file changed, 51 insertions(+), 44 deletions(-)

diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c
index 359935c..29bd325 100644
--- a/src/xenvif/receiver.c
+++ b/src/xenvif/receiver.c
@@ -1709,49 +1709,6 @@ __ReceiverRingSend(
         __ReceiverRingReleaseLock(Ring);
 }
 
-_IRQL_requires_(DISPATCH_LEVEL)
-static FORCEINLINE VOID
-__ReceiverRingReturnPacket(
-    IN  PXENVIF_RECEIVER_RING   Ring,
-    IN  PXENVIF_RECEIVER_PACKET Packet,
-    IN  BOOLEAN                 Locked
-    )
-{
-    PMDL                        Mdl;
-
-    Mdl = &Packet->Mdl;
-
-    while (Mdl != NULL) {
-        PMDL    Next;
-
-        Next = Mdl->Next;
-        Mdl->Next = NULL;
-
-        __ReceiverRingPutMdl(Ring, Mdl, Locked);
-
-        Mdl = Next;
-    }
-
-    if (__ReceiverRingIsStopped(Ring)) {
-        KIRQL   Irql;
-
-        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-
-        if (!Locked)
-            __ReceiverRingAcquireLock(Ring);
-
-        if (__ReceiverRingIsStopped(Ring)) {
-            __ReceiverRingStart(Ring);
-            __ReceiverRingTrigger(Ring, TRUE);
-        }
-
-        if (!Locked)
-            __ReceiverRingReleaseLock(Ring);
-
-        KeLowerIrql(Irql);
-    }
-}
-
 static FORCEINLINE PXENVIF_RECEIVER_FRAGMENT
 __ReceiverRingPreparePacket(
     IN  PXENVIF_RECEIVER_RING   Ring,
@@ -1828,7 +1785,7 @@ __ReceiverRingPushRequests(
     Ring->RequestsPushed = Ring->RequestsPosted;
 }
 
-static VOID
+static NTSTATUS
 ReceiverRingFill(
     IN  PXENVIF_RECEIVER_RING   Ring
     )
@@ -1837,6 +1794,7 @@ ReceiverRingFill(
     PXENVIF_FRONTEND            Frontend;
     RING_IDX                    req_prod;
     RING_IDX                    rsp_cons;
+    NTSTATUS                    status;
 
     Receiver = Ring->Receiver;
     Frontend = Receiver->Frontend;
@@ -1848,6 +1806,7 @@ ReceiverRingFill(
 
     KeMemoryBarrier();
 
+    status = STATUS_SUCCESS;
     while (req_prod - rsp_cons < RING_SIZE(&Ring->Front)) {
         PXENVIF_RECEIVER_PACKET     Packet;
         PXENVIF_RECEIVER_FRAGMENT   Fragment;
@@ -1857,6 +1816,7 @@ ReceiverRingFill(
         Packet = __ReceiverRingGetPacket(Ring, TRUE);
 
         if (Packet == NULL) {
+            status = STATUS_INSUFFICIENT_RESOURCES;
             __ReceiverRingStop(Ring);
             break;
         }
@@ -1864,6 +1824,7 @@ ReceiverRingFill(
         Fragment = __ReceiverRingPreparePacket(Ring, Packet);
         
         if (Fragment == NULL) {
+            status = STATUS_INSUFFICIENT_RESOURCES;
             __ReceiverRingPutPacket(Ring, Packet, TRUE);
             break;
         }
@@ -1889,6 +1850,52 @@ ReceiverRingFill(
     Ring->Front.req_prod_pvt = req_prod;
 
     __ReceiverRingPushRequests(Ring);
+
+    return status;
+}
+
+_IRQL_requires_(DISPATCH_LEVEL)
+static FORCEINLINE VOID
+__ReceiverRingReturnPacket(
+    IN  PXENVIF_RECEIVER_RING   Ring,
+    IN  PXENVIF_RECEIVER_PACKET Packet,
+    IN  BOOLEAN                 Locked
+    )
+{
+    PMDL                        Mdl;
+
+    Mdl = &Packet->Mdl;
+
+    while (Mdl != NULL) {
+        PMDL    Next;
+
+        Next = Mdl->Next;
+        Mdl->Next = NULL;
+
+        __ReceiverRingPutMdl(Ring, Mdl, Locked);
+
+        Mdl = Next;
+    }
+
+    if (__ReceiverRingIsStopped(Ring)) {
+        KIRQL   Irql;
+
+        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+
+        if (!Locked)
+            __ReceiverRingAcquireLock(Ring);
+
+        if (__ReceiverRingIsStopped(Ring) &&
+            NT_SUCCESS(ReceiverRingFill(Ring))) {
+            __ReceiverRingStart(Ring);
+            __ReceiverRingTrigger(Ring, TRUE);
+        }
+
+        if (!Locked)
+            __ReceiverRingReleaseLock(Ring);
+
+        KeLowerIrql(Irql);
+    }
 }
 
 static FORCEINLINE VOID
-- 
2.54.0.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.