[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |