summaryrefslogtreecommitdiff
path: root/datapath-windows
diff options
context:
space:
mode:
authorSorin Vinturis <svinturis@cloudbasesolutions.com>2016-04-07 11:21:12 +0000
committerBen Pfaff <blp@ovn.org>2016-04-10 12:43:45 -0700
commit811c911ff523b0cbba4fbf1b4523a63690d522f1 (patch)
tree7f186e73612ee86e5f3252777f6f225788230ddd /datapath-windows
parent6982ee960e47616f4bd5178d94740e81feaea26c (diff)
downloadopenvswitch-811c911ff523b0cbba4fbf1b4523a63690d522f1.tar.gz
datapath-windows: Hot add CPU support.
Hot add CPU is the ability to dynamically add CPUs to a running system. Adding CPUs can occur physically by adding new hardware, logically by online hardware partitioning, or virtually through a virtualization layer. This patch add support to reallocate any per-cpu resources, in case a new processor is added. Signed-off-by: Sorin Vinturis <svinturis@cloudbasesolutions.com> Reported-by: Sorin Vinturis <svinturis@cloudbasesolutions.com> Reported-at: https://github.com/openvswitch/ovs-issues/issues/112 Acked-by: Paul-Daniel Boca <pboca@cloudbasesolutions.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'datapath-windows')
-rw-r--r--datapath-windows/ovsext/Datapath.c13
-rw-r--r--datapath-windows/ovsext/Datapath.h2
-rw-r--r--datapath-windows/ovsext/Driver.c11
-rw-r--r--datapath-windows/ovsext/Recirc.c100
-rw-r--r--datapath-windows/ovsext/Recirc.h45
-rw-r--r--datapath-windows/ovsext/Util.c34
-rw-r--r--datapath-windows/ovsext/Util.h20
7 files changed, 117 insertions, 108 deletions
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 464fa9784..8c0c246a5 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -379,26 +379,29 @@ FreeUserDumpState(POVS_OPEN_INSTANCE instance)
}
}
-VOID
+NDIS_STATUS
OvsInit()
{
+ NDIS_STATUS status = NDIS_STATUS_SUCCESS;
+
gOvsCtrlLock = &ovsCtrlLockObj;
NdisAllocateSpinLock(gOvsCtrlLock);
OvsInitEventQueue();
- OvsDeferredActionsQueueAlloc();
- OvsDeferredActionsLevelAlloc();
+
+ status = OvsPerCpuDataInit();
+
+ return status;
}
VOID
OvsCleanup()
{
+ OvsPerCpuDataCleanup();
OvsCleanupEventQueue();
if (gOvsCtrlLock) {
NdisFreeSpinLock(gOvsCtrlLock);
gOvsCtrlLock = NULL;
}
- OvsDeferredActionsQueueFree();
- OvsDeferredActionsLevelFree();
}
VOID
diff --git a/datapath-windows/ovsext/Datapath.h b/datapath-windows/ovsext/Datapath.h
index 2c61d8217..09e233fd3 100644
--- a/datapath-windows/ovsext/Datapath.h
+++ b/datapath-windows/ovsext/Datapath.h
@@ -65,7 +65,7 @@ typedef struct _OVS_OPEN_INSTANCE {
NDIS_STATUS OvsCreateDeviceObject(NDIS_HANDLE ovsExtDriverHandle);
VOID OvsDeleteDeviceObject();
-VOID OvsInit();
+NDIS_STATUS OvsInit();
VOID OvsCleanup();
POVS_OPEN_INSTANCE OvsGetOpenInstance(PFILE_OBJECT fileObject,
diff --git a/datapath-windows/ovsext/Driver.c b/datapath-windows/ovsext/Driver.c
index 853886e2e..80979ea61 100644
--- a/datapath-windows/ovsext/Driver.c
+++ b/datapath-windows/ovsext/Driver.c
@@ -96,7 +96,10 @@ DriverEntry(PDRIVER_OBJECT driverObject,
UNREFERENCED_PARAMETER(registryPath);
/* Initialize driver associated data structures. */
- OvsInit();
+ status = OvsInit();
+ if (status != NDIS_STATUS_SUCCESS) {
+ goto cleanup;
+ }
gOvsExtDriverObject = driverObject;
@@ -175,12 +178,12 @@ OvsExtUnload(struct _DRIVER_OBJECT *driverObject)
{
UNREFERENCED_PARAMETER(driverObject);
- /* Release driver associated data structures. */
- OvsCleanup();
-
OvsDeleteDeviceObject();
NdisFDeregisterFilterDriver(gOvsExtDriverHandle);
+
+ /* Release driver associated data structures. */
+ OvsCleanup();
}
diff --git a/datapath-windows/ovsext/Recirc.c b/datapath-windows/ovsext/Recirc.c
index 86e6f51df..2febf060d 100644
--- a/datapath-windows/ovsext/Recirc.c
+++ b/datapath-windows/ovsext/Recirc.c
@@ -18,71 +18,61 @@
#include "Flow.h"
#include "Jhash.h"
-static POVS_DEFERRED_ACTION_QUEUE ovsDeferredActionQueue = NULL;
-static UINT32* ovsDeferredActionLevel = NULL;
-
/*
* --------------------------------------------------------------------------
- * OvsDeferredActionsQueueAlloc --
- * The function allocates per-cpu deferred actions queue.
+ * '_OVS_DEFERRED_ACTION_QUEUE' structure is responsible for keeping track of
+ * all deferred actions. The maximum number of deferred actions should not
+ * exceed 'DEFERRED_ACTION_QUEUE_SIZE'.
* --------------------------------------------------------------------------
*/
-BOOLEAN
-OvsDeferredActionsQueueAlloc()
-{
- ovsDeferredActionQueue =
- OvsAllocateMemoryPerCpu(sizeof(*ovsDeferredActionQueue),
- OVS_RECIRC_POOL_TAG);
- if (!ovsDeferredActionQueue) {
- return FALSE;
- }
- return TRUE;
-}
+typedef struct _OVS_DEFERRED_ACTION_QUEUE {
+ UINT32 head;
+ UINT32 tail;
+ OVS_DEFERRED_ACTION deferredActions[DEFERRED_ACTION_QUEUE_SIZE];
+} OVS_DEFERRED_ACTION_QUEUE, *POVS_DEFERRED_ACTION_QUEUE;
-/*
- * --------------------------------------------------------------------------
- * OvsDeferredActionsQueueFree --
- * The function frees per-cpu deferred actions queue.
- * --------------------------------------------------------------------------
- */
-VOID
-OvsDeferredActionsQueueFree()
-{
- OvsFreeMemoryWithTag(ovsDeferredActionQueue,
- OVS_RECIRC_POOL_TAG);
- ovsDeferredActionQueue = NULL;
-}
+typedef struct _OVS_DEFERRED_ACTION_DATA {
+ OVS_DEFERRED_ACTION_QUEUE queue;
+ UINT32 level;
+} OVS_DEFERRED_ACTION_DATA, *POVS_DEFERRED_ACTION_DATA;
+
+static POVS_DEFERRED_ACTION_DATA deferredData = NULL;
/*
* --------------------------------------------------------------------------
- * OvsDeferredActionsLevelAlloc --
- * The function allocates per-cpu deferred actions execution level.
+ * OvsDeferredActionsInit --
+ * The function allocates all necessary deferred actions resources.
* --------------------------------------------------------------------------
*/
-BOOLEAN
-OvsDeferredActionsLevelAlloc()
+NTSTATUS
+OvsDeferredActionsInit()
{
- ovsDeferredActionLevel =
- OvsAllocateMemoryPerCpu(sizeof(*ovsDeferredActionLevel),
- OVS_RECIRC_POOL_TAG);
- if (!ovsDeferredActionLevel) {
- return FALSE;
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG count = KeQueryMaximumProcessorCountEx(ALL_PROCESSOR_GROUPS);
+
+ deferredData = OvsAllocateMemoryPerCpu(sizeof(*deferredData),
+ count,
+ OVS_RECIRC_POOL_TAG);
+ if (!deferredData) {
+ status = NDIS_STATUS_RESOURCES;
}
- return TRUE;
+
+ return status;
}
/*
* --------------------------------------------------------------------------
- * OvsDeferredActionsLevelFree --
- * The function frees per-cpu deferred actions execution level.
+ * OvsDeferredActionsCleanup --
+ * The function frees all deferred actions resources.
* --------------------------------------------------------------------------
*/
VOID
-OvsDeferredActionsLevelFree()
+OvsDeferredActionsCleanup()
{
- OvsFreeMemoryWithTag(ovsDeferredActionLevel,
- OVS_RECIRC_POOL_TAG);
- ovsDeferredActionLevel = NULL;
+ if (deferredData) {
+ OvsFreeMemoryWithTag(deferredData, OVS_RECIRC_POOL_TAG);
+ deferredData = NULL;
+ }
}
/*
@@ -104,7 +94,7 @@ OvsDeferredActionsQueueGet()
}
index = KeGetCurrentProcessorNumberEx(NULL);
- queue = &ovsDeferredActionQueue[index];
+ queue = &deferredData[index].queue;
if (oldIrql < DISPATCH_LEVEL) {
KeLowerIrql(oldIrql);
@@ -123,7 +113,7 @@ OvsDeferredActionsQueueGet()
UINT32
OvsDeferredActionsLevelGet()
{
- UINT32 *level = NULL;
+ UINT32 level = 0;
ULONG index = 0;
KIRQL oldIrql = KeGetCurrentIrql();
@@ -132,13 +122,13 @@ OvsDeferredActionsLevelGet()
}
index = KeGetCurrentProcessorNumberEx(NULL);
- level = &ovsDeferredActionLevel[index];
+ level = deferredData[index].level;
if (oldIrql < DISPATCH_LEVEL) {
KeLowerIrql(oldIrql);
}
- return *level;
+ return level;
}
/*
@@ -151,7 +141,6 @@ OvsDeferredActionsLevelGet()
VOID
OvsDeferredActionsLevelInc()
{
- UINT32 *level = NULL;
ULONG index = 0;
KIRQL oldIrql = KeGetCurrentIrql();
@@ -160,8 +149,7 @@ OvsDeferredActionsLevelInc()
}
index = KeGetCurrentProcessorNumberEx(NULL);
- level = &ovsDeferredActionLevel[index];
- (*level)++;
+ deferredData[index].level++;
if (oldIrql < DISPATCH_LEVEL) {
KeLowerIrql(oldIrql);
@@ -178,7 +166,6 @@ OvsDeferredActionsLevelInc()
VOID
OvsDeferredActionsLevelDec()
{
- UINT32 *level = NULL;
ULONG index = 0;
KIRQL oldIrql = KeGetCurrentIrql();
@@ -187,8 +174,7 @@ OvsDeferredActionsLevelDec()
}
index = KeGetCurrentProcessorNumberEx(NULL);
- level = &ovsDeferredActionLevel[index];
- (*level)--;
+ deferredData[index].level--;
if (oldIrql < DISPATCH_LEVEL) {
KeLowerIrql(oldIrql);
@@ -243,7 +229,7 @@ OvsDeferredActionsQueuePop(POVS_DEFERRED_ACTION_QUEUE queue)
/* Reset the queue for the next packet. */
OvsDeferredActionsQueueInit(queue);
} else {
- deferredAction = &queue->queue[queue->tail++];
+ deferredAction = &queue->deferredActions[queue->tail++];
}
if (oldIrql < DISPATCH_LEVEL) {
@@ -271,7 +257,7 @@ OvsDeferredActionsQueuePush(POVS_DEFERRED_ACTION_QUEUE queue)
}
if (queue->head < DEFERRED_ACTION_QUEUE_SIZE) {
- deferredAction = &queue->queue[queue->head++];
+ deferredAction = &queue->deferredActions[queue->head++];
}
if (oldIrql < DISPATCH_LEVEL) {
diff --git a/datapath-windows/ovsext/Recirc.h b/datapath-windows/ovsext/Recirc.h
index ee0576347..2b314ce27 100644
--- a/datapath-windows/ovsext/Recirc.h
+++ b/datapath-windows/ovsext/Recirc.h
@@ -30,19 +30,6 @@ typedef struct _OVS_DEFERRED_ACTION {
/*
* --------------------------------------------------------------------------
- * '_OVS_DEFERRED_ACTION_QUEUE' structure is responsible for keeping track of
- * all deferred actions. The maximum number of deferred actions should not
- * exceed 'DEFERRED_ACTION_QUEUE_SIZE'.
- * --------------------------------------------------------------------------
- */
-typedef struct _OVS_DEFERRED_ACTION_QUEUE {
- UINT32 head;
- UINT32 tail;
- OVS_DEFERRED_ACTION queue[DEFERRED_ACTION_QUEUE_SIZE];
-} OVS_DEFERRED_ACTION_QUEUE, *POVS_DEFERRED_ACTION_QUEUE;
-
-/*
- * --------------------------------------------------------------------------
* OvsProcessDeferredActions --
* This function processes all deferred actions contained in the queue
* corresponding to the current CPU.
@@ -69,39 +56,21 @@ OvsAddDeferredActions(PNET_BUFFER_LIST packet,
/*
* --------------------------------------------------------------------------
- * OvsDeferredActionsQueueAlloc --
- * The function allocates per-cpu deferred actions queue.
- * --------------------------------------------------------------------------
- */
-BOOLEAN
-OvsDeferredActionsQueueAlloc();
-
-/*
- * --------------------------------------------------------------------------
- * OvsDeferredActionsQueueFree --
- * The function frees per-cpu deferred actions queue.
- * --------------------------------------------------------------------------
- */
-VOID
-OvsDeferredActionsQueueFree();
-
-/*
- * --------------------------------------------------------------------------
- * OvsDeferredActionsLevelAlloc --
- * The function allocates per-cpu deferred actions execution level.
+ * OvsDeferredActionsInit --
+ * The function allocates all necessary deferred actions resources.
* --------------------------------------------------------------------------
*/
-BOOLEAN
-OvsDeferredActionsLevelAlloc();
+NTSTATUS
+OvsDeferredActionsInit();
/*
* --------------------------------------------------------------------------
- * OvsDeferredActionsLevelFree --
- * The function frees per-cpu deferred actions execution level.
+ * OvsDeferredActionsCleanup --
+ * The function frees all deferred actions resources.
* --------------------------------------------------------------------------
*/
VOID
-OvsDeferredActionsLevelFree();
+OvsDeferredActionsCleanup();
/*
* --------------------------------------------------------------------------
diff --git a/datapath-windows/ovsext/Util.c b/datapath-windows/ovsext/Util.c
index 14c4493b0..a1ce0e6f4 100644
--- a/datapath-windows/ovsext/Util.c
+++ b/datapath-windows/ovsext/Util.c
@@ -15,6 +15,7 @@
*/
#include "precomp.h"
+#include "Recirc.h"
#ifdef OVS_DBG_MOD
#undef OVS_DBG_MOD
#endif
@@ -118,13 +119,18 @@ OvsCompareString(PVOID string1, PVOID string2)
}
VOID *
-OvsAllocateMemoryPerCpu(size_t size, ULONG tag)
+OvsAllocateMemoryPerCpu(size_t size,
+ size_t count,
+ ULONG tag)
{
VOID *ptr = NULL;
- ULONG count = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
ASSERT(KeQueryActiveGroupCount() == 1);
+ if (!count) {
+ count = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
+ }
+
ptr = OvsAllocateMemoryWithTag(count * size, tag);
if (ptr) {
RtlZeroMemory(ptr, count * size);
@@ -132,3 +138,27 @@ OvsAllocateMemoryPerCpu(size_t size, ULONG tag)
return ptr;
}
+
+/*
+ * --------------------------------------------------------------------------
+ * OvsPerCpuDataInit --
+ * The function allocates necessary per-processor resources.
+ * --------------------------------------------------------------------------
+ */
+NTSTATUS
+OvsPerCpuDataInit()
+{
+ return OvsDeferredActionsInit();
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * OvsPerCpuDataCleanup --
+ * The function frees all per-processor resources.
+ * --------------------------------------------------------------------------
+ */
+VOID
+OvsPerCpuDataCleanup()
+{
+ OvsDeferredActionsCleanup();
+}
diff --git a/datapath-windows/ovsext/Util.h b/datapath-windows/ovsext/Util.h
index 038754dd0..78b926d3b 100644
--- a/datapath-windows/ovsext/Util.h
+++ b/datapath-windows/ovsext/Util.h
@@ -41,7 +41,7 @@
VOID *OvsAllocateMemory(size_t size);
VOID *OvsAllocateMemoryWithTag(size_t size, ULONG tag);
VOID *OvsAllocateAlignedMemory(size_t size, UINT16 align);
-VOID *OvsAllocateMemoryPerCpu(size_t size, ULONG tag);
+VOID *OvsAllocateMemoryPerCpu(size_t size, size_t count, ULONG tag);
VOID OvsFreeMemory(VOID *ptr);
VOID OvsFreeMemoryWithTag(VOID *ptr, ULONG tag);
VOID OvsFreeAlignedMemory(VOID *ptr);
@@ -94,4 +94,22 @@ VOID OvsAppendList(PLIST_ENTRY dst, PLIST_ENTRY src);
BOOLEAN OvsCompareString(PVOID string1, PVOID string2);
+/*
+ * --------------------------------------------------------------------------
+ * OvsPerCpuDataInit --
+ * The function allocates necessary per-processor resources.
+ * --------------------------------------------------------------------------
+ */
+NTSTATUS
+OvsPerCpuDataInit();
+
+/*
+ * --------------------------------------------------------------------------
+ * OvsPerCpuDataCleanup --
+ * The function frees all per-processor resources.
+ * --------------------------------------------------------------------------
+ */
+VOID
+OvsPerCpuDataCleanup();
+
#endif /* __UTIL_H_ */