summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Switch.c
diff options
context:
space:
mode:
authorSorin Vinturis <svinturis@cloudbasesolutions.com>2015-04-07 16:35:54 +0000
committerGurucharan Shetty <gshetty@nicira.com>2015-04-07 15:24:38 -0700
commit6c4e7adb0807155b603eef30a7929c42667bfa38 (patch)
treebc21b8f41540477578c5274f695723f2d391caca /datapath-windows/ovsext/Switch.c
parentf293a803d9ece7157ec5d098deb1bf29e5de5915 (diff)
downloadopenvswitch-6c4e7adb0807155b603eef30a7929c42667bfa38.tar.gz
datapath-windows: Solved BSOD when uninstalling the driver (race condition)
The BSOD occurred because the FilterAttach routine released the switch context, while there were IRPs in processing. The solution was to add a reference count to prevent premature deallocation of the global switch context structure, gOvsSwitchContext. Signed-off-by: Sorin Vinturis <svinturis@cloudbasesolutions.com> Reported-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Reported-at: https://github.com/openvswitch/ovs-issues/issues/58 Acked-by: Eitan Eliahu <eliahue@vmware.com> Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Diffstat (limited to 'datapath-windows/ovsext/Switch.c')
-rw-r--r--datapath-windows/ovsext/Switch.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c
index 61a453183..4f4591fca 100644
--- a/datapath-windows/ovsext/Switch.c
+++ b/datapath-windows/ovsext/Switch.c
@@ -42,6 +42,12 @@ extern PNDIS_SPIN_LOCK gOvsCtrlLock;
extern NDIS_HANDLE gOvsExtDriverHandle;
extern NDIS_HANDLE gOvsExtDriverObject;
+/*
+ * Reference count used to prevent premature deallocation of the global switch
+ * context structure, gOvsSwitchContext.
+ */
+volatile LONG gOvsSwitchContextRefCount = 1;
+
static NDIS_STATUS OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle,
POVS_SWITCH_CONTEXT *switchContextOut);
static NDIS_STATUS OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext);
@@ -423,6 +429,7 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
switchContext->isActivateFailed = FALSE;
switchContext->dpNo = OVS_DP_NUMBER;
ovsTimeIncrementPerTick = KeQueryTimeIncrement() / 10000;
+
OVS_LOG_TRACE("Exit: Succesfully initialized switchContext: %p",
switchContext);
return NDIS_STATUS_SUCCESS;
@@ -431,6 +438,12 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
static VOID
OvsUninitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
{
+ OvsReleaseSwitchContext(switchContext);
+}
+
+VOID
+OvsDeleteSwitchContext(POVS_SWITCH_CONTEXT switchContext)
+{
OVS_LOG_TRACE("Enter: Delete switchContext:%p", switchContext);
/* We need to do cleanup for tunnel port here. */
@@ -457,6 +470,49 @@ OvsUninitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
OVS_LOG_TRACE("Exit: Delete switchContext: %p", switchContext);
}
+VOID
+OvsReleaseSwitchContext(POVS_SWITCH_CONTEXT switchContext)
+{
+ LONG ref = 0;
+ LONG newRef = 0;
+ LONG icxRef = 0;
+
+ do {
+ ref = gOvsSwitchContextRefCount;
+ newRef = (0 == ref) ? 0 : ref - 1;
+ icxRef = InterlockedCompareExchange(&gOvsSwitchContextRefCount,
+ newRef,
+ ref);
+ } while (icxRef != ref);
+
+ if (ref == 1) {
+ OvsDeleteSwitchContext(switchContext);
+ }
+}
+
+BOOLEAN
+OvsAcquireSwitchContext(VOID)
+{
+ LONG ref = 0;
+ LONG newRef = 0;
+ LONG icxRef = 0;
+ BOOLEAN ret = FALSE;
+
+ do {
+ ref = gOvsSwitchContextRefCount;
+ newRef = (0 == ref) ? 0 : ref + 1;
+ icxRef = InterlockedCompareExchange(&gOvsSwitchContextRefCount,
+ newRef,
+ ref);
+ } while (icxRef != ref);
+
+ if (ref != 0) {
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
/*
* --------------------------------------------------------------------------
* This function activates the switch by initializing it with all the runtime