[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

 


Rackspace

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