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

[RFC PATCH 5/9] granter: Decouple cache lifetime from Connected


  • To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Date: Fri, 23 Oct 2026 17:14:13 +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: Fri, 23 Oct 2026 15:14:30 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

We must keep the cache alive until the very last grant has been released
by the backend.

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
 src/xenvbd/granter.c | 129 +++++++++++++++++++++++++++++++------------
 1 file changed, 95 insertions(+), 34 deletions(-)

diff --git a/src/xenvbd/granter.c b/src/xenvbd/granter.c
index 74a786d..2a10f57 100644
--- a/src/xenvbd/granter.c
+++ b/src/xenvbd/granter.c
@@ -100,11 +100,26 @@ fail1:
     return status;
 }
 
+static VOID
+__GranterDestroyCache(
+    _Inout_ PXENVBD_GRANTER Granter
+    );
+
 VOID
 GranterDestroy(
     _Inout_ PXENVBD_GRANTER Granter
     )
 {
+    BUG_ON(Granter->Current != 0);
+
+    if (Granter->Cache != NULL) {
+        KIRQL   Irql;
+
+        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+        __GranterDestroyCache(Granter);
+        KeLowerIrql(Irql);
+    }
+
     Granter->Frontend = NULL;
     RtlZeroMemory(&Granter->Lock, sizeof(KSPIN_LOCK));
 
@@ -166,8 +181,8 @@ GranterDebugCallback(
 
 #define MAXNAMELEN  32
 
-NTSTATUS
-GranterConnect(
+static NTSTATUS
+__GranterCreateCache(
     _Inout_ PXENVBD_GRANTER Granter
     )
 {
@@ -175,25 +190,20 @@ GranterConnect(
     CHAR                    Name[MAXNAMELEN];
     NTSTATUS                status;
 
-    ASSERT(Granter->Connected == FALSE);
+    ASSERT3P(Granter->Cache, ==, NULL);
 
     AdapterGetGnttabInterface(Adapter, &Granter->GnttabInterface);
-    AdapterGetDebugInterface(Adapter, &Granter->DebugInterface);
 
     status = XENBUS_GNTTAB(Acquire, &Granter->GnttabInterface);
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = XENBUS_DEBUG(Acquire, &Granter->DebugInterface);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
     status = RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "disk_%u",
                                 FrontendGetTargetId(Granter->Frontend));
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     status = XENBUS_GNTTAB(CreateCache,
                            &Granter->GnttabInterface,
@@ -205,7 +215,64 @@ GranterConnect(
                            Granter,
                            &Granter->Cache);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail3;
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
+
+fail1:
+    Error("fail1 %08x\n", status);
+
+    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE));
+
+    return status;
+}
+
+static VOID
+__GranterDestroyCache(
+    _Inout_ PXENVBD_GRANTER Granter
+    )
+{
+    ASSERT3S(Granter->Current, ==, 0);
+
+    XENBUS_GNTTAB(DestroyCache,
+                  &Granter->GnttabInterface,
+                  Granter->Cache);
+    Granter->Cache = NULL;
+
+    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
+
+    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE));
+}
+
+NTSTATUS
+GranterConnect(
+    _Inout_ PXENVBD_GRANTER Granter
+    )
+{
+    PXENVBD_ADAPTER         Adapter = 
TargetGetAdapter(FrontendGetTarget(Granter->Frontend));
+    NTSTATUS                status;
+
+    ASSERT(Granter->Connected == FALSE);
+
+    if (Granter->Cache == NULL) {
+        status = __GranterCreateCache(Granter);
+        if (!NT_SUCCESS(status))
+            goto fail1;
+    }
+
+    AdapterGetDebugInterface(Adapter, &Granter->DebugInterface);
+
+    status = XENBUS_DEBUG(Acquire, &Granter->DebugInterface);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
     status = XENBUS_DEBUG(Register,
                           &Granter->DebugInterface,
@@ -214,30 +281,26 @@ GranterConnect(
                           Granter,
                           &Granter->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail3;
 
     Granter->Connected = TRUE;
     return STATUS_SUCCESS;
 
-fail5:
-    Error("fail5\n");
-    XENBUS_GNTTAB(DestroyCache,
-                  &Granter->GnttabInterface,
-                  Granter->Cache);
-    Granter->Cache = NULL;
-fail4:
-    Error("fail4\n");
 fail3:
     Error("fail3\n");
+
     XENBUS_DEBUG(Release, &Granter->DebugInterface);
+
 fail2:
     Error("fail2\n");
-    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
-fail1:
-    Error("fail1 %08x\n", status);
 
     RtlZeroMemory(&Granter->DebugInterface, sizeof(XENBUS_DEBUG_INTERFACE));
-    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE));
+
+    if (Granter->Current == 0)
+        __GranterDestroyCache(Granter);
+
+fail1:
+    Error("fail1 %08x\n", status);
 
     return status;
 }
@@ -281,7 +344,6 @@ GranterDisconnect(
 {
     ASSERT(Granter->Connected == TRUE);
 
-    ASSERT3S(Granter->Current, ==, 0);
     Granter->Maximum = 0;
 
     XENBUS_DEBUG(Deregister,
@@ -289,18 +351,20 @@ GranterDisconnect(
                  Granter->DebugCallback);
     Granter->DebugCallback = NULL;
 
-    XENBUS_GNTTAB(DestroyCache,
-                  &Granter->GnttabInterface,
-                  Granter->Cache);
-    Granter->Cache = NULL;
-
     XENBUS_DEBUG(Release, &Granter->DebugInterface);
-    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
 
     RtlZeroMemory(&Granter->DebugInterface, sizeof(XENBUS_DEBUG_INTERFACE));
-    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFACE));
 
     Granter->Connected = FALSE;
+
+    if (Granter->Current != 0) {
+        Warning("Target[%u] : %ld grants outstanding\n",
+                FrontendGetTargetId(Granter->Frontend),
+                Granter->Current);
+        return;
+    }
+
+    __GranterDestroyCache(Granter);
 }
 
 NTSTATUS
@@ -382,9 +446,6 @@ GranterPut(
 {
     NTSTATUS                status;
 
-    if (Granter->Connected == FALSE)
-        return;
-
     for (;;) {
         status = GranterTryPut(Granter, Handle);
         if (NT_SUCCESS(status))
-- 
2.56.0.windows.3



--
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®.