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

[win-pv-devel] [PATCH xenvbd] Try to avoid dumping non-RAM pages



When XENCRSH sets up blkif requests they may end up referring to PFNs that
are ballooned out. When these requests reach the backend driver, it will
unsurprisingly encounter failures when trying to map or copy the data from
these PFNs, generally resulting in the request as a whole being failed and
a lot of noise being emitted to various logs.

This patch adds a check into PrepareReadWrite() to check the P2M type of
PFNs being dumped. If the type is found to be anything other than writable
RAM then the PFN is substituted with a buffer PFN, which will just contain
zeroes. The storage backend will be able to map or copy these pages, so
stalls in the dump process and useless log messages will be avoided.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xencrsh/buffer.c |  2 +-
 src/xencrsh/hvm.c    | 31 +++++++++++++++++++++++++++++++
 src/xencrsh/hvm.h    |  6 ++++++
 src/xencrsh/pdo.c    | 32 ++++++++++++++++++++++++++++----
 4 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/src/xencrsh/buffer.c b/src/xencrsh/buffer.c
index 6c158b4..530daca 100644
--- a/src/xencrsh/buffer.c
+++ b/src/xencrsh/buffer.c
@@ -107,7 +107,7 @@ BufferGet(
     PXENVBD_BUFFER  Buf;
 
     if (__Buffer.Next == 0) {
-        // Warn!
+        LogWarning("failed to get buffer\n");
         return FALSE;
     }
     // find a free buffer, copy Buffer@Length into the buffer, return the 
BufferId and Pfn
diff --git a/src/xencrsh/hvm.c b/src/xencrsh/hvm.c
index 77a9ba6..47fcc5b 100644
--- a/src/xencrsh/hvm.c
+++ b/src/xencrsh/hvm.c
@@ -359,3 +359,34 @@ fail1:
 
     return status;
 }
+
+NTSTATUS
+HvmGetMemoryType(
+    IN  PFN_NUMBER              Pfn,
+    OUT ULONG                   *Type
+    )
+{
+    struct xen_hvm_get_mem_type op;
+    LONG_PTR                rc;
+    NTSTATUS                status;
+
+    RtlZeroMemory(&op, sizeof(struct xen_hvm_get_mem_type));
+
+    op.domid = DOMID_SELF;
+    op.pfn = Pfn;
+
+    rc = HvmOp(HVMOP_get_mem_type, &op);
+
+    if (rc < 0)
+        goto fail1;
+
+    *Type = op.mem_type;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    ERRNO_TO_STATUS(-rc, status);
+    LogError("fail1 (%08x)\n", status);
+
+    return status;
+}
diff --git a/src/xencrsh/hvm.h b/src/xencrsh/hvm.h
index 9b8f1df..433d73a 100644
--- a/src/xencrsh/hvm.h
+++ b/src/xencrsh/hvm.h
@@ -59,4 +59,10 @@ HvmSetParameter(
     IN  ULONGLONG       Value
     );
 
+NTSTATUS
+HvmGetMemoryType(
+    IN  PFN_NUMBER      Pfn,
+    OUT ULONG           *Type
+    );
+
 #endif // _XENVBD_HVM_H
diff --git a/src/xencrsh/pdo.c b/src/xencrsh/pdo.c
index 2ab764b..c3a9300 100644
--- a/src/xencrsh/pdo.c
+++ b/src/xencrsh/pdo.c
@@ -41,10 +41,12 @@
 #include "pdoinquiry.h"
 
 #include "austere.h"
+#include "hvm.h"
 #include "store.h"
 #include "gnttab.h"
 #include "evtchn.h"
 
+#include <xen/hvm/hvm_op.h>
 #include <xencdb.h>
 #include "log.h"
 #include "assert.h"
@@ -226,12 +228,17 @@ __CleanupRequest(
 
         // free bounce buffer
         if (Request->Segments[Index].BufferId) {
-            if (Request->Operation == BLKIF_OP_READ && CopyOut) {
-                BufferCopyOut(Request->Segments[Index].BufferId, 
(PUCHAR)Request->Segments[Index].Buffer, Request->Segments[Index].Length);
+            if (Request->Operation == BLKIF_OP_READ && CopyOut &&
+                Request->Segments[Index].Buffer) {
+                BufferCopyOut(Request->Segments[Index].BufferId,
+                              (PUCHAR)Request->Segments[Index].Buffer,
+                              Request->Segments[Index].Length);
             } 
             BufferPut(Request->Segments[Index].BufferId);
             Request->Segments[Index].BufferId = 0;
-            MmUnmapLockedPages(Request->Segments[Index].Buffer, 
&Request->Segments[Index].Mdl);
+            if (Request->Segments[Index].Buffer)
+                MmUnmapLockedPages(Request->Segments[Index].Buffer,
+                                   &Request->Segments[Index].Mdl);
         }
     }
 
@@ -428,6 +435,8 @@ PrepareReadWrite(
             SGIndex.LastLength = 0;
             __GetPhysAddr(SGList, &SGIndex, &PhysAddr, &PhysLen);
             if (__PhysAddrIsAligned(PhysAddr, PhysLen, SectorSize - 1)) {
+                ULONG Type;
+
                 // get first sector, last sector and count
                 FirstSector = (__Offset(PhysAddr) + SectorSize - 1) / 
SectorSize;
                 SectorsNow  = __Min(NumSectors - SectorsDone, SectorsPerPage - 
FirstSector);
@@ -438,6 +447,21 @@ PrepareReadWrite(
                
                 // simples - grab Pfn of PhysAddr
                 Pfn         = __Pfn(PhysAddr);
+
+                Status = HvmGetMemoryType(Pfn, &Type);
+                if (!NT_SUCCESS(Status))
+                    LogWarning("Unable to get type for PFN %lx\n", Pfn);
+                else if (Type != HVMMEM_ram_rw) {
+                    ULONG BufferId;
+
+                    if (!BufferGet(&BufferId, &Pfn)) {
+                        Pdo->NeedsWake = TRUE;
+                        __CleanupSrb(Srb);
+                        return STATUS_INSUFFICIENT_RESOURCES;
+                    }
+
+                    Request->Segments[Index2].BufferId = BufferId;
+                }
             } else {
                 PMDL        Mdl;
                 ULONG       BufferId;
@@ -1177,4 +1201,4 @@ PdoEvtchnInterruptHandler(
     )
 {
     FrontendEvtchnCallback(&Pdo->Frontend);
-}
\ No newline at end of file
+}
-- 
2.5.3


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

 


Rackspace

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