Version: 1
-Previous: ef5ac51c0b30cab7a725fd38fa7f975c412e93dc
+Previous: a0ec2a7eb517e12e195cf78d168e3c383ec32878
Head: d6d2302f2d258fa2c07e55a2e124a9bdd75367a0
Applied:
rm-build: d6d2302f2d258fa2c07e55a2e124a9bdd75367a0
old-apphang: 7a6f7ff02c6035e54fc262414eb9484ea98018b9
old-cm_send_cb: 70dceed7518c8429e4c9e0646c7ec035f1cf53cb
old-queue_mads: a9c572c34ae693764a33e87173125d3065a6d1c5
- epdisc: 4c931f6af5e37a502f7a10b78a902747f9738623
+ old-epdisc: 4c931f6af5e37a502f7a10b78a902747f9738623
Hidden:
+++ /dev/null
-Bottom: 49ad94abc1f95efc4958f44965ae67c9be6bf494
-Top: 5470a0744b804e31f34e5b956cd5294f3da4023f
-Author: U-AMR\MSHEFTY <MSHEFTY@mshefty-MOBL2.amr.corp.intel.com>
-Date: 2009-12-04 10:52:48 -0800
-
-winverbs/ep: fix race handling DREQ initiated from either side
-
-When Disconnect is called, the EP state is checked first outside
-of any locks to determine if the disconnect should be processed as
-an active disconnect (and send the DREQ) or a passive disconnect
-(and send the DREP). Once that determination is made, the code
-will recheck the EP state under lock. However, a DREQ could have
-been received between the two state checks. The result is that
-the second state check will find that the EP is no longer in the
-correct state and fail the Disconnect request.
-
-If an app checks the Disconnect return value, it will see the failure.
-The ndconn sample test does this, which results in the test aborting
-when this condition is met. Fix the race by always checking the
-EP state under locks. First try to take the active role of
-disconnecting (send the DREQ), and if that fails, fall back to
-being passive (send the DREP).
-
-With this change, the ndconn test is able to make further progress.
-
-Signed-off-by: Sean Hefty <sean.hefty@intel.com>
-
-
----
-
-diff --git a/trunk/core/winverbs/kernel/wv_ep.c b/trunk/core/winverbs/kernel/wv_ep.c
-index 2fbb5b3..3d6dece 100644
---- a/trunk/core/winverbs/kernel/wv_ep.c
-+++ b/trunk/core/winverbs/kernel/wv_ep.c
-@@ -932,22 +932,27 @@ complete:
- WdfRequestComplete(Request, status);\r
- }\r
- \r
-+// The IB CM could have received and processed a DREQ that we haven't seen yet.\r
- static NTSTATUS WvEpDisconnectActive(WDFREQUEST Request,\r
-- UINT8 *pVerbsData, size_t VerbsSize,\r
-- WV_ENDPOINT *pEndpoint,\r
-- WV_IO_EP_DISCONNECT *pAttr)\r
-+ UINT8 *pVerbsData, size_t VerbsSize,\r
-+ WV_ENDPOINT *pEndpoint,\r
-+ WV_IO_EP_DISCONNECT *pAttr)\r
- {\r
- NTSTATUS status, failure;\r
- \r
- WdfObjectAcquireLock(pEndpoint->Queue);\r
-- if (pEndpoint->State != WvEpConnected) {\r
-- status = STATUS_NOT_SUPPORTED;\r
-+ if (pEndpoint->State == WvEpConnected) {\r
-+ status = IbCmInterface.CM.send_dreq(pEndpoint->pIbCmId, NULL, 0);\r
-+ if (status == STATUS_INVALID_DEVICE_STATE) {\r
-+ pEndpoint->State = WvEpPassiveDisconnect;\r
-+ goto release;\r
-+ }\r
-+ pEndpoint->State = WvEpActiveDisconnect;\r
-+ } else {\r
-+ status = STATUS_INVALID_DEVICE_STATE;\r
- goto release;\r
- }\r
- \r
-- pEndpoint->State = WvEpActiveDisconnect;\r
-- IbCmInterface.CM.send_dreq(pEndpoint->pIbCmId, NULL, 0);\r
--\r
- status = WdfRequestForwardToIoQueue(Request, pEndpoint->Queue);\r
- if (!NT_SUCCESS(status)) {\r
- pEndpoint->State = WvEpDisconnected;\r
-@@ -1020,20 +1025,12 @@ void WvEpDisconnect(WV_PROVIDER *pProvider, WDFREQUEST Request)
- goto complete;\r
- }\r
- \r
-- /* EP state is re-checked under lock in WvEpDisconnect* calls */\r
-- switch (ep->State) {\r
-- case WvEpConnected:\r
-- status = WvEpDisconnectActive(Request, out, outlen, ep, pattr);\r
-- break;\r
-- case WvEpPassiveDisconnect:\r
-+ status = WvEpDisconnectActive(Request, out, outlen, ep, pattr);\r
-+ if (status == STATUS_INVALID_DEVICE_STATE) {\r
- status = WvEpDisconnectPassive(Request, out, outlen, ep, pattr);\r
-- break;\r
-- default:\r
-- status = STATUS_NOT_SUPPORTED;\r
-- break;\r
- }\r
--\r
- WvEpRelease(ep);\r
-+\r
- complete:\r
- if (!NT_SUCCESS(status)) {\r
- WdfRequestComplete(Request, status);
--- /dev/null
+Bottom: 49ad94abc1f95efc4958f44965ae67c9be6bf494
+Top: 5470a0744b804e31f34e5b956cd5294f3da4023f
+Author: U-AMR\MSHEFTY <MSHEFTY@mshefty-MOBL2.amr.corp.intel.com>
+Date: 2009-12-04 10:52:48 -0800
+
+winverbs/ep: fix race handling DREQ initiated from either side
+
+When Disconnect is called, the EP state is checked first outside
+of any locks to determine if the disconnect should be processed as
+an active disconnect (and send the DREQ) or a passive disconnect
+(and send the DREP). Once that determination is made, the code
+will recheck the EP state under lock. However, a DREQ could have
+been received between the two state checks. The result is that
+the second state check will find that the EP is no longer in the
+correct state and fail the Disconnect request.
+
+If an app checks the Disconnect return value, it will see the failure.
+The ndconn sample test does this, which results in the test aborting
+when this condition is met. Fix the race by always checking the
+EP state under locks. First try to take the active role of
+disconnecting (send the DREQ), and if that fails, fall back to
+being passive (send the DREP).
+
+With this change, the ndconn test is able to make further progress.
+
+Signed-off-by: Sean Hefty <sean.hefty@intel.com>
+
+
+---
+
+diff --git a/trunk/core/winverbs/kernel/wv_ep.c b/trunk/core/winverbs/kernel/wv_ep.c
+index 2fbb5b3..3d6dece 100644
+--- a/trunk/core/winverbs/kernel/wv_ep.c
++++ b/trunk/core/winverbs/kernel/wv_ep.c
+@@ -932,22 +932,27 @@ complete:
+ WdfRequestComplete(Request, status);\r
+ }\r
+ \r
++// The IB CM could have received and processed a DREQ that we haven't seen yet.\r
+ static NTSTATUS WvEpDisconnectActive(WDFREQUEST Request,\r
+- UINT8 *pVerbsData, size_t VerbsSize,\r
+- WV_ENDPOINT *pEndpoint,\r
+- WV_IO_EP_DISCONNECT *pAttr)\r
++ UINT8 *pVerbsData, size_t VerbsSize,\r
++ WV_ENDPOINT *pEndpoint,\r
++ WV_IO_EP_DISCONNECT *pAttr)\r
+ {\r
+ NTSTATUS status, failure;\r
+ \r
+ WdfObjectAcquireLock(pEndpoint->Queue);\r
+- if (pEndpoint->State != WvEpConnected) {\r
+- status = STATUS_NOT_SUPPORTED;\r
++ if (pEndpoint->State == WvEpConnected) {\r
++ status = IbCmInterface.CM.send_dreq(pEndpoint->pIbCmId, NULL, 0);\r
++ if (status == STATUS_INVALID_DEVICE_STATE) {\r
++ pEndpoint->State = WvEpPassiveDisconnect;\r
++ goto release;\r
++ }\r
++ pEndpoint->State = WvEpActiveDisconnect;\r
++ } else {\r
++ status = STATUS_INVALID_DEVICE_STATE;\r
+ goto release;\r
+ }\r
+ \r
+- pEndpoint->State = WvEpActiveDisconnect;\r
+- IbCmInterface.CM.send_dreq(pEndpoint->pIbCmId, NULL, 0);\r
+-\r
+ status = WdfRequestForwardToIoQueue(Request, pEndpoint->Queue);\r
+ if (!NT_SUCCESS(status)) {\r
+ pEndpoint->State = WvEpDisconnected;\r
+@@ -1020,20 +1025,12 @@ void WvEpDisconnect(WV_PROVIDER *pProvider, WDFREQUEST Request)
+ goto complete;\r
+ }\r
+ \r
+- /* EP state is re-checked under lock in WvEpDisconnect* calls */\r
+- switch (ep->State) {\r
+- case WvEpConnected:\r
+- status = WvEpDisconnectActive(Request, out, outlen, ep, pattr);\r
+- break;\r
+- case WvEpPassiveDisconnect:\r
++ status = WvEpDisconnectActive(Request, out, outlen, ep, pattr);\r
++ if (status == STATUS_INVALID_DEVICE_STATE) {\r
+ status = WvEpDisconnectPassive(Request, out, outlen, ep, pattr);\r
+- break;\r
+- default:\r
+- status = STATUS_NOT_SUPPORTED;\r
+- break;\r
+ }\r
+-\r
+ WvEpRelease(ep);\r
++\r
+ complete:\r
+ if (!NT_SUCCESS(status)) {\r
+ WdfRequestComplete(Request, status);