diff options
author | Sorin Vinturis <svinturis@cloudbasesolutions.com> | 2015-04-07 16:35:54 +0000 |
---|---|---|
committer | Gurucharan Shetty <gshetty@nicira.com> | 2015-04-07 15:24:38 -0700 |
commit | 6c4e7adb0807155b603eef30a7929c42667bfa38 (patch) | |
tree | bc21b8f41540477578c5274f695723f2d391caca /datapath-windows/ovsext/Switch.c | |
parent | f293a803d9ece7157ec5d098deb1bf29e5de5915 (diff) | |
download | openvswitch-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.c | 56 |
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 |