Version: 1
-Previous: 5955fd96bf9989ea4852a70477dcd88a5aec9967
+Previous: 83d1916c9bea4a5458fe2659fe31909261806de9
Head: 66cc200ece77ae6e35f97d834367a58a84c710cd
Applied:
- ep-disc: 66cc200ece77ae6e35f97d834367a58a84c710cd
+ epdisc: 66cc200ece77ae6e35f97d834367a58a84c710cd
Unapplied:
Hidden:
+++ /dev/null
-Bottom: 300b4541aa6ee170b44264a0c091ece4e17a9eba
-Top: 270c0464a4e35f6c3aca3fdf4148f6d997909cc7
-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: 300b4541aa6ee170b44264a0c091ece4e17a9eba
+Top: 270c0464a4e35f6c3aca3fdf4148f6d997909cc7
+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);