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

[win-pv-devel] [PATCH 2/5] Use CACHE interface for bounce buffers



From: Owen Smith <owen.smith@xxxxxxxxxx>

When the incomming read/write buffer is not aligned, the data needs
bouncing via a page-aligned buffer. Use the CACHE interface to provide
this buffer instead of a custom lookaside collection. Also moves the
storage for mapping the source buffers to the bounce buffer structure,
which will reduce the allocation size of the segments used on the fast
path (aligned buffers). The Indirect pages are also pre-allocated in the
object construction, and not for every object retrieval, and likewise
indirect pages are only freed on object destruction, and not for every
object put.
This will remove the log spam caused by the custom implementation.

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xenvbd/adapter.c         | 129 ++++++++++++-
 src/xenvbd/adapter.h         |  11 ++
 src/xenvbd/buffer.c          | 426 -------------------------------------------
 src/xenvbd/buffer.h          |  80 --------
 src/xenvbd/driver.c          |   6 -
 src/xenvbd/ring.c            |  97 ++++++----
 src/xenvbd/srbext.h          |  13 +-
 src/xenvbd/target.c          |   1 -
 vs2015/xenvbd/xenvbd.vcxproj |   1 -
 9 files changed, 200 insertions(+), 564 deletions(-)
 delete mode 100644 src/xenvbd/buffer.c
 delete mode 100644 src/xenvbd/buffer.h

diff --git a/src/xenvbd/adapter.c b/src/xenvbd/adapter.c
index 59724bb..4fb75b8 100644
--- a/src/xenvbd/adapter.c
+++ b/src/xenvbd/adapter.c
@@ -53,7 +53,6 @@
 #include "target.h"
 #include "srbext.h"
 #include "thread.h"
-#include "buffer.h"
 
 #include "util.h"
 #include "debug.h"
@@ -81,6 +80,7 @@ struct _XENVBD_ADAPTER {
     XENBUS_UNPLUG_INTERFACE     UnplugInterface;
     XENFILT_EMULATED_INTERFACE  EmulatedInterface;
 
+    PXENBUS_CACHE               BounceCache;
     PXENBUS_DEBUG_CALLBACK      DebugCallback;
     PXENBUS_SUSPEND_CALLBACK    SuspendCallback;
 
@@ -910,8 +910,6 @@ AdapterDebugCallback(
                  Adapter->BuildIo,
                  Adapter->StartIo,
                  Adapter->Completed);
-
-    BufferDebugCallback(&Adapter->DebugInterface);
 }
 
 static NTSTATUS
@@ -1097,6 +1095,89 @@ AdapterDevicePowerThread(
     return STATUS_SUCCESS;
 }
 
+PXENVBD_BOUNCE
+AdapterGetBounce(
+    IN  PXENVBD_ADAPTER Adapter
+    )
+{
+    return XENBUS_CACHE(Get,
+                        &Adapter->CacheInterface,
+                        Adapter->BounceCache,
+                        FALSE);
+}
+
+VOID
+AdapterPutBounce(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PXENVBD_BOUNCE  Bounce
+    )
+{
+    XENBUS_CACHE(Put,
+                 &Adapter->CacheInterface,
+                 Adapter->BounceCache,
+                 Bounce,
+                 FALSE);
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+AdapterBounceCtor(
+    IN  PVOID       Argument,
+    IN  PVOID       Object
+    )
+{
+    PXENVBD_BOUNCE  Bounce = Object;
+    NTSTATUS        status;
+
+    UNREFERENCED_PARAMETER(Argument);
+
+    status = STATUS_NO_MEMORY;
+    Bounce->BounceMdl = __AllocatePage();
+    if (Bounce->BounceMdl == NULL)
+        goto fail1;
+
+    Bounce->BouncePtr = MmGetSystemAddressForMdlSafe(Bounce->BounceMdl,
+                                                     NormalPagePriority);
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1\n");
+    return status;
+}
+
+static DECLSPEC_NOINLINE VOID
+AdapterBounceDtor(
+    IN  PVOID       Argument,
+    IN  PVOID       Object
+    )
+{
+    PXENVBD_BOUNCE  Bounce = Object;
+
+    UNREFERENCED_PARAMETER(Argument);
+
+    Bounce->BouncePtr = NULL;
+
+    __FreePages(Bounce->BounceMdl);
+    Bounce->BounceMdl = NULL;
+}
+
+static DECLSPEC_NOINLINE VOID
+AdapterAcquireLock(
+    IN  PVOID       Argument
+    )
+{
+    PXENVBD_ADAPTER Adapter = Argument;
+    KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
+}
+
+static DECLSPEC_NOINLINE VOID
+AdapterReleaseLock(
+    IN  PVOID       Argument
+    )
+{
+    PXENVBD_ADAPTER Adapter = Argument;
+    KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
+}
+
 __drv_requiresIRQL(PASSIVE_LEVEL)
 static NTSTATUS
 __AdapterQueryInterface(
@@ -1256,25 +1337,52 @@ AdapterInitialize(
     if (!NT_SUCCESS(status))
         goto fail8;
 
+    status = XENBUS_CACHE(Acquire, &Adapter->CacheInterface);
+    if (!NT_SUCCESS(status))
+        goto fail9;
+
+    status = XENBUS_CACHE(Create,
+                          &Adapter->CacheInterface,
+                          "vbd_bounce",
+                          sizeof(XENVBD_BOUNCE),
+                          32,
+                          AdapterBounceCtor,
+                          AdapterBounceDtor,
+                          AdapterAcquireLock,
+                          AdapterReleaseLock,
+                          Adapter,
+                          &Adapter->BounceCache);
+    if (!NT_SUCCESS(status))
+        goto fail10;
+
     status = ThreadCreate(AdapterScanThread,
                           Adapter,
                           &Adapter->ScanThread);
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail11;
 
     status = ThreadCreate(AdapterDevicePowerThread,
                           Adapter,
                           &Adapter->DevicePowerThread);
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail12;
 
     return STATUS_SUCCESS;
 
-fail10:
-    Error("fail10\n");
+fail12:
+    Error("fail12\n");
     ThreadAlert(Adapter->ScanThread);
     ThreadJoin(Adapter->ScanThread);
     Adapter->ScanThread = NULL;
+fail11:
+    Error("fail11\n");
+    XENBUS_CACHE(Destroy,
+                 &Adapter->CacheInterface,
+                 Adapter->BounceCache);
+    Adapter->BounceCache = NULL;
+fail10:
+    Error("fail10\n");
+    XENBUS_CACHE(Release, &Adapter->CacheInterface);
 fail9:
     Error("fail9\n");
     RtlZeroMemory(&Adapter->EmulatedInterface,
@@ -1353,6 +1461,13 @@ AdapterTeardown(
         TargetDestroy(Target);
     }
 
+    XENBUS_CACHE(Destroy,
+                 &Adapter->CacheInterface,
+                 Adapter->BounceCache);
+    Adapter->BounceCache = NULL;
+
+    XENBUS_CACHE(Release, &Adapter->CacheInterface);
+
     RtlZeroMemory(&Adapter->EmulatedInterface,
                   sizeof (XENFILT_EMULATED_INTERFACE));
 
diff --git a/src/xenvbd/adapter.h b/src/xenvbd/adapter.h
index 25febc1..354699b 100644
--- a/src/xenvbd/adapter.h
+++ b/src/xenvbd/adapter.h
@@ -93,6 +93,17 @@ AdapterGetNextSGEntry(
     OUT PULONG          Length
     );
 
+extern PXENVBD_BOUNCE
+AdapterGetBounce(
+    IN  PXENVBD_ADAPTER Adapter
+    );
+
+extern VOID
+AdapterPutBounce(
+    IN  PXENVBD_ADAPTER Adapter,
+    IN  PXENVBD_BOUNCE  Bounce
+    );
+
 extern NTSTATUS
 AdapterDispatchPnp(
     IN  PXENVBD_ADAPTER Adapter,
diff --git a/src/xenvbd/buffer.c b/src/xenvbd/buffer.c
deleted file mode 100644
index 9de7792..0000000
--- a/src/xenvbd/buffer.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#include "buffer.h"
-#include "thread.h"
-#include "debug.h"
-#include "assert.h"
-#include "util.h"
-
-#define BUFFER_POOL_TAG 'fuBX'
-
-#define BUFFER_MIN_COUNT         32
-
-extern PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID BaseAddress);
-
-typedef struct _XENVBD_BUFFER {
-    LIST_ENTRY          Entry;
-    PMDL                Mdl;
-    PVOID               VAddr;
-    PFN_NUMBER          Pfn;
-    PVOID               Context;
-} XENVBD_BUFFER, *PXENVBD_BUFFER;
-
-typedef struct _XENVBD_BOUNCE_BUFFER {
-    LIST_ENTRY          FreeList;
-    LIST_ENTRY          UsedList;
-    ULONG               FreeSize;
-    ULONG               UsedSize;
-    ULONG               FreeMaxSize;
-    ULONG               UsedMaxSize;
-    KSPIN_LOCK          Lock;
-    PXENVBD_THREAD      Thread;
-    ULONG               ReapThreadCount;
-    ULONG               Reaped;
-    ULONG               Allocated;
-    ULONG               Freed;
-} XENVBD_BOUNCE_BUFFER, *PXENVBD_BOUNCE_BUFFER;
-
-static XENVBD_BOUNCE_BUFFER __Buffer;
-
-#define TIME_US(_us)        ((_us) * 10)
-#define TIME_MS(_ms)        (TIME_US((_ms) * 1000))
-#define TIME_S(_s)          (TIME_MS((_s) * 1000))
-#define TIME_RELATIVE(_t)   (-(_t))
-
-static DECLSPEC_NOINLINE PXENVBD_BUFFER
-__BufferAlloc()
-{
-    PXENVBD_BUFFER  BufferId;
-
-    BufferId = (PXENVBD_BUFFER)__AllocatePoolWithTag(NonPagedPool, 
sizeof(XENVBD_BUFFER), BUFFER_POOL_TAG);
-    if (BufferId == NULL)
-        goto fail1;
-
-    RtlZeroMemory(BufferId, sizeof(XENVBD_BUFFER));
-    
-    BufferId->Mdl = __AllocatePage();
-    if (BufferId->Mdl == NULL)
-        goto fail2;
-
-    BufferId->VAddr = MmGetSystemAddressForMdlSafe(BufferId->Mdl,
-                                                   NormalPagePriority);
-
-    BufferId->Pfn = 
(PFN_NUMBER)(MmGetPhysicalAddress(BufferId->VAddr).QuadPart >> PAGE_SHIFT);
-    
-    ++__Buffer.Allocated;
-    return BufferId;
-
-fail2:
-    __FreePoolWithTag(BufferId, BUFFER_POOL_TAG);
-fail1:
-    return NULL;
-}
-static DECLSPEC_NOINLINE VOID
-__BufferFree(
-    IN PXENVBD_BUFFER           BufferId
-    )
-{
-    if (BufferId == NULL)
-        return;
-
-    __FreePage(BufferId->Mdl);
-    __FreePoolWithTag((PVOID)BufferId, BUFFER_POOL_TAG);
-
-    ++__Buffer.Freed;
-}
-static DECLSPEC_NOINLINE BOOLEAN
-__IsOnList(
-    IN  PLIST_ENTRY             ListHead,
-    IN  PLIST_ENTRY             ListItem,
-    IN  BOOLEAN                 Locked
-    )
-{
-    KIRQL       Irql = KeGetCurrentIrql();
-    PLIST_ENTRY Entry;
-    BOOLEAN     Found = FALSE;
-
-    if (!Locked)
-        KeAcquireSpinLock(&__Buffer.Lock, &Irql);
-
-    ASSERT3P(ListHead, !=, NULL);
-    ASSERT3P(ListItem, !=, NULL);
-    ASSERT3P(ListHead->Flink, !=, NULL);
-    ASSERT3P(ListHead, !=, ListItem);
-    ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
-
-#pragma prefast(suppress:6011)
-    for (Entry = ListHead->Flink; Entry != ListHead; Entry = Entry->Flink) {
-        ASSERT3P(Entry, !=, NULL);
-        if (Entry == ListItem) {
-            Found = TRUE;
-            break;
-        }
-    }
-
-    if (!Locked)
-        KeReleaseSpinLock(&__Buffer.Lock, Irql);
-
-    return Found;
-}
-
-#ifdef DBG
-#define IsOnList(a, b, c)  __IsOnList(a, b, c)
-#else
-#define IsOnList(a, b, c)  (TRUE)
-#endif
-
-static DECLSPEC_NOINLINE VOID
-__BufferPushFreeList(
-    IN PXENVBD_BUFFER           BufferId
-    )
-{
-    ASSERT3P(BufferId->Entry.Flink, ==, NULL);
-    ASSERT3P(BufferId->Entry.Blink, ==, NULL);
-
-    InsertHeadList(&__Buffer.FreeList, &BufferId->Entry);
-    ++__Buffer.FreeSize;
-    if (__Buffer.FreeSize > __Buffer.FreeMaxSize)
-        __Buffer.FreeMaxSize = __Buffer.FreeSize;
-}
-static DECLSPEC_NOINLINE PXENVBD_BUFFER
-__BufferPopFreeList(
-    )
-{
-    PLIST_ENTRY     Entry;
-
-    Entry = RemoveHeadList(&__Buffer.FreeList);
-    if (Entry && Entry != &__Buffer.FreeList) {
-        PXENVBD_BUFFER BufferId = CONTAINING_RECORD(Entry, XENVBD_BUFFER, 
Entry);
-        BufferId->Entry.Flink = NULL;
-        BufferId->Entry.Blink = NULL;
-        --__Buffer.FreeSize;
-        return BufferId;
-    }
-
-    return NULL;
-}
-static DECLSPEC_NOINLINE VOID
-__BufferPushUsedList(
-    IN PXENVBD_BUFFER           BufferId
-    )
-{
-    ASSERT3P(BufferId->Entry.Flink, ==, NULL);
-    ASSERT3P(BufferId->Entry.Blink, ==, NULL);
-
-    InsertHeadList(&__Buffer.UsedList, &BufferId->Entry);
-    ++__Buffer.UsedSize;
-    if (__Buffer.UsedSize > __Buffer.UsedMaxSize)
-        __Buffer.UsedMaxSize = __Buffer.UsedSize;
-}
-static DECLSPEC_NOINLINE PXENVBD_BUFFER
-__BufferPopUsedList(
-    )
-{
-    PLIST_ENTRY     Entry;
-
-    Entry = RemoveHeadList(&__Buffer.UsedList);
-    if (Entry && Entry != &__Buffer.UsedList) {
-        PXENVBD_BUFFER BufferId = CONTAINING_RECORD(Entry, XENVBD_BUFFER, 
Entry);
-        BufferId->Entry.Flink = NULL;
-        BufferId->Entry.Blink = NULL;
-        --__Buffer.UsedSize;
-        return BufferId;
-    }
-
-    return NULL;
-}
-static DECLSPEC_NOINLINE VOID
-__BufferRemoveUsedList(
-    IN PXENVBD_BUFFER           BufferId
-    )
-{
-    ASSERT3P(BufferId->Entry.Flink, !=, NULL);
-    ASSERT3P(BufferId->Entry.Blink, !=, NULL);
-    ASSERT(IsOnList(&__Buffer.UsedList, &BufferId->Entry, TRUE));
-
-    RemoveEntryList(&BufferId->Entry);
-    BufferId->Entry.Flink = NULL;
-    BufferId->Entry.Blink = NULL;
-    --__Buffer.UsedSize;
-}
-static DECLSPEC_NOINLINE NTSTATUS
-__BufferReaperThread(
-    IN PXENVBD_THREAD           Thread,
-    IN PVOID                    Context
-    )
-{
-    KIRQL           Irql;
-    PKEVENT         Event;
-    LARGE_INTEGER   Timeout;
-    PXENVBD_BUFFER  BufferId;
-
-    UNREFERENCED_PARAMETER(Context);
-    
-    Timeout.QuadPart = TIME_RELATIVE(TIME_S(1)); // 1 Second
-    Event = ThreadGetEvent(Thread);
-
-    while (TRUE) {
-        KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, &Timeout);
-        if (ThreadIsAlerted(Thread))
-            break;
-
-        KeAcquireSpinLock(&__Buffer.Lock, &Irql);
-        if (__Buffer.FreeSize > BUFFER_MIN_COUNT) {
-            Verbose("Reaping Buffers (%d > %d)\n", __Buffer.FreeSize, 
BUFFER_MIN_COUNT);
-            ++__Buffer.ReapThreadCount;
-        }
-        while (__Buffer.FreeSize > BUFFER_MIN_COUNT) {
-            BufferId = __BufferPopFreeList();
-            if (BufferId) {
-                ++__Buffer.Reaped;
-                __BufferFree(BufferId);
-            }
-        }
-        KeReleaseSpinLock(&__Buffer.Lock, Irql);
-    }
-
-    return STATUS_SUCCESS;
-}
-
-VOID
-BufferInitialize(
-    )
-{
-    ULONG           i;
-    PXENVBD_BUFFER  BufferId;
-
-    RtlZeroMemory(&__Buffer, sizeof(XENVBD_BOUNCE_BUFFER));
-    KeInitializeSpinLock(&__Buffer.Lock);
-    InitializeListHead(&__Buffer.FreeList);
-    InitializeListHead(&__Buffer.UsedList);
-
-    for (i = 0; i < BUFFER_MIN_COUNT; ++i) {
-        BufferId = __BufferAlloc();
-        if (BufferId) {
-            __BufferPushFreeList(BufferId);
-        }
-    }
-
-    if (__Buffer.Thread == NULL) {
-        (VOID) ThreadCreate(__BufferReaperThread, NULL, &__Buffer.Thread);
-    }
-}
-
-VOID
-BufferTerminate(
-    )
-{
-    PXENVBD_BUFFER  BufferId;
-
-    if (__Buffer.Thread) {
-        ThreadAlert(__Buffer.Thread);
-        ThreadJoin(__Buffer.Thread);
-        __Buffer.Thread = NULL;
-    }
-
-    while ((BufferId = __BufferPopUsedList()) != NULL) {
-        Warning("Potentially leaking buffer @ 0x%p\n", BufferId->VAddr);
-        __BufferPushFreeList(BufferId);
-    }
-    while ((BufferId = __BufferPopFreeList()) != NULL) {
-        __BufferFree(BufferId);
-    }
-}
-
-__checkReturn
-BOOLEAN
-BufferGet(
-    __in  PVOID             _Context,
-    __out PVOID*            _BufferId,
-    __out PFN_NUMBER*       Pfn
-    )
-{
-    PXENVBD_BUFFER  BufferId;
-    KIRQL           Irql;
-    BOOLEAN         Result = FALSE;
-
-       *_BufferId = NULL;
-       *Pfn = 0;
-
-    KeAcquireSpinLock(&__Buffer.Lock, &Irql);
-    BufferId = __BufferPopFreeList();
-    if (BufferId == NULL) {
-        BufferId = __BufferAlloc();
-    }
-    if (BufferId) {
-        __BufferPushUsedList(BufferId);
-
-        BufferId->Context = _Context;
-        *_BufferId = BufferId;
-        *Pfn = BufferId->Pfn; 
-        Result = TRUE;
-    } 
-    KeReleaseSpinLock(&__Buffer.Lock, Irql);
-    
-    return Result;
-}
-
-VOID
-BufferPut(
-    __in PVOID              _BufferId
-    )
-{
-    KIRQL           Irql;
-    PXENVBD_BUFFER  BufferId = (PXENVBD_BUFFER)_BufferId;
-
-    KeAcquireSpinLock(&__Buffer.Lock, &Irql);
-    __BufferRemoveUsedList(BufferId);
-    BufferId->Context = NULL;
-    __BufferPushFreeList(BufferId);
-    KeReleaseSpinLock(&__Buffer.Lock, Irql);
-}
-
-VOID
-BufferCopyIn(
-    __in PVOID              _BufferId,
-    __in PVOID              Input,
-    __in ULONG              Length
-    )
-{
-    PXENVBD_BUFFER  BufferId = (PXENVBD_BUFFER)_BufferId;
-
-    ASSERT3P(BufferId, !=, NULL);
-    ASSERT3P(Input, !=, NULL);
-    ASSERT3U(Length, <=, PAGE_SIZE);
-
-    ASSERT3P(BufferId->VAddr, !=, NULL);
-    ASSERT(IsOnList(&__Buffer.UsedList, &BufferId->Entry, FALSE));
-    RtlCopyMemory(BufferId->VAddr, Input, Length);
-}
-
-VOID
-BufferCopyOut(
-    __in PVOID              _BufferId,
-    __in PVOID              Output,
-    __in ULONG              Length
-    )
-{
-    PXENVBD_BUFFER  BufferId = (PXENVBD_BUFFER)_BufferId;
-
-    ASSERT3P(BufferId, !=, NULL);
-    ASSERT3P(Output, !=, NULL);
-    ASSERT3U(Length, <=, PAGE_SIZE);
-
-    ASSERT3P(BufferId->VAddr, !=, NULL);
-    ASSERT(IsOnList(&__Buffer.UsedList, &BufferId->Entry, FALSE));
-    RtlCopyMemory(Output, BufferId->VAddr, Length);
-}
-
-VOID 
-BufferDebugCallback(
-    __in PXENBUS_DEBUG_INTERFACE DebugInterface
-    )
-{
-    PLIST_ENTRY Entry;
-
-    XENBUS_DEBUG(Printf, DebugInterface,
-                 "BUFFER: Allocated/Freed : %d / %d\n",
-                 __Buffer.Allocated, __Buffer.Freed);
-    XENBUS_DEBUG(Printf, DebugInterface,
-                 "BUFFER: Free (Cur/Max)  : %d / %d\n",
-                 __Buffer.FreeSize, __Buffer.FreeMaxSize);
-    XENBUS_DEBUG(Printf, DebugInterface,
-                 "BUFFER: Used (Cur/Max)  : %d / %d\n",
-                 __Buffer.UsedSize, __Buffer.UsedMaxSize);
-
-    for (Entry = __Buffer.UsedList.Flink; Entry != &__Buffer.UsedList; Entry = 
Entry->Flink) {
-        PXENVBD_BUFFER BufferId = CONTAINING_RECORD(Entry, XENVBD_BUFFER, 
Entry);
-
-        XENBUS_DEBUG(Printf, DebugInterface,
-                     "BUFFER: (Used)          : VADDR:0x%p PFN:%p (SRB 
0x%p)\n",
-                     BufferId->VAddr, (void*)BufferId->Pfn, BufferId->Context);
-    }
-
-    XENBUS_DEBUG(Printf, DebugInterface,
-                 "BUFFER: Reaped          : %d / %d\n", 
-                 __Buffer.Reaped, __Buffer.ReapThreadCount);
-}
diff --git a/src/xenvbd/buffer.h b/src/xenvbd/buffer.h
deleted file mode 100644
index 3dace80..0000000
--- a/src/xenvbd/buffer.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#ifndef _XENVBD_BUFFER_H
-#define _XENVBD_BUFFER_H
-
-#include <wdm.h>
-#include <xenvbd-storport.h>
-#include <debug_interface.h>
-
-extern VOID
-BufferInitialize(
-    );
-
-extern VOID
-BufferTerminate(
-    );
-
-__checkReturn
-extern BOOLEAN
-BufferGet(
-    __in  PVOID             Context,
-    __out PVOID*            BufferId,
-    __out PFN_NUMBER*       Pfn
-    );
-
-extern VOID
-BufferPut(
-    __in  PVOID             BufferId
-    );
-
-extern VOID
-BufferCopyIn(
-    __in  PVOID             BufferId,
-    __in  PVOID             Input,
-    __in  ULONG             Length
-    );
-
-extern VOID
-BufferCopyOut(
-    __in  PVOID             BufferId,
-    __in  PVOID             Output,
-    __in  ULONG             Length
-    );
-
-extern VOID 
-BufferDebugCallback(
-    __in PXENBUS_DEBUG_INTERFACE DebugInterface
-    );
-
-   
-#endif // _XENVBD_BUFFER_H
diff --git a/src/xenvbd/driver.c b/src/xenvbd/driver.c
index 676c445..e7a3d3a 100644
--- a/src/xenvbd/driver.c
+++ b/src/xenvbd/driver.c
@@ -41,7 +41,6 @@
 #include "adapter.h"
 #include "registry.h"
 #include "srbext.h"
-#include "buffer.h"
 
 #include "util.h"
 #include "debug.h"
@@ -240,8 +239,6 @@ DriverUnload(
     Driver.StorPortDispatchPnp = NULL;
     Driver.StorPortDispatchPower = NULL;
 
-    BufferTerminate();
-
     RegistryCloseKey(Driver.ParametersKey);
     Driver.ParametersKey = NULL;
 
@@ -366,7 +363,6 @@ DriverEntry(
 
     Driver.ParametersKey = ParametersKey;
     Driver.Adapter = NULL;
-    BufferInitialize();
 
     __DriverInitializeOverrides();
 
@@ -391,8 +387,6 @@ DriverEntry(
 fail4:
     Error("fail4\n");
 
-    BufferTerminate();
-
     RegistryCloseKey(Driver.ParametersKey);
     Driver.ParametersKey = NULL;
 
diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index ba389d8..77eee54 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -47,7 +47,6 @@
 #include "driver.h"
 #include "granter.h"
 #include "queue.h"
-#include "buffer.h"
 
 #include "util.h"
 #include "debug.h"
@@ -446,15 +445,25 @@ RingPutSegment(
     )
 {
     PXENVBD_GRANTER     Granter = FrontendGetGranter(Ring->Frontend);
+    PXENVBD_BOUNCE      Bounce = Segment->Bounce;
 
     if (Segment->Grant)
         GranterPut(Granter, Segment->Grant);
 
-    if (Segment->BufferId)
-        BufferPut(Segment->BufferId);
+    if (Bounce) {
+        if (Bounce->SourcePtr) {
+            MmUnmapLockedPages(Bounce->SourcePtr,
+                               &Bounce->SourceMdl);
+        }
+        RtlZeroMemory(&Bounce->SourceMdl, sizeof(MDL));
+        Bounce->SourcePtr = NULL;
+        Bounce->SourcePfn[0] = 0;
+        Bounce->SourcePfn[1] = 0;
 
-    if (Segment->Buffer)
-        MmUnmapLockedPages(Segment->Buffer, &Segment->Mdl);
+        AdapterPutBounce(TargetGetAdapter(FrontendGetTarget(Ring->Frontend)),
+                         Bounce);
+    }
+    Segment->Bounce = NULL;
 
     RtlZeroMemory(Segment, sizeof(XENVBD_SEGMENT));
     __LookasideFree(&Ring->SegmentList, Segment);
@@ -636,9 +645,13 @@ RingRequestCopyOutput(
             Entry != &Request->Segments;
             Entry = Entry->Flink) {
         PXENVBD_SEGMENT Segment = CONTAINING_RECORD(Entry, XENVBD_SEGMENT, 
Entry);
+        PXENVBD_BOUNCE  Bounce = Segment->Bounce;
 
-        if (Segment->BufferId)
-            BufferCopyOut(Segment->BufferId, Segment->Buffer, Segment->Length);
+        if (Bounce) {
+            RtlCopyMemory(Bounce->SourcePtr,
+                          Bounce->BouncePtr,
+                          MmGetMdlByteCount(&Bounce->SourceMdl));
+        }
     }
 }
 
@@ -660,8 +673,9 @@ RingPrepareSegment(
     const ULONG         SectorSize = 
FrontendGetDiskInfo(Ring->Frontend)->SectorSize;
     const ULONG         SectorsPerPage = __RingSectorsPerPage(SectorSize);
     PXENVBD_TARGET      Target = FrontendGetTarget(Ring->Frontend);
+    PXENVBD_ADAPTER     Adapter = TargetGetAdapter(Target);
 
-    Pfn = AdapterGetNextSGEntry(TargetGetAdapter(Target),
+    Pfn = AdapterGetNextSGEntry(Adapter,
                                 SrbExt,
                                 0,
                                 &Offset,
@@ -673,13 +687,11 @@ RingPrepareSegment(
         Segment->FirstSector    = (UCHAR)((Offset + SectorSize - 1) / 
SectorSize);
         *SectorsNow             = __min(SectorsLeft, SectorsPerPage - 
Segment->FirstSector);
         Segment->LastSector     = (UCHAR)(Segment->FirstSector + *SectorsNow - 
1);
-        Segment->BufferId       = NULL; // granted, ensure its null
-        Segment->Buffer         = NULL; // granted, ensure its null
-        Segment->Length         = 0;    // granted, ensure its 0
 
         ASSERT3U((Length / SectorSize), ==, *SectorsNow);
     } else {
-        PMDL        Mdl;
+        PXENVBD_BOUNCE      Bounce;
+        PMDL                Mdl;
 
         ++Ring->SegsBounced;
         // get first sector, last sector and count
@@ -687,29 +699,33 @@ RingPrepareSegment(
         *SectorsNow             = __min(SectorsLeft, SectorsPerPage);
         Segment->LastSector     = (UCHAR)(*SectorsNow - 1);
 
-        // map SGList to Virtual Address. Populates Segment->Buffer and 
Segment->Length
+        Bounce = AdapterGetBounce(Adapter);
+        if (Bounce == NULL)
+            goto fail1;
+        Segment->Bounce = Bounce;
+
 #pragma warning(push)
 #pragma warning(disable:28145)
-        Mdl = &Segment->Mdl;
-        Mdl->Next           = NULL;
-        Mdl->Size           = (SHORT)(sizeof(MDL) + sizeof(PFN_NUMBER));
-        Mdl->MdlFlags       = MDL_PAGES_LOCKED;
-        Mdl->Process        = NULL;
-        Mdl->MappedSystemVa = NULL;
-        Mdl->StartVa        = NULL;
-        Mdl->ByteCount      = Length;
-        Mdl->ByteOffset     = Offset;
-        Segment->Pfn[0]     = Pfn;
+        Mdl = &Bounce->SourceMdl;
+        Mdl->Next               = NULL;
+        Mdl->Size               = (SHORT)(sizeof(MDL) + sizeof(PFN_NUMBER));
+        Mdl->MdlFlags           = MDL_PAGES_LOCKED;
+        Mdl->Process            = NULL;
+        Mdl->MappedSystemVa     = NULL;
+        Mdl->StartVa            = NULL;
+        Mdl->ByteCount          = Length;
+        Mdl->ByteOffset         = Offset;
+        Bounce->SourcePfn[0]    = Pfn;
 
         if (Length < *SectorsNow * SectorSize) {
-            Pfn = AdapterGetNextSGEntry(TargetGetAdapter(Target),
+            Pfn = AdapterGetNextSGEntry(Adapter,
                                         SrbExt,
                                         Length,
                                         &Offset,
                                         &Length);
-            Mdl->Size       += sizeof(PFN_NUMBER);
-            Mdl->ByteCount  = Mdl->ByteCount + Length;
-            Segment->Pfn[1] = Pfn;
+            Mdl->Size           += sizeof(PFN_NUMBER);
+            Mdl->ByteCount      += Length;
+            Bounce->SourcePfn[1] = Pfn;
         }
 #pragma warning(pop)
 
@@ -717,23 +733,26 @@ RingPrepareSegment(
         ASSERT3U(Mdl->ByteCount, <=, PAGE_SIZE);
         ASSERT3U(*SectorsNow, ==, (Mdl->ByteCount / SectorSize));
 
-        Segment->Length = __min(Mdl->ByteCount, PAGE_SIZE);
-        Segment->Buffer = MmMapLockedPagesSpecifyCache(Mdl, KernelMode,
-                                MmCached, NULL, FALSE, __RingPriority(Ring));
-        if (!Segment->Buffer)
-            goto fail1;
-
-        ASSERT3P(MmGetMdlPfnArray(Mdl)[0], ==, Segment->Pfn[0]);
-        ASSERT3P(MmGetMdlPfnArray(Mdl)[1], ==, Segment->Pfn[1]);
-
-        // get a buffer
-        if (!BufferGet(Segment, &Segment->BufferId, &Pfn))
+        Bounce->SourcePtr = MmMapLockedPagesSpecifyCache(Mdl,
+                                                         KernelMode,
+                                                         MmCached,
+                                                         NULL,
+                                                         FALSE,
+                                                         __RingPriority(Ring));
+        if (Bounce->SourcePtr == NULL)
             goto fail2;
 
+        ASSERT3P(MmGetMdlPfnArray(Mdl)[0], ==, Bounce->SourcePfn[0]);
+        ASSERT3P(MmGetMdlPfnArray(Mdl)[1], ==, Bounce->SourcePfn[1]);
+
         // copy contents in
         if (ReadOnly) { // Operation == BLKIF_OP_WRITE
-            BufferCopyIn(Segment->BufferId, Segment->Buffer, Segment->Length);
+            RtlCopyMemory(Bounce->BouncePtr,
+                          Bounce->SourcePtr,
+                          MmGetMdlByteCount(&Bounce->SourceMdl));
         }
+
+        Pfn = MmGetMdlPfnArray(Bounce->BounceMdl)[0];
     }
 
     // Grant segment's page
diff --git a/src/xenvbd/srbext.h b/src/xenvbd/srbext.h
index c5ecdb6..54ec119 100644
--- a/src/xenvbd/srbext.h
+++ b/src/xenvbd/srbext.h
@@ -37,6 +37,14 @@
 #include <xen.h>
 #include "assert.h"
 
+typedef struct _XENVBD_BOUNCE {
+    PVOID                   BouncePtr;
+    PMDL                    BounceMdl;
+    PVOID                   SourcePtr;
+    MDL                     SourceMdl;
+    PFN_NUMBER              SourcePfn[2];
+} XENVBD_BOUNCE, *PXENVBD_BOUNCE;
+
 #pragma pack(push, 1)
 typedef struct _BLKIF_SEGMENT {
     ULONG                   GrantRef;
@@ -63,10 +71,7 @@ typedef struct _XENVBD_SEGMENT {
     UCHAR                   FirstSector;
     UCHAR                   LastSector;
     ULONG                   Length;
-    PVOID                   BufferId;
-    PVOID                   Buffer; // VirtAddr mapped to PhysAddr(s)
-    MDL                     Mdl;
-    PFN_NUMBER              Pfn[2];
+    PXENVBD_BOUNCE          Bounce;
 } XENVBD_SEGMENT, *PXENVBD_SEGMENT;
 
 // Internal request context
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index fd8621d..37b9a2f 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -48,7 +48,6 @@
 #include "frontend.h"
 #include "queue.h"
 #include "srbext.h"
-#include "buffer.h"
 
 #include "debug.h"
 #include "assert.h"
diff --git a/vs2015/xenvbd/xenvbd.vcxproj b/vs2015/xenvbd/xenvbd.vcxproj
index d5b812b..a85e65b 100644
--- a/vs2015/xenvbd/xenvbd.vcxproj
+++ b/vs2015/xenvbd/xenvbd.vcxproj
@@ -64,7 +64,6 @@
     <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" 
/>
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="../../src/xenvbd/buffer.c" />
     <ClCompile Include="../../src/xenvbd/driver.c" />
     <ClCompile Include="../../src/xenvbd/registry.c" />
     <ClCompile Include="../../src/xenvbd/adapter.c" />
-- 
2.8.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://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®.