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

[PATCH 2/3] Get rid of the single contiguous memory hole



From: Paul Durrant <pdurrant@xxxxxxxxxx>

A standard grant table with 64 pages only uses half the allocated 2 MiB of
space and, empirically, getting more than 2 MiB of physically contiguous
memory doesn't seem to work very often.
By changing FdoAllocateHole() and FdoFreeHole() to use an MDL we can do
discrete contiguous allocations on-demand, which is all that is actually
required by callers. It's straightforward to adapt __AllocatePages() for
this purpose by having it pass the MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS
flag to MmAllocatePagesForMdlEx().

NOTE: This means that the generic XENBUS_HOLE becomes XENBUS_PCI_HOLE.
      Also re-work the function naming so FdoAllocateHole() becomes
      FdoHoleAllocate() and other names are similarly restructured. It
      makes the code marginally neater.
      Take the opprtunity to also put zeroing of FrameIndex in the
      XENBUS_GNTTAB Context in the right place in the GnttabAcquire()
      error path, and adjust GnttabRelease() accordingly.

Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx>
---
 src/common/util.h        |  17 +-
 src/xenbus/fdo.c         | 594 +++++++++++++++++----------------------
 src/xenbus/fdo.h         |  17 +-
 src/xenbus/gnttab.c      |  79 +++---
 src/xenbus/shared_info.c |  48 +++-
 5 files changed, 357 insertions(+), 398 deletions(-)

diff --git a/src/common/util.h b/src/common/util.h
index 326ff0b98d9f..b020e5bed096 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -180,28 +180,37 @@ __FreePoolWithTag(
 
 static FORCEINLINE PMDL
 __AllocatePages(
-    IN  ULONG           Count
+    IN  ULONG           Count,
+    IN  BOOLEAN         Contiguous
     )
 {
     PHYSICAL_ADDRESS    LowAddress;
     PHYSICAL_ADDRESS    HighAddress;
     LARGE_INTEGER       SkipBytes;
     SIZE_T              TotalBytes;
+    ULONG               Flags;
     PMDL                Mdl;
     PUCHAR              MdlMappedSystemVa;
     NTSTATUS            status;
 
     LowAddress.QuadPart = 0ull;
     HighAddress.QuadPart = ~0ull;
-    SkipBytes.QuadPart = 0ull;
     TotalBytes = (SIZE_T)PAGE_SIZE * Count;
 
+    if (Contiguous) {
+        SkipBytes.QuadPart = TotalBytes;
+        Flags = MM_ALLOCATE_REQUIRE_CONTIGUOUS_CHUNKS;
+    } else {
+        SkipBytes.QuadPart = 0ull;
+        Flags = MM_ALLOCATE_FULLY_REQUIRED;
+    }
+
     Mdl = MmAllocatePagesForMdlEx(LowAddress,
                                   HighAddress,
                                   SkipBytes,
                                   TotalBytes,
                                   MmCached,
-                                  MM_ALLOCATE_FULLY_REQUIRED);
+                                  Flags);
 
     status = STATUS_NO_MEMORY;
     if (Mdl == NULL)
@@ -245,7 +254,7 @@ fail1:
     return NULL;
 }
 
-#define __AllocatePage()    __AllocatePages(1)
+#define __AllocatePage()    __AllocatePages(1, FALSE)
 
 static FORCEINLINE VOID
 __FreePages(
diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c
index 99a4605f590c..976a7a35b12b 100644
--- a/src/xenbus/fdo.c
+++ b/src/xenbus/fdo.c
@@ -91,12 +91,12 @@ typedef struct _XENBUS_VIRQ {
     ULONG                   Count;
 } XENBUS_VIRQ, *PXENBUS_VIRQ;
 
-typedef struct _XENBUS_HOLE {
-    PXENBUS_RANGE_SET               RangeSet;
-    ULONG                           Count;
-    PVOID                           VirtualAddress;
-    PHYSICAL_ADDRESS                PhysicalAddress;
-} XENBUS_HOLE, *PXENBUS_HOLE;
+typedef struct _XENBUS_PCI_HOLE {
+    PXENBUS_RANGE_SET   RangeSet;
+    ULONG               Count;
+    PVOID               VirtualAddress;
+    PHYSICAL_ADDRESS    PhysicalAddress;
+} XENBUS_PCI_HOLE, *PXENBUS_PCI_HOLE;
 
 struct _XENBUS_FDO {
     PXENBUS_DX                      Dx;
@@ -156,8 +156,8 @@ struct _XENBUS_FDO {
     XENBUS_RANGE_SET_INTERFACE      RangeSetInterface;
     XENBUS_BALLOON_INTERFACE        BalloonInterface;
 
-    PMDL                            Mdl;
-    XENBUS_HOLE                     Hole;
+    ULONG                           UseMemoryHole;
+    XENBUS_PCI_HOLE                 PciHole;
     LIST_ENTRY                      InterruptList;
 
     LIST_ENTRY                      VirqList;
@@ -3218,82 +3218,24 @@ FdoSuspendCallbackLate(
     ASSERT(NT_SUCCESS(status));
 }
 
-static FORCEINLINE NTSTATUS
-__FdoCreateMemoryHole(
-    IN  PXENBUS_FDO Fdo
-    )
-{
-    PXENBUS_HOLE    Hole = &Fdo->Hole;
-    PMDL            Mdl;
-    PFN_NUMBER      Pfn;
-    NTSTATUS        status;
-
-    Mdl = Fdo->Mdl;
-    Hole->VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, 
NormalPagePriority);
-
-    Pfn = MmGetMdlPfnArray(Mdl)[0];
-    Hole->PhysicalAddress.QuadPart = (ULONGLONG)Pfn << PAGE_SHIFT;
-
-    Hole->Count = BYTES_TO_PAGES(Mdl->ByteCount);
-    ASSERT3U(Hole->Count, ==, 1u << PAGE_ORDER_2M);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (MemoryDecreaseReservation(PAGE_ORDER_2M, 1, &Pfn) != 1)
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Hole->Count = 0;
-    Hole->PhysicalAddress.QuadPart = 0;
-    Hole->VirtualAddress = NULL;
-
-    return status;
-}
-
-static FORCEINLINE VOID
-__FdoDestroyMemoryHole(
-    IN  PXENBUS_FDO Fdo
-    )
-{
-    PXENBUS_HOLE    Hole = &Fdo->Hole;
-    PMDL            Mdl;
-    PFN_NUMBER      Pfn;
-    ULONG           Index;
-
-    Mdl = Fdo->Mdl;
-    Pfn = MmGetMdlPfnArray(Mdl)[0];
-
-    ASSERT3U(Hole->Count, ==, 1u << PAGE_ORDER_2M);
-    if (MemoryPopulatePhysmap(PAGE_ORDER_2M, 1, &Pfn) == 1)
-        goto done;
-
-    for (Index = 0; Index < Hole->Count; Index++) {
-        if (MemoryPopulatePhysmap(PAGE_ORDER_4K, 1, &Pfn) != 1)
-            BUG("FAILED TO RE-POPULATE HOLE");
-
-        Pfn++;
-    }
-
-done:
-    Hole->Count = 0;
-    Hole->PhysicalAddress.QuadPart = 0;
-    Hole->VirtualAddress = NULL;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoCreatePciHole(
+static NTSTATUS
+FdoPciHoleCreate(
     IN  PXENBUS_FDO                 Fdo
     )
 {
-    PXENBUS_HOLE                    Hole = &Fdo->Hole;
+    PXENBUS_PCI_HOLE                Hole = &Fdo->PciHole;
     ULONG                           Index;
     PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated;
-    SIZE_T                          Size;
+    PFN_NUMBER                      Pfn;
     NTSTATUS                        status;
 
+    status = XENBUS_RANGE_SET(Create,
+                              &Fdo->RangeSetInterface,
+                              "PCI",
+                              &Hole->RangeSet);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     for (Index = 0; Index < Fdo->TranslatedResourceList->Count; Index++) {
         Translated = &Fdo->TranslatedResourceList->PartialDescriptors[Index];
 
@@ -3302,125 +3244,106 @@ __FdoCreatePciHole(
     }
 
     status = STATUS_OBJECT_NAME_NOT_FOUND;
-    goto fail1;
+    goto fail2;
 
 found:
-    Hole->PhysicalAddress = Translated->u.Memory.Start;
-    Size = Translated->u.Memory.Length;
-    Hole->Count = (ULONG)(Size >> PAGE_SHIFT);
-
-    Hole->VirtualAddress = MmMapIoSpace(Hole->PhysicalAddress,
-                                        Size,
+    Hole->VirtualAddress = MmMapIoSpace(Translated->u.Memory.Start,
+                                        Translated->u.Memory.Length,
                                         MmCached);
 
     status = STATUS_UNSUCCESSFUL;
     if (Hole->VirtualAddress == NULL)
-        goto fail2;
+        goto fail3;
+
+    Hole->PhysicalAddress = Translated->u.Memory.Start;
+    Hole->Count = (ULONG)(Translated->u.Memory.Length >> PAGE_SHIFT);
+
+    status = XENBUS_RANGE_SET(Put,
+                              &Fdo->RangeSetInterface,
+                              Hole->RangeSet,
+                              0,
+                              Hole->Count);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    Pfn = (PFN_NUMBER)(Hole->PhysicalAddress.QuadPart >> PAGE_SHIFT);
+    Info("%08x - %08x\n",
+         Pfn,
+         Pfn + Hole->Count - 1);
 
     return STATUS_SUCCESS;
 
-fail2:
-    Error("fail2\n");
+fail4:
+    Error("fail4\n");
+
+    MmUnmapIoSpace(Hole->VirtualAddress, Hole->Count << PAGE_SHIFT);
 
     Hole->VirtualAddress = NULL;
     Hole->Count = 0;
     Hole->PhysicalAddress.QuadPart = 0;
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+fail3:
+    Error("fail3\n");
 
-    return status;
-}
+fail2:
+    Error("fail2\n");
 
-static FORCEINLINE VOID
-__FdoDestroyPciHole(
-    IN  PXENBUS_FDO Fdo
-    )
-{
-    PXENBUS_HOLE    Hole = &Fdo->Hole;
-    SIZE_T          Size;
+    XENBUS_RANGE_SET(Destroy,
+                     &Fdo->RangeSetInterface,
+                     Hole->RangeSet);
+    Hole->RangeSet = NULL;
 
-    Size = (ULONGLONG)Hole->Count << PAGE_SHIFT;
-    MmUnmapIoSpace(Hole->VirtualAddress, Size);
+fail1:
+    Error("fail1 (%08x)\n", status);
 
-    Hole->VirtualAddress = NULL;
-    Hole->Count = 0;
-    Hole->PhysicalAddress.QuadPart = 0;
+    return status;
 }
 
-static NTSTATUS
-FdoCreateHole(
+static VOID
+FdoPciHoleDestroy(
     IN  PXENBUS_FDO     Fdo
     )
 {
-    PXENBUS_HOLE        Hole = &Fdo->Hole;
-    PFN_NUMBER          Pfn;
+    PXENBUS_PCI_HOLE    Hole = &Fdo->PciHole;
     NTSTATUS            status;
 
-    status = XENBUS_RANGE_SET(Create,
-                              &Fdo->RangeSetInterface,
-                              "hole",
-                              &Hole->RangeSet);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = (Fdo->Mdl != NULL) ?
-             __FdoCreateMemoryHole(Fdo) :
-             __FdoCreatePciHole(Fdo);
-
-    if (!NT_SUCCESS(status))
-        goto fail2;
+    BUG_ON(Hole->Count == 0);
 
-    status = XENBUS_RANGE_SET(Put,
+    status = XENBUS_RANGE_SET(Get,
                               &Fdo->RangeSetInterface,
                               Hole->RangeSet,
                               0,
                               Hole->Count);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Pfn = (PFN_NUMBER)(Hole->PhysicalAddress.QuadPart >> PAGE_SHIFT);
-    Info("(%s) %08x - %08x\n",
-         (Fdo->Mdl != NULL) ? "MEMORY" : "PCI",
-         Pfn,
-         Pfn + Hole->Count - 1);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
+    ASSERT(NT_SUCCESS(status));
 
-    if (Fdo->Mdl != NULL)
-        __FdoDestroyMemoryHole(Fdo);
-    else
-        __FdoDestroyPciHole(Fdo);
+    MmUnmapIoSpace(Hole->VirtualAddress, Hole->Count << PAGE_SHIFT);
 
-fail2:
-    Error("fail2\n");
+    Hole->VirtualAddress = NULL;
+    Hole->Count = 0;
+    Hole->PhysicalAddress.QuadPart = 0;
 
     XENBUS_RANGE_SET(Destroy,
                      &Fdo->RangeSetInterface,
                      Hole->RangeSet);
     Hole->RangeSet = NULL;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
 }
 
-NTSTATUS
-FdoAllocateHole(
+static PMDL
+FdoPciHoleAllocate(
     IN  PXENBUS_FDO         Fdo,
-    IN  ULONG               Count,
-    OUT PVOID               *VirtualAddress OPTIONAL,
-    OUT PPHYSICAL_ADDRESS   PhysicalAddress
+    IN  ULONG               Count
     )
 {
-    PXENBUS_HOLE            Hole = &Fdo->Hole;
+    PXENBUS_PCI_HOLE        Hole = &Fdo->PciHole;
     LONGLONG                Index;
+    PVOID                   VirtualAddress;
+    PHYSICAL_ADDRESS        PhysicalAddress;
+    PMDL                    Mdl;
+    PPFN_NUMBER             PfnArray;
     NTSTATUS                status;
 
+    BUG_ON(Hole->Count == 0);
+
     status = XENBUS_RANGE_SET(Pop,
                               &Fdo->RangeSetInterface,
                               Hole->RangeSet,
@@ -3429,35 +3352,76 @@ FdoAllocateHole(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    if (VirtualAddress != NULL)
-        *VirtualAddress = (PUCHAR)Hole->VirtualAddress +
-                          (Index << PAGE_SHIFT);
+    VirtualAddress = (PUCHAR)Hole->VirtualAddress + (Index << PAGE_SHIFT);
 
-    PhysicalAddress->QuadPart = Hole->PhysicalAddress.QuadPart +
-                                (Index << PAGE_SHIFT);
+    Mdl = IoAllocateMdl(VirtualAddress,
+                        Count << PAGE_SHIFT,
+                        FALSE,
+                        FALSE,
+                        NULL);
 
-    return STATUS_SUCCESS;;
+    status = STATUS_NO_MEMORY;
+    if (Mdl == NULL)
+        goto fail2;
+
+    ASSERT3P(Mdl->StartVa, ==, VirtualAddress);
+    ASSERT3U(Mdl->ByteCount, ==, Count << PAGE_SHIFT);
+
+    PhysicalAddress.QuadPart = Hole->PhysicalAddress.QuadPart + (Index << 
PAGE_SHIFT);
+
+    PfnArray = MmGetMdlPfnArray(Mdl);
+    PfnArray[0] = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT);
+
+    for (Index = 0; Index < (LONGLONG)Count; Index++)
+        PfnArray[Index] = PfnArray[0] + (ULONG)Index;
+
+    return Mdl;
+
+fail2:
+    Error("fail2\n");
+
+    (VOID) XENBUS_RANGE_SET(Put,
+                            &Fdo->RangeSetInterface,
+                            Hole->RangeSet,
+                            Index,
+                            Count);
 
 fail1:
     Error("fail1 (%08x)\n", status);
 
-    return status;
+    return NULL;
 }
 
-VOID
-FdoFreeHole(
-    IN  PXENBUS_FDO         Fdo,
-    IN  PHYSICAL_ADDRESS    PhysicalAddress,
-    IN  ULONG               Count
+static VOID
+FdoPciHoleFree(
+    IN  PXENBUS_FDO     Fdo,
+    IN  PMDL            Mdl
     )
 {
-    PXENBUS_HOLE            Hole = &Fdo->Hole;
-    LONGLONG                Index;
-    NTSTATUS                status;
+    PXENBUS_PCI_HOLE    Hole = &Fdo->PciHole;
+    ULONG               Count;
+    PPFN_NUMBER         PfnArray;
+    LONGLONG            Index;
+    PHYSICAL_ADDRESS    PhysicalAddress;
+    NTSTATUS            status;
 
-    Index = PhysicalAddress.QuadPart - Hole->PhysicalAddress.QuadPart;
-    ASSERT3U(Index & (PAGE_SIZE - 1), ==, 0);
-    Index >>= PAGE_SHIFT;
+    BUG_ON(Hole->Count == 0);
+
+    Count = Mdl->ByteCount >> PAGE_SHIFT;
+    ASSERT3U(Count, <, Hole->Count);
+
+    PfnArray = MmGetMdlPfnArray(Mdl);
+
+    // Verify that the PFNs are contiguous
+    for (Index = 0; Index < (LONGLONG)Count; Index++)
+        BUG_ON(PfnArray[Index] != PfnArray[0] + Index);
+
+    PhysicalAddress.QuadPart = PfnArray[0] << PAGE_SHIFT;
+
+    Index = (PhysicalAddress.QuadPart - Hole->PhysicalAddress.QuadPart) >> 
PAGE_SHIFT;
+
+    ASSERT3U(Index, <, Hole->Count);
+    ASSERT3U(Index + Count, <=, Hole->Count);
 
     status = XENBUS_RANGE_SET(Put,
                               &Fdo->RangeSetInterface,
@@ -3465,34 +3429,91 @@ FdoFreeHole(
                               Index,
                               Count);
     ASSERT(NT_SUCCESS(status));
+
+    ExFreePool(Mdl);
+}
+
+static PMDL
+FdoMemoryHoleAllocate(
+    IN  PXENBUS_FDO     Fdo,
+    IN  ULONG           Count
+    )
+{
+    PMDL                Mdl;
+    PPFN_NUMBER         PfnArray;
+    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(Fdo);
+
+    Mdl = __AllocatePages(Count, TRUE);
+
+    status = STATUS_NO_MEMORY;
+    if (Mdl == NULL)
+        goto fail1;
+
+    PfnArray = MmGetMdlPfnArray(Mdl);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (MemoryDecreaseReservation(PAGE_ORDER_4K, Count, PfnArray) != Count)
+        goto fail2;
+
+    return Mdl;
+
+fail2:
+    Error("fail2\n");
+
+    __FreePages(Mdl);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
 }
 
 static VOID
-FdoDestroyHole(
-    IN  PXENBUS_FDO Fdo
+FdoMemoryHoleFree(
+    IN  PXENBUS_FDO     Fdo,
+    IN  PMDL            Mdl
     )
 {
-    PXENBUS_HOLE    Hole = &Fdo->Hole;
-    NTSTATUS        status;
+    ULONG               Count;
+    PPFN_NUMBER         PfnArray;
 
-    status = XENBUS_RANGE_SET(Get,
-                              &Fdo->RangeSetInterface,
-                              Hole->RangeSet,
-                              0,
-                              Hole->Count);
-    ASSERT(NT_SUCCESS(status));
+    UNREFERENCED_PARAMETER(Fdo);
 
-    if (Fdo->Mdl != NULL)
-        __FdoDestroyMemoryHole(Fdo);
-    else
-        __FdoDestroyPciHole(Fdo);
+    Count = Mdl->ByteCount >> PAGE_SHIFT;
+    PfnArray = MmGetMdlPfnArray(Mdl);
 
-    XENBUS_RANGE_SET(Destroy,
-                     &Fdo->RangeSetInterface,
-                     Hole->RangeSet);
-    Hole->RangeSet = NULL;
+    if (MemoryPopulatePhysmap(PAGE_ORDER_4K, Count, PfnArray) != Count)
+        BUG("FAILED TO RE-POPULATE HOLE");
+
+    __FreePages(Mdl);
 }
 
+PMDL
+FdoHoleAllocate(
+    IN  PXENBUS_FDO Fdo,
+    IN  ULONG       Count
+    )
+{
+    return (Fdo->UseMemoryHole != 0) ?
+        FdoMemoryHoleAllocate(Fdo, Count) :
+        FdoPciHoleAllocate(Fdo, Count);
+}
+
+VOID
+FdoHoleFree(
+    IN  PXENBUS_FDO Fdo,
+    IN  PMDL        Mdl
+    )
+{
+    if (Fdo->UseMemoryHole != 0)
+        FdoMemoryHoleFree(Fdo, Mdl);
+    else
+        FdoPciHoleFree(Fdo, Mdl);
+}
+
+
 static VOID
 FdoDebugCallback(
     IN  PVOID   Argument,
@@ -3566,10 +3587,11 @@ FdoD3ToD0(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    // Subsequent interfaces require use of BAR space
-    status = FdoCreateHole(Fdo);
-    if (!NT_SUCCESS(status))
-        goto fail4;
+    if (Fdo->UseMemoryHole == 0) {
+        status = FdoPciHoleCreate(Fdo);
+        if (!NT_SUCCESS(status))
+            goto fail4;
+    }
 
     status = XENBUS_EVTCHN(Acquire, &Fdo->EvtchnInterface);
     if (!NT_SUCCESS(status))
@@ -3677,7 +3699,8 @@ fail6:
 fail5:
     Error("fail5\n");
 
-    FdoDestroyHole(Fdo);
+    if (Fdo->UseMemoryHole == 0)
+        FdoPciHoleDestroy(Fdo);
 
 fail4:
     Error("fail4\n");
@@ -3800,7 +3823,8 @@ FdoD0ToD3(
 
     XENBUS_EVTCHN(Release, &Fdo->EvtchnInterface);
 
-    FdoDestroyHole(Fdo);
+    if (Fdo->UseMemoryHole == 0)
+        FdoPciHoleDestroy(Fdo);
 
     XENBUS_RANGE_SET(Release, &Fdo->RangeSetInterface);
 
@@ -5605,107 +5629,6 @@ fail1:
                       (_Size),                                                 
         \
                       (_Optional))
 
-
-#define FDO_HOLE_SIZE   (2ull << 20)
-
-static FORCEINLINE NTSTATUS
-__FdoAllocateBuffer(
-    IN  PXENBUS_FDO     Fdo
-    )
-{
-    HANDLE              ParametersKey;
-    ULONG               UseMemoryHole;
-    ULONG               Count;
-    ULONG               Size;
-    PHYSICAL_ADDRESS    Low;
-    PHYSICAL_ADDRESS    High;
-    PHYSICAL_ADDRESS    Align;
-    PVOID               Buffer;
-    PMDL                Mdl;
-    NTSTATUS            status;
-
-    ParametersKey = DriverGetParametersKey();
-
-    status = RegistryQueryDwordValue(ParametersKey,
-                                     "UseMemoryHole",
-                                     &UseMemoryHole);
-    if (!NT_SUCCESS(status))
-        UseMemoryHole = 1;
-
-    ASSERT(Fdo->Mdl == NULL);
-    if (UseMemoryHole == 0)
-        goto done;
-
-    Count = 1u << PAGE_ORDER_2M;
-    Size = Count << PAGE_SHIFT;
-
-    Low.QuadPart = 0;
-    High = SystemMaximumPhysicalAddress();
-    Align.QuadPart = Size;
-
-    Buffer = MmAllocateContiguousNodeMemory((SIZE_T)Size,
-                                            Low,
-                                            High,
-                                            Align,
-                                            PAGE_READWRITE,
-                                            MM_ANY_NODE_OK);
-
-    status = STATUS_NO_MEMORY;
-    if (Buffer == NULL)
-        goto fail1;
-
-    Mdl = IoAllocateMdl(Buffer,
-                        Size,
-                        FALSE,
-                        FALSE,
-                        NULL);
-
-    status = STATUS_NO_MEMORY;
-    if (Mdl == NULL)
-        goto fail2;
-
-    MmBuildMdlForNonPagedPool(Mdl);
-
-    ASSERT3U(Mdl->ByteOffset, ==, 0);
-    ASSERT3U(Mdl->ByteCount, ==, Size);
-
-    Fdo->Mdl = Mdl;
-
-done:
-    return STATUS_SUCCESS;
-
-fail2:
-    Error("fail2\n");
-
-    MmFreeContiguousMemory(Buffer);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-static FORCEINLINE VOID
-__FdoFreeBuffer(
-    IN  PXENBUS_FDO Fdo
-    )
-{
-    PMDL            Mdl;
-    PVOID           Buffer;
-
-    Mdl = Fdo->Mdl;
-    if (Mdl == NULL)
-        return;
-
-    Fdo->Mdl = NULL;
-
-    Buffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
-
-    ExFreePool(Mdl);
-
-    MmFreeContiguousMemory(Buffer);
-}
-
 static NTSTATUS
 FdoBalloonInitialize(
     IN  PXENBUS_FDO Fdo
@@ -5790,6 +5713,8 @@ FdoCreate(
     PXENBUS_DX                  Dx;
     PXENBUS_FDO                 Fdo;
     PCI_COMMON_HEADER           Header;
+    HANDLE                      ParametersKey;
+    ULONG                       UseMemoryHole;
     NTSTATUS                    status;
 
 #pragma prefast(suppress:28197) // Possibly leaking memory 
'FunctionDeviceObject'
@@ -5857,53 +5782,59 @@ FdoCreate(
     if (!__FdoIsActive(Fdo))
         goto done;
 
-    status = __FdoAllocateBuffer(Fdo);
+    ParametersKey = DriverGetParametersKey();
+
+    status = RegistryQueryDwordValue(ParametersKey,
+                                     "UseMemoryHole",
+                                     &UseMemoryHole);
     if (!NT_SUCCESS(status))
-        goto fail9;
+        UseMemoryHole = 1;
+
+    Fdo->UseMemoryHole = UseMemoryHole;
 
     status = DebugInitialize(Fdo, &Fdo->DebugContext);
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail9;
 
     status = SuspendInitialize(Fdo, &Fdo->SuspendContext);
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail10;
 
     status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext);
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail11;
 
     status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext);
     if (!NT_SUCCESS(status))
-        goto fail13;
+        goto fail12;
 
     status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext);
     if (!NT_SUCCESS(status))
-        goto fail14;
+        goto fail13;
 
     status = CacheInitialize(Fdo, &Fdo->CacheContext);
     if (!NT_SUCCESS(status))
-        goto fail15;
+        goto fail14;
 
     status = GnttabInitialize(Fdo, &Fdo->GnttabContext);
     if (!NT_SUCCESS(status))
-        goto fail16;
+        goto fail15;
 
     status = StoreInitialize(Fdo, &Fdo->StoreContext);
     if (!NT_SUCCESS(status))
-        goto fail17;
+        goto fail16;
 
     status = ConsoleInitialize(Fdo, &Fdo->ConsoleContext);
     if (!NT_SUCCESS(status))
-        goto fail18;
+        goto fail17;
 
     status = UnplugInitialize(Fdo, &Fdo->UnplugContext);
     if (!NT_SUCCESS(status))
-        goto fail19;
+        goto fail18;
 
     status = FdoBalloonInitialize(Fdo);
     if (!NT_SUCCESS(status))
-        goto fail20;
+        goto fail19;
 
     status = DebugGetInterface(__FdoGetDebugContext(Fdo),
                                XENBUS_DEBUG_INTERFACE_VERSION_MAX,
@@ -5974,74 +5905,71 @@ done:
 
     return STATUS_SUCCESS;
 
-fail20:
-    Error("fail20\n");
-
-    UnplugTeardown(Fdo->UnplugContext);
-    Fdo->UnplugContext = NULL;
-
 fail19:
     Error("fail19\n");
 
-    ConsoleTeardown(Fdo->ConsoleContext);
-    Fdo->ConsoleContext = NULL;
+    UnplugTeardown(Fdo->UnplugContext);
+    Fdo->UnplugContext = NULL;
 
 fail18:
     Error("fail18\n");
 
-    StoreTeardown(Fdo->StoreContext);
-    Fdo->StoreContext = NULL;
+    ConsoleTeardown(Fdo->ConsoleContext);
+    Fdo->ConsoleContext = NULL;
 
 fail17:
     Error("fail17\n");
 
-    GnttabTeardown(Fdo->GnttabContext);
-    Fdo->GnttabContext = NULL;
+    StoreTeardown(Fdo->StoreContext);
+    Fdo->StoreContext = NULL;
 
 fail16:
     Error("fail16\n");
 
-    CacheTeardown(Fdo->CacheContext);
-    Fdo->CacheContext = NULL;
+    GnttabTeardown(Fdo->GnttabContext);
+    Fdo->GnttabContext = NULL;
 
 fail15:
     Error("fail15\n");
 
-    RangeSetTeardown(Fdo->RangeSetContext);
-    Fdo->RangeSetContext = NULL;
+    CacheTeardown(Fdo->CacheContext);
+    Fdo->CacheContext = NULL;
 
 fail14:
     Error("fail14\n");
 
-    EvtchnTeardown(Fdo->EvtchnContext);
-    Fdo->EvtchnContext = NULL;
+    RangeSetTeardown(Fdo->RangeSetContext);
+    Fdo->RangeSetContext = NULL;
 
 fail13:
     Error("fail13\n");
 
-    SharedInfoTeardown(Fdo->SharedInfoContext);
-    Fdo->SharedInfoContext = NULL;
+    EvtchnTeardown(Fdo->EvtchnContext);
+    Fdo->EvtchnContext = NULL;
 
 fail12:
     Error("fail12\n");
 
-    SuspendTeardown(Fdo->SuspendContext);
-    Fdo->SuspendContext = NULL;
+    SharedInfoTeardown(Fdo->SharedInfoContext);
+    Fdo->SharedInfoContext = NULL;
 
 fail11:
     Error("fail11\n");
 
-    DebugTeardown(Fdo->DebugContext);
-    Fdo->DebugContext = NULL;
+    SuspendTeardown(Fdo->SuspendContext);
+    Fdo->SuspendContext = NULL;
 
 fail10:
     Error("fail10\n");
 
-    __FdoFreeBuffer(Fdo);
+    DebugTeardown(Fdo->DebugContext);
+    Fdo->DebugContext = NULL;
 
 fail9:
     Error("fail9\n");
 
+    Fdo->UseMemoryHole = 0;
+
     //
     // We don't want to call DriverClearActive() so just
     // clear the FDO flag.
@@ -6180,7 +6108,7 @@ FdoDestroy(
         DebugTeardown(Fdo->DebugContext);
         Fdo->DebugContext = NULL;
 
-        __FdoFreeBuffer(Fdo);
+        Fdo->UseMemoryHole = 0;
 
         FdoClearActive(Fdo);
     }
diff --git a/src/xenbus/fdo.h b/src/xenbus/fdo.h
index a58526ab5bb2..f2ec88c637ca 100644
--- a/src/xenbus/fdo.h
+++ b/src/xenbus/fdo.h
@@ -132,19 +132,16 @@ FdoGetName(
     IN  PXENBUS_FDO Fdo
     );
 
-extern NTSTATUS
-FdoAllocateHole(
-    IN  PXENBUS_FDO         Fdo,
-    IN  ULONG               Count,
-    OUT PVOID               *VirtualAddress OPTIONAL,
-    OUT PPHYSICAL_ADDRESS   PhysicalAddress
+extern PMDL
+FdoHoleAllocate(
+    IN  PXENBUS_FDO Fdo,
+    IN  ULONG       Count
     );
 
 extern VOID
-FdoFreeHole(
-    IN  PXENBUS_FDO         Fdo,
-    IN  PHYSICAL_ADDRESS    PhysicalAddress,
-    IN  ULONG               Count
+FdoHoleFree(
+    IN  PXENBUS_FDO Fdo,
+    IN  PMDL        Mdl
     );
 
 // Disable erroneous SAL warnings around use of interrupt locks
diff --git a/src/xenbus/gnttab.c b/src/xenbus/gnttab.c
index af562608b40d..5929270a7793 100644
--- a/src/xenbus/gnttab.c
+++ b/src/xenbus/gnttab.c
@@ -70,7 +70,7 @@ struct _XENBUS_GNTTAB_ENTRY {
 };
 
 typedef struct _XENBUS_GNTTAB_MAP_ENTRY {
-    ULONG   NumberPages;
+    PMDL    Mdl;
     ULONG   MapHandles[1];
 } XENBUS_GNTTAB_MAP_ENTRY, *PXENBUS_GNTTAB_MAP_ENTRY;
 
@@ -79,7 +79,7 @@ struct _XENBUS_GNTTAB_CONTEXT {
     KSPIN_LOCK                  Lock;
     LONG                        References;
     ULONG                       MaximumFrameCount;
-    PHYSICAL_ADDRESS            Address;
+    PMDL                        Mdl;
     LONG                        FrameIndex;
     grant_entry_v1_t            *Table;
     XENBUS_RANGE_SET_INTERFACE  RangeSetInterface;
@@ -129,7 +129,7 @@ GnttabExpand(
     if (Index == Context->MaximumFrameCount)
         goto fail1;
 
-    Address = Context->Address;
+    Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
     Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT;
 
     status = MemoryAddToPhysmap((PFN_NUMBER)(Address.QuadPart >> PAGE_SHIFT),
@@ -187,7 +187,7 @@ GnttabMap(
     for (Index = 0; Index <= Context->FrameIndex; Index++) {
         PHYSICAL_ADDRESS    Address;
 
-        Address = Context->Address;
+        Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
         Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT;
 
         status = MemoryAddToPhysmap((PFN_NUMBER)(Address.QuadPart >> 
PAGE_SHIFT),
@@ -213,7 +213,7 @@ GnttabUnmap(
     for (Index = Context->FrameIndex; Index >= 0; --Index) {
         PHYSICAL_ADDRESS    Address;
 
-        Address = Context->Address;
+        Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
         Address.QuadPart += (ULONGLONG)Index << PAGE_SHIFT;
 
         (VOID) MemoryRemoveFromPhysmap((PFN_NUMBER)(Address.QuadPart >> 
PAGE_SHIFT));
@@ -615,16 +615,16 @@ GnttabMapForeignPages(
     )
 {
     PXENBUS_GNTTAB_CONTEXT      Context = Interface->Context;
+    PMDL                        Mdl;
     LONG                        PageIndex;
     PHYSICAL_ADDRESS            PageAddress;
     PXENBUS_GNTTAB_MAP_ENTRY    MapEntry;
     NTSTATUS                    status;
 
-    status = FdoAllocateHole(Context->Fdo,
-                             NumberPages,
-                             NULL,
-                             Address);
-    if (!NT_SUCCESS(status))
+    Mdl = FdoHoleAllocate(Context->Fdo, NumberPages);
+
+    status = STATUS_NO_MEMORY;
+    if (Mdl == NULL)
         goto fail1;
 
     MapEntry = __GnttabAllocate(FIELD_OFFSET(XENBUS_GNTTAB_MAP_ENTRY,
@@ -635,8 +635,10 @@ GnttabMapForeignPages(
     if (MapEntry == NULL)
         goto fail2;
 
+    MapEntry->Mdl = Mdl;
+
+    Address->QuadPart = MmGetMdlPfnArray(Mdl)[0] << PAGE_SHIFT;
     PageAddress.QuadPart = Address->QuadPart;
-    MapEntry->NumberPages = NumberPages;
 
     for (PageIndex = 0; PageIndex < (LONG)NumberPages; PageIndex++) {
         status = GrantTableMapForeignPage(Domain,
@@ -670,12 +672,14 @@ fail3:
                                           PageAddress);
     }
 
+    Address->QuadPart = 0;
+
     __GnttabFree(MapEntry);
 
 fail2:
     Error("fail2\n");
 
-    FdoFreeHole(Context->Fdo, *Address, NumberPages);
+    FdoHoleFree(Context->Fdo, Mdl);
 
 fail1:
     Error("fail1: (%08x)\n", status);
@@ -690,9 +694,11 @@ GnttabUnmapForeignPages(
     )
 {
     PXENBUS_GNTTAB_CONTEXT      Context = Interface->Context;
-    ULONG                       PageIndex;
+    ULONG                       NumberPages;
     PHYSICAL_ADDRESS            PageAddress;
+    ULONG                       PageIndex;
     PXENBUS_GNTTAB_MAP_ENTRY    MapEntry;
+    PMDL                        Mdl;
     NTSTATUS                    status;
 
     status = HashTableLookup(Context->MapTable,
@@ -708,7 +714,10 @@ GnttabUnmapForeignPages(
 
     PageAddress.QuadPart = Address.QuadPart;
 
-    for (PageIndex = 0; PageIndex < MapEntry->NumberPages; PageIndex++) {
+    Mdl = MapEntry->Mdl;
+    NumberPages = Mdl->ByteCount >> PAGE_SHIFT;
+
+    for (PageIndex = 0; PageIndex < NumberPages; PageIndex++) {
         status = GrantTableUnmapForeignPage(MapEntry->MapHandles[PageIndex],
                                             PageAddress);
         BUG_ON(!NT_SUCCESS(status));
@@ -716,12 +725,10 @@ GnttabUnmapForeignPages(
         PageAddress.QuadPart += PAGE_SIZE;
     }
 
-    FdoFreeHole(Context->Fdo,
-                Address,
-                MapEntry->NumberPages);
-
     __GnttabFree(MapEntry);
 
+    FdoHoleFree(Context->Fdo, Mdl);
+
     return STATUS_SUCCESS;
 
 fail2:
@@ -750,14 +757,17 @@ GnttabDebugCallback(
     )
 {
     PXENBUS_GNTTAB_CONTEXT  Context = Argument;
+    PHYSICAL_ADDRESS        Address;
 
     UNREFERENCED_PARAMETER(Crashing);
 
+    Address.QuadPart = MmGetMdlPfnArray(Context->Mdl)[0] << PAGE_SHIFT;
+
     XENBUS_DEBUG(Printf,
                  &Context->DebugInterface,
                  "Address = %08x.%08x\n",
-                 Context->Address.HighPart,
-                 Context->Address.LowPart);
+                 Address.HighPart,
+                 Address.LowPart);
     
     XENBUS_DEBUG(Printf,
                  &Context->DebugInterface,
@@ -790,13 +800,13 @@ GnttabAcquire(
               "GNTTAB: MAX FRAMES = %u\n",
               Context->MaximumFrameCount);
 
-    status = FdoAllocateHole(Fdo,
-                             Context->MaximumFrameCount,
-                             &Context->Table,
-                             &Context->Address);
-    if (!NT_SUCCESS(status))
+    Context->Mdl = FdoHoleAllocate(Fdo, Context->MaximumFrameCount);
+
+    status = STATUS_NO_MEMORY;
+    if (Context->Mdl == NULL)
         goto fail2;
 
+    Context->Table = Context->Mdl->StartVa;
     Context->FrameIndex = -1;
 
     status = XENBUS_RANGE_SET(Acquire, &Context->RangeSetInterface);
@@ -894,7 +904,6 @@ fail5:
                      Context->RangeSet);
     Context->RangeSet = NULL;
 
-    Context->FrameIndex = 0;
 
 fail4:
     Error("fail4\n");
@@ -904,12 +913,12 @@ fail4:
 fail3:
     Error("fail3\n");
 
-    FdoFreeHole(Fdo,
-                Context->Address,
-                Context->MaximumFrameCount);
-    Context->Address.QuadPart = 0;
+    Context->FrameIndex = 0;
     Context->Table = NULL;
 
+    FdoHoleFree(Fdo, Context->Mdl);
+    Context->Mdl = NULL;
+
 fail2:
     Error("fail2\n");
 
@@ -968,16 +977,14 @@ GnttabRelease(
                      Context->RangeSet);
     Context->RangeSet = NULL;
 
-    Context->FrameIndex = 0;
-
     XENBUS_RANGE_SET(Release, &Context->RangeSetInterface);
 
-    FdoFreeHole(Fdo,
-                Context->Address,
-                Context->MaximumFrameCount);
-    Context->Address.QuadPart = 0;
+    Context->FrameIndex = 0;
     Context->Table = NULL;
 
+    FdoHoleFree(Fdo, Context->Mdl);
+    Context->Mdl = NULL;
+
     Context->MaximumFrameCount = 0;
 
     Trace("<====\n");
diff --git a/src/xenbus/shared_info.c b/src/xenbus/shared_info.c
index f25e12a1c689..dc456ebcbf83 100644
--- a/src/xenbus/shared_info.c
+++ b/src/xenbus/shared_info.c
@@ -53,7 +53,7 @@ struct _XENBUS_SHARED_INFO_CONTEXT {
     PXENBUS_FDO                     Fdo;
     KSPIN_LOCK                      Lock;
     LONG                            References;
-    PHYSICAL_ADDRESS                Address;
+    PMDL                            Mdl;
     shared_info_t                   *Shared;
     PXENBUS_SHARED_INFO_PROCESSOR   Processor;
     ULONG                           ProcessorCount;
@@ -459,17 +459,21 @@ SharedInfoMap(
     IN  PXENBUS_SHARED_INFO_CONTEXT Context
     )
 {
+    PFN_NUMBER                      Pfn;
+    PHYSICAL_ADDRESS                Address;
     NTSTATUS                        status;
 
-    status = MemoryAddToPhysmap((PFN_NUMBER)(Context->Address.QuadPart >> 
PAGE_SHIFT),
-                                XENMAPSPACE_shared_info,
-                                0);
+    Pfn = MmGetMdlPfnArray(Context->Mdl)[0];
+
+    status = MemoryAddToPhysmap(Pfn, XENMAPSPACE_shared_info, 0);
     ASSERT(NT_SUCCESS(status));
 
+    Address.QuadPart = Pfn << PAGE_SHIFT;
+
     LogPrintf(LOG_LEVEL_INFO,
               "SHARED_INFO: MAP XENMAPSPACE_shared_info @ %08x.%08x\n",
-              Context->Address.HighPart,
-              Context->Address.LowPart);
+              Address.HighPart,
+              Address.LowPart);
 }
 
 static VOID
@@ -477,11 +481,14 @@ SharedInfoUnmap(
     IN  PXENBUS_SHARED_INFO_CONTEXT Context
     )
 {
+    PFN_NUMBER                      Pfn;
+
     LogPrintf(LOG_LEVEL_INFO,
               "SHARED_INFO: UNMAP XENMAPSPACE_shared_info\n");
 
+    Pfn = MmGetMdlPfnArray(Context->Mdl)[0];
 
-    (VOID) MemoryRemoveFromPhysmap((PFN_NUMBER)(Context->Address.QuadPart >> 
PAGE_SHIFT));
+    (VOID) MemoryRemoveFromPhysmap(Pfn);
 }
 
 static VOID
@@ -502,12 +509,17 @@ SharedInfoDebugCallback(
     )
 {
     PXENBUS_SHARED_INFO_CONTEXT Context = Argument;
+    PFN_NUMBER                  Pfn;
+    PHYSICAL_ADDRESS            Address;
+
+    Pfn = MmGetMdlPfnArray(Context->Mdl)[0];
+    Address.QuadPart = Pfn << PAGE_SHIFT;
 
     XENBUS_DEBUG(Printf,
                  &Context->DebugInterface,
                  "Address = %08x.%08x\n",
-                 Context->Address.HighPart,
-                 Context->Address.LowPart);
+                 Address.HighPart,
+                 Address.LowPart);
 
     if (!Crashing) {
         shared_info_t   *Shared;
@@ -593,10 +605,14 @@ SharedInfoAcquire(
 
     Trace("====>\n");
 
-    status = FdoAllocateHole(Fdo, 1, &Context->Shared, &Context->Address);
-    if (!NT_SUCCESS(status))
+    Context->Mdl = FdoHoleAllocate(Fdo, 1);
+
+    status = STATUS_NO_MEMORY;
+    if (Context->Mdl == NULL)
         goto fail1;
 
+    Context->Shared = Context->Mdl->StartVa;
+
     SharedInfoMap(Context);
     SharedInfoEvtchnMaskAll(Context);
 
@@ -715,10 +731,11 @@ fail2:
 
     SharedInfoUnmap(Context);
 
-    FdoFreeHole(Fdo, Context->Address, 1);
-    Context->Address.QuadPart = 0;
     Context->Shared = NULL;
 
+    FdoHoleFree(Fdo, Context->Mdl);
+    Context->Mdl = NULL;
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -777,10 +794,11 @@ SharedInfoRelease (
 
     SharedInfoUnmap(Context);
 
-    FdoFreeHole(Fdo, Context->Address, 1);
-    Context->Address.QuadPart = 0;
     Context->Shared = NULL;
 
+    FdoHoleFree(Fdo, Context->Mdl);
+    Context->Mdl = NULL;
+
     Trace("<====\n");
 
 done:
-- 
2.25.1




 


Rackspace

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