]> xenbits.xensource.com Git - people/pauldu/xennet.git/commitdiff
Query for cache interface
authorOwen Smith <owen.smith@citrix.com>
Thu, 18 Dec 2014 16:54:31 +0000 (16:54 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Mon, 22 Dec 2014 16:22:05 +0000 (16:22 +0000)
Signed-off-by: Owen Smith <owen.smith@citrix.com>
include/cache_interface.h [new file with mode: 0644]
src/xennet/adapter.c
src/xennet/adapter.h

diff --git a/include/cache_interface.h b/include/cache_interface.h
new file mode 100644 (file)
index 0000000..ac50a82
--- /dev/null
@@ -0,0 +1,233 @@
+/* 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.
+ */
+
+/*! \file cache_interface.h
+    \brief XENBUS CACHE Interface
+
+    This interface provides access to XENBUS's object cache
+    implementation.
+*/
+
+#ifndef _XENBUS_CACHE_INTERFACE_H
+#define _XENBUS_CACHE_INTERFACE_H
+
+#ifndef _WINDLL
+
+/*! \typedef XENBUS_CACHE
+    \brief Cache handle
+*/
+typedef struct _XENBUS_CACHE    XENBUS_CACHE, *PXENBUS_CACHE;
+
+/*! \typedef XENBUS_CACHE_ACQUIRE
+    \brief Acquire a reference to the CACHE interface
+
+    \param Interface The interface header
+*/
+typedef NTSTATUS
+(*XENBUS_CACHE_ACQUIRE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_CACHE_RELEASE
+    \brief Release a reference to the CACHE interface
+
+    \param Interface The interface header
+*/
+typedef VOID
+(*XENBUS_CACHE_RELEASE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_CACHE_CTOR
+    \brief Object creator callback
+
+    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+    \param Object Newly allocated object
+
+    This callback is invoked just after a new object is allocated and may
+    be used to initialize any object data prior to its insertion into the
+    cache.
+*/
+typedef NTSTATUS
+(*XENBUS_CACHE_CTOR)(
+    IN  PVOID   Argument,
+    IN  PVOID   Object
+    );
+
+/*! \typedef XENBUS_CACHE_DTOR
+    \brief Object destructor callback
+
+    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+    \param Object Object about to be freed
+
+    This callback is invoked just after an object is removed from the
+    cache and before it is freed and may be used to tear down any object data.
+*/
+typedef VOID
+(*XENBUS_CACHE_DTOR)(
+    IN  PVOID   Argument,
+    IN  PVOID   Object
+    );
+
+/*! \typedef XENBUS_CACHE_ACQUIRE_LOCK
+    \brief Cache lock callback
+
+    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+
+    This callback is invoked if the cache implementation requires mutual
+    exclusion.
+*/
+typedef VOID
+(*XENBUS_CACHE_ACQUIRE_LOCK)(
+    IN  PVOID   Argument
+    );
+
+/*! \typedef XENBUS_CACHE_RELEASE_LOCK
+    \brief Cache unlock callback
+
+    \param Argument Context \a Argument supplied to \a XENBUS_CACHE_CREATE
+
+    This callback is invoked to release the mutual exclusion lock acquired
+    by a previous invocation of \a XENBUS_CACHE_ACQUIRE_LOCK.
+*/
+typedef VOID
+(*XENBUS_CACHE_RELEASE_LOCK)(
+    IN  PVOID   Argument
+    );
+
+/*! \typedef XENBUS_CACHE_CREATE
+    \brief Create a cache of objects of the given \a Size
+
+    \param Interface The interface header
+    \param Name A name for the cache which will be used in debug output
+    \param Size The size of each object in bytes
+    \param Reservation The target minimum population of the cache
+    \param Ctor A callback which is invoked when a new object created
+    \param Dtor A callback which is invoked when an object is destroyed
+    \param AcquireLock A callback invoked to acquire a spinlock
+    \param ReleaseLock A callback invoked to release the spinlock
+    \param Argument An optional context argument passed to the callbacks
+    \param Cache A pointer to a cache handle to be initialized
+
+    If a non-zero \a Reservation is specified then this method will fail
+    unless that number of objects can be immediately created.
+*/
+typedef NTSTATUS
+(*XENBUS_CACHE_CREATE)(
+    IN  PINTERFACE                  Interface,
+    IN  const CHAR                  *Name,
+    IN  ULONG                       Size,
+    IN  ULONG                       Reservation,
+    IN  XENBUS_CACHE_CTOR           Ctor,
+    IN  XENBUS_CACHE_DTOR           Dtor,
+    IN  XENBUS_CACHE_ACQUIRE_LOCK   AcquireLock,
+    IN  XENBUS_CACHE_RELEASE_LOCK   ReleaseLock,
+    IN  PVOID                       Argument OPTIONAL,
+    OUT PXENBUS_CACHE               *Cache
+    );
+
+/*! \typedef XENBUS_CACHE_GET
+    \brief Get an object from a \a Cache
+
+    \param Interface The interface header
+    \param Cache The cache handle
+    \param Locked If mutually exclusive access to the cache is already
+    guaranteed then set this to TRUE
+*/
+typedef PVOID
+(*XENBUS_CACHE_GET)(
+    IN  PINTERFACE      Interface,
+    IN  PXENBUS_CACHE   Cache,
+    IN  BOOLEAN         Locked
+    );
+
+/*! \typedef XENBUS_CACHE_PUT
+    \brief Return an object to a \a Cache
+
+    \param Interface The interface header
+    \param Cache The cache handle
+    \param Locked If mutually exclusive access to the cache is already
+    guaranteed then set this to TRUE
+*/
+typedef VOID
+(*XENBUS_CACHE_PUT)(
+    IN  PINTERFACE      Interface,
+    IN  PXENBUS_CACHE   Cache,
+    IN  PVOID           Object,
+    IN  BOOLEAN         Locked
+    );
+
+/*! \typedef XENBUS_CACHE_DESTROY
+    \brief Destroy a \a Cache
+
+    \param Interface The interface header
+    \param Cache The cache handle
+
+    All objects must have been returned to the cache prior to destruction
+*/
+typedef VOID
+(*XENBUS_CACHE_DESTROY)(
+    IN  PINTERFACE      Interface,
+    IN  PXENBUS_CACHE   Cache
+    );
+
+// {A98DFD78-416A-4949-92A5-E084F2F4B44E}
+DEFINE_GUID(GUID_XENBUS_CACHE_INTERFACE,
+0xa98dfd78, 0x416a, 0x4949, 0x92, 0xa5, 0xe0, 0x84, 0xf2, 0xf4, 0xb4, 0x4e);
+
+/*! \struct _XENBUS_CACHE_INTERFACE_V1
+    \brief CACHE interface version 1
+    \ingroup interfaces
+*/
+struct _XENBUS_CACHE_INTERFACE_V1 {
+    INTERFACE               Interface;
+    XENBUS_CACHE_ACQUIRE    CacheAcquire;
+    XENBUS_CACHE_RELEASE    CacheRelease;
+    XENBUS_CACHE_CREATE     CacheCreate;
+    XENBUS_CACHE_GET        CacheGet;
+    XENBUS_CACHE_PUT        CachePut;
+    XENBUS_CACHE_DESTROY    CacheDestroy;
+};
+
+typedef struct _XENBUS_CACHE_INTERFACE_V1 XENBUS_CACHE_INTERFACE, *PXENBUS_CACHE_INTERFACE;
+
+/*! \def XENBUS_CACHE
+    \brief Macro at assist in method invocation
+*/
+#define XENBUS_CACHE(_Method, _Interface, ...)    \
+    (_Interface)->Cache ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif  // _WINDLL
+
+#define XENBUS_CACHE_INTERFACE_VERSION_MIN  1
+#define XENBUS_CACHE_INTERFACE_VERSION_MAX  1
+
+#endif  // _XENBUS_CACHE_INTERFACE_H
index f7199cf8d393a6f62ad6a17291269c9604704170..218e845b12938df748a9a640ed2d65e3a889381f 100644 (file)
 #include "transmitter.h"
 #include "receiver.h"
 #include <vif_interface.h>
+#include <cache_interface.h>
 #include <version.h>
 #include "dbg_print.h"
 #include "assert.h"
 
 struct _XENNET_ADAPTER {
     XENVIF_VIF_INTERFACE    VifInterface;
+    XENBUS_CACHE_INTERFACE  CacheInterface;
 
     ULONG                   MaximumFrameSize;
     ULONG                   CurrentLookahead;
@@ -921,6 +923,14 @@ AdapterGetVifInterface(
     return &Adapter->VifInterface;
 }
 
+PXENBUS_CACHE_INTERFACE
+AdapterGetCacheInterface(
+    IN  PXENNET_ADAPTER     Adapter
+    )
+{
+    return &Adapter->CacheInterface;
+}
+
 PXENNET_TRANSMITTER
 AdapterGetTransmitter(
     IN  PXENNET_ADAPTER     Adapter
@@ -2011,36 +2021,50 @@ AdapterInitialize(
     if (!NT_SUCCESS(status))
         goto fail2;
 
+    status = __QueryInterface(DeviceObject,
+                              &GUID_XENBUS_CACHE_INTERFACE,
+                              XENBUS_CACHE_INTERFACE_VERSION_MAX,
+                              (PINTERFACE)&(*Adapter)->CacheInterface,
+                              sizeof(XENBUS_CACHE_INTERFACE),
+                              FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
     status = XENVIF_VIF(Acquire,
                         &(*Adapter)->VifInterface);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail4;
+
+    status = XENBUS_CACHE(Acquire,
+                          &(*Adapter)->CacheInterface);
+    if (!NT_SUCCESS(status))
+        goto fail5;
 
     (*Adapter)->NdisAdapterHandle = Handle;
 
     ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail4;
+        goto fail6;
 
     ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail5;
+        goto fail7;
 
     ndisStatus = AdapterGetAdvancedSettings(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail6;
+        goto fail8;
 
     ndisStatus = AdapterSetRegistrationAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail7;
+        goto fail9;
 
     ndisStatus = AdapterSetGeneralAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail8;
+        goto fail10;
 
     ndisStatus = AdapterSetOffloadAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail9;
+        goto fail11;
 
     RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION));
     Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
@@ -2059,27 +2083,31 @@ AdapterInitialize(
 
     ndisStatus = AdapterEnable(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail10;
+        goto fail12;
 
     return NDIS_STATUS_SUCCESS;
 
-fail10:
+fail12:
     if ((*Adapter)->NdisDmaHandle)
         NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle);
     (*Adapter)->NdisDmaHandle = NULL;
+fail11:
+fail10:
 fail9:
 fail8:
-fail7:
-fail6:
     ReceiverTeardown((*Adapter)->Receiver);
     (*Adapter)->Receiver = NULL;
-fail5:
+fail7:
     TransmitterTeardown((*Adapter)->Transmitter);
     (*Adapter)->Transmitter = NULL;
-fail4:
+fail6:
     (*Adapter)->NdisAdapterHandle = NULL;
 
+    XENBUS_CACHE(Release, &(*Adapter)->CacheInterface);
+fail5:
     XENVIF_VIF(Release, &(*Adapter)->VifInterface);
+fail4:
+    RtlZeroMemory(&(*Adapter)->CacheInterface, sizeof(XENBUS_CACHE_INTERFACE));
 fail3:
     RtlZeroMemory(&(*Adapter)->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
 fail2:
@@ -2103,6 +2131,9 @@ AdapterTeardown(
         NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle);
     Adapter->NdisDmaHandle = NULL;
 
+    XENBUS_CACHE(Release, &Adapter->CacheInterface);
+    RtlZeroMemory(&Adapter->CacheInterface, sizeof(XENBUS_CACHE_INTERFACE));
+
     XENVIF_VIF(Release, &Adapter->VifInterface);
     RtlZeroMemory(&Adapter->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
 
index 6c60aadb3e94733cc429be4c12c179c9f3f8d6ec..042b863a265e9fa7bc5d1c6bde537fadabd3681a 100644 (file)
@@ -89,6 +89,12 @@ AdapterGetVifInterface(
     IN  PXENNET_ADAPTER     Adapter
     );
 
+#include <cache_interface.h>
+extern PXENBUS_CACHE_INTERFACE
+AdapterGetCacheInterface(
+    IN  PXENNET_ADAPTER     Adapter
+    );
+
 #include "transmitter.h"
 extern PXENNET_TRANSMITTER
 AdapterGetTransmitter(