[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 2/5] Use CACHE interface for bounce buffers
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of owen.smith@xxxxxxxxxx > Sent: 26 September 2017 14:50 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith <owen.smith@xxxxxxxxxx> > Subject: [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> Reviewed-by: Paul Durrant <paul.durrant@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 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |