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

[win-pv-devel] [PATCH 8/8] Rework indirect context structure



Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xenvbd/blockring.c | 48 ++++++++++++++++-----------------
 src/xenvbd/pdo.c       | 72 ++++++++++++++++++++++++++++++++------------------
 src/xenvbd/srbext.h    | 13 ++++++---
 3 files changed, 79 insertions(+), 54 deletions(-)

diff --git a/src/xenvbd/blockring.c b/src/xenvbd/blockring.c
index 28f1393..6ca9cb2 100644
--- a/src/xenvbd/blockring.c
+++ b/src/xenvbd/blockring.c
@@ -152,9 +152,10 @@ __BlockRingInsert(
     case BLKIF_OP_WRITE:
         if (Request->NrSegments > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
             // Indirect
-            ULONG                       PageIndex;
-            ULONG                       SegmentIndex;
-            PLIST_ENTRY                 Entry;
+            ULONG                       PageIdx;
+            ULONG                       SegIdx;
+            PLIST_ENTRY                 PageEntry;
+            PLIST_ENTRY                 SegEntry;
             blkif_request_indirect_t*   req_indirect;
 
             req_indirect = (blkif_request_indirect_t*)req;
@@ -165,29 +166,28 @@ __BlockRingInsert(
             req_indirect->sector_number     = Request->FirstSector;
             req_indirect->handle            = (USHORT)BlockRing->DeviceId;
 
-            for (PageIndex = 0, SegmentIndex = 0, Entry = 
Request->Segments.Flink;
-                    PageIndex < BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST &&
-                    Entry != &Request->Segments;
-                        Entry = Entry->Flink) {
-                PBLKIF_SEGMENT  Indirect = Request->Pages[PageIndex];
-                PXENVBD_SEGMENT Segment = CONTAINING_RECORD(Entry, 
XENVBD_SEGMENT, Entry);
-
-                Indirect[SegmentIndex].GrantRef = GranterReference(Granter, 
Segment->Grant);
-                Indirect[SegmentIndex].First    = Segment->FirstSector;
-                Indirect[SegmentIndex].Last     = Segment->LastSector;
-
-                ++SegmentIndex;
-                if (SegmentIndex >= XENVBD_MAX_SEGMENTS_PER_PAGE) {
-                    ++PageIndex;
-                    SegmentIndex = 0;
+            for (PageIdx = 0,
+                 PageEntry = Request->Indirects.Flink,
+                 SegEntry = Request->Segments.Flink;
+                    PageIdx < BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST &&
+                    PageEntry != &Request->Indirects &&
+                    SegEntry != &Request->Segments;
+                        ++PageIdx, PageEntry = PageEntry->Flink) {
+                PXENVBD_INDIRECT Page = CONTAINING_RECORD(PageEntry, 
XENVBD_INDIRECT, Entry);
+
+                req_indirect->indirect_grefs[PageIdx] = 
GranterReference(Granter, Page->Grant);
+
+                for (SegIdx = 0;
+                        SegIdx < XENVBD_MAX_SEGMENTS_PER_PAGE &&
+                        SegEntry != &Request->Segments;
+                            ++SegIdx, SegEntry = SegEntry->Flink) {
+                    PXENVBD_SEGMENT Segment = CONTAINING_RECORD(SegEntry, 
XENVBD_SEGMENT, Entry);
+
+                    Page->Page[SegIdx].GrantRef = GranterReference(Granter, 
Segment->Grant);
+                    Page->Page[SegIdx].First    = Segment->FirstSector;
+                    Page->Page[SegIdx].Last     = Segment->LastSector;
                 }
             }
-            for (PageIndex = 0;
-                    PageIndex < BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST &&
-                    Request->Grants[PageIndex] != NULL;
-                        ++PageIndex) {
-                req_indirect->indirect_grefs[PageIndex] = 
GranterReference(Granter, Request->Grants[PageIndex]);
-            }
         } else {
             // Direct
             ULONG           Index;
diff --git a/src/xenvbd/pdo.c b/src/xenvbd/pdo.c
index e8d94cb..3c429b2 100644
--- a/src/xenvbd/pdo.c
+++ b/src/xenvbd/pdo.c
@@ -567,20 +567,38 @@ PdoSectorSize(
 }
 
 //=============================================================================
-static PVOID
+static PXENVBD_INDIRECT
 PdoGetIndirect(
     IN  PXENVBD_PDO             Pdo
     )
 {
-    PVOID                       Indirect;
+    PXENVBD_INDIRECT    Indirect;
+    NTSTATUS            status;
+    PXENVBD_GRANTER     Granter = FrontendGetGranter(Pdo->Frontend);
 
     Indirect = __LookasideAlloc(&Pdo->IndirectList);
     if (Indirect == NULL)
         goto fail1;
 
-    RtlZeroMemory(Indirect, PAGE_SIZE);
+    RtlZeroMemory(Indirect, sizeof(XENVBD_INDIRECT));
+
+    Indirect->Page = __AllocPages(PAGE_SIZE, &Indirect->Mdl);
+    if (Indirect->Page == NULL)
+        goto fail2;
+
+    status = GranterGet(Granter,
+                        MmGetMdlPfnArray(Indirect->Mdl)[0],
+                        TRUE,
+                        &Indirect->Grant);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
     return Indirect;
 
+fail3:
+    __FreePages(Indirect->Page, Indirect->Mdl);
+fail2:
+    __LookasideFree(&Pdo->IndirectList, Indirect);
 fail1:
     return NULL;
 }
@@ -588,10 +606,17 @@ fail1:
 static VOID
 PdoPutIndirect(
     IN  PXENVBD_PDO             Pdo,
-    IN  PVOID                   Indirect
+    IN  PXENVBD_INDIRECT        Indirect
     )
 {
-    RtlZeroMemory(Indirect, PAGE_SIZE);
+    PXENVBD_GRANTER Granter = FrontendGetGranter(Pdo->Frontend);
+
+    if (Indirect->Grant)
+        GranterPut(Granter, Indirect->Grant);
+    if (Indirect->Page)
+        __FreePages(Indirect->Page, Indirect->Mdl);
+
+    RtlZeroMemory(Indirect, sizeof(XENVBD_INDIRECT));
     __LookasideFree(&Pdo->IndirectList, Indirect);
 }
 
@@ -648,6 +673,7 @@ PdoGetRequest(
     RtlZeroMemory(Request, sizeof(XENVBD_REQUEST));
     Request->Id = (ULONG)InterlockedIncrement((PLONG)&Pdo->NextTag);
     InitializeListHead(&Request->Segments);
+    InitializeListHead(&Request->Indirects);
 
     return Request;
 
@@ -661,11 +687,9 @@ PdoPutRequest(
     IN  PXENVBD_REQUEST         Request
     )
 {
-    ULONG           Index;
-    PXENVBD_GRANTER Granter = FrontendGetGranter(Pdo->Frontend);
+    PLIST_ENTRY     Entry;
 
     for (;;) {
-        PLIST_ENTRY     Entry;
         PXENVBD_SEGMENT Segment;
 
         Entry = RemoveHeadList(&Request->Segments);
@@ -675,11 +699,14 @@ PdoPutRequest(
         PdoPutSegment(Pdo, Segment);
     }
 
-    for (Index = 0; Index < BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST; ++Index) {
-        if (Request->Grants[Index])
-            GranterPut(Granter, Request->Grants[Index]);
-        if (Request->Pages[Index])
-            PdoPutIndirect(Pdo, Request->Pages[Index]);
+    for (;;) {
+        PXENVBD_INDIRECT    Indirect;
+
+        Entry = RemoveHeadList(&Request->Indirects);
+        if (Entry == &Request->Indirects)
+            break;
+        Indirect = CONTAINING_RECORD(Entry, XENVBD_INDIRECT, Entry);
+        PdoPutIndirect(Pdo, Indirect);
     }
 
     RtlZeroMemory(Request, sizeof(XENVBD_REQUEST));
@@ -1052,32 +1079,25 @@ PrepareBlkifIndirect(
     IN  PXENVBD_REQUEST         Request
     )
 {
-    NTSTATUS        status;
     ULONG           Index;
     ULONG           NrSegments = 0;
-    PXENVBD_GRANTER Granter = FrontendGetGranter(Pdo->Frontend);
 
     for (Index = 0;
             Index < BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST &&
             NrSegments < Request->NrSegments;
                 ++Index) {
-        Request->Pages[Index] = PdoGetIndirect(Pdo);
-        if (Request->Pages[Index] == NULL)
-            goto fail1;
+        PXENVBD_INDIRECT    Indirect;
 
-        status = GranterGet(Granter,
-                            __Virt2Pfn(Request->Pages[Index]),
-                            TRUE,
-                            &Request->Grants[Index]);
-        if (!NT_SUCCESS(status))
-            goto fail2;
+        Indirect = PdoGetIndirect(Pdo);
+        if (Indirect == NULL)
+            goto fail1;
+        InsertTailList(&Request->Indirects, &Indirect->Entry);
 
         NrSegments += XENVBD_MAX_SEGMENTS_PER_PAGE;
     }
 
     return TRUE;
 
-fail2:
 fail1:
     return FALSE;
 }
@@ -2583,7 +2603,7 @@ PdoCreate(
 
     __LookasideInit(&Pdo->RequestList, sizeof(XENVBD_REQUEST), 
REQUEST_POOL_TAG);
     __LookasideInit(&Pdo->SegmentList, sizeof(XENVBD_SEGMENT), 
SEGMENT_POOL_TAG);
-    __LookasideInit(&Pdo->IndirectList, PAGE_SIZE, INDIRECT_POOL_TAG);
+    __LookasideInit(&Pdo->IndirectList, sizeof(XENVBD_INDIRECT), 
INDIRECT_POOL_TAG);
 
     Status = PdoD3ToD0(Pdo);
     if (!NT_SUCCESS(Status))
diff --git a/src/xenvbd/srbext.h b/src/xenvbd/srbext.h
index 6550b72..6b41475 100644
--- a/src/xenvbd/srbext.h
+++ b/src/xenvbd/srbext.h
@@ -48,6 +48,14 @@ typedef struct _BLKIF_SEGMENT {
 
 #define XENVBD_MAX_SEGMENTS_PER_PAGE    (PAGE_SIZE / sizeof(BLKIF_SEGMENT))
 
+// Internal indirect context
+typedef struct _XENVBD_INDIRECT {
+    LIST_ENTRY              Entry;
+    PBLKIF_SEGMENT          Page;
+    PVOID                   Grant;
+    PMDL                    Mdl;
+} XENVBD_INDIRECT, *PXENVBD_INDIRECT;
+
 // Internal segment context
 typedef struct _XENVBD_SEGMENT {
     LIST_ENTRY              Entry;
@@ -74,10 +82,7 @@ typedef struct _XENVBD_REQUEST {
 
     ULONG64                 FirstSector;
     ULONG64                 NrSectors;  // BLKIF_OP_DISCARD only
-
-    // BLKIF_OP_{READ/WRITE} with NrSegments > 11 only
-    PVOID                   Pages[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST];
-    PVOID                   Grants[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST];
+    LIST_ENTRY              Indirects;  // BLKIF_OP_{READ/WRITE} with 
NrSegments > 11 only
 } XENVBD_REQUEST, *PXENVBD_REQUEST;
 
 // SRBExtension - context for SRBs
-- 
1.9.4.msysgit.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel


 


Rackspace

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