datapath-windows: Incorrect assumption of the IRQL
authorSorin Vinturis <svinturis@cloudbasesolutions.com>
Mon, 6 Oct 2014 15:19:23 +0000 (15:19 +0000)
committerBen Pfaff <blp@nicira.com>
Mon, 6 Oct 2014 22:35:11 +0000 (15:35 -0700)
Acquiring a spin lock raises the IRQL to DISPATCH_LEVEL. But
in many places of the code, while holding a spin lock, there
are useless checks for the current IRQL against DISPATCH_LEVEL.
Also, the dispatch flag is not correctly set when calling
NdisAcquireRWLockXXX() functions, which causes an extra check
of the current IRQL.

Signed-off-by: Sorin Vinturis <svinturis@cloudbasesolutions.com>
Reported-by: Sorin Vinturis <svinturis@cloudbasesolutions.com>
Reported-at: https://github.com/openvswitch/ovs-issues/issues/47
Acked-by: Nithin Raju <nithin@vmware.com>
Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
Acked-by: Eitan Eliahu <eliahue@vmware.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
datapath-windows/ovsext/Datapath.c
datapath-windows/ovsext/Flow.c
datapath-windows/ovsext/PacketIO.c

index e2d89a6..6e7a298 100644 (file)
@@ -1389,8 +1389,9 @@ OvsGetVportDumpNext(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
      * it means we have an array of pids, instead of a single pid.
      * ATM we assume we have one pid only.
     */
-
-    NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState, 0);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState,
+        NDIS_RWL_AT_DISPATCH_LEVEL);
 
     if (gOvsSwitchContext->numVports > 0) {
         /* inBucket: the bucket, used for lookup */
index ebcf005..50fa954 100644 (file)
@@ -1935,7 +1935,8 @@ OvsDoDumpFlows(OvsFlowDumpInput *dumpInput,
 
     datapath = &gOvsSwitchContext->datapath;
     ASSERT(datapath);
-    OvsAcquireDatapathRead(datapath, &dpLockState, FALSE);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    OvsAcquireDatapathRead(datapath, &dpLockState, TRUE);
 
     head = &datapath->flowTable[rowIndex];
     node = head->Flink;
@@ -2077,7 +2078,8 @@ OvsPutFlowIoctl(PVOID inputBuffer,
 
     datapath = &gOvsSwitchContext->datapath;
     ASSERT(datapath);
-    OvsAcquireDatapathWrite(datapath, &dpLockState, FALSE);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    OvsAcquireDatapathWrite(datapath, &dpLockState, TRUE);
     status = HandleFlowPut(put, datapath, stats);
     OvsReleaseDatapath(datapath, &dpLockState);
 
@@ -2256,7 +2258,8 @@ OvsGetFlowIoctl(PVOID inputBuffer,
 
     datapath = &gOvsSwitchContext->datapath;
     ASSERT(datapath);
-    OvsAcquireDatapathRead(datapath, &dpLockState, FALSE);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    OvsAcquireDatapathRead(datapath, &dpLockState, TRUE);
     flow = OvsLookupFlow(datapath, &getInput->key, &hash, FALSE);
     if (!flow) {
         status = STATUS_INVALID_PARAMETER;
@@ -2289,7 +2292,8 @@ OvsFlushFlowIoctl(UINT32 dpNo)
 
     datapath = &gOvsSwitchContext->datapath;
     ASSERT(datapath);
-    OvsAcquireDatapathWrite(datapath, &dpLockState, FALSE);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    OvsAcquireDatapathWrite(datapath, &dpLockState, TRUE);
     DeleteAllFlows(datapath);
     OvsReleaseDatapath(datapath, &dpLockState);
 
index ac7862d..87d7037 100644 (file)
@@ -268,7 +268,7 @@ OvsStartNBLIngress(POVS_SWITCH_CONTEXT switchContext,
             }
 
             ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-            OvsAcquireDatapathRead(datapath, &dpLockState, dispatch);
+            OvsAcquireDatapathRead(datapath, &dpLockState, TRUE);
 
             flow = OvsLookupFlow(datapath, &key, &hash, FALSE);
             if (flow) {