[ofw] [PATCH] libibumad: add umad_cancel_recv

Hefty, Sean sean.hefty at intel.com
Thu Apr 28 11:29:26 PDT 2011


umad_recv is a blocking call.  Provide a routine that will
unblock any thread waiting in umad_recv.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
umad_cancel_recv is a Windows specific call, but it could easily be implemented
on Linux.  There really isn't a good way to handle this that doesn't end up
being OS specific.

I tested the compile and that the existing diags still ran okay, but did not
test this actual call.  You should be able to call this from opensm
umad_receiver_stop before trying to destroy the thread.  I don't know if
opensm requires other changes or how umad_receiver_stop gets invoked.

 trunk/ulp/libibumad/include/infiniband/umad.h |    2 ++
 trunk/ulp/libibumad/src/ibum_exports.src      |    1 +
 trunk/ulp/libibumad/src/umad.cpp              |   17 ++++++++++-------
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/trunk/ulp/libibumad/include/infiniband/umad.h b/trunk/ulp/libibumad/include/infiniband/umad.h
index aceebf3..8da5996 100644
--- a/trunk/ulp/libibumad/include/infiniband/umad.h
+++ b/trunk/ulp/libibumad/include/infiniband/umad.h
@@ -189,6 +189,8 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms);
 __declspec(dllexport)
 int umad_poll(int portid, int timeout_ms);
 HANDLE umad_get_fd(int portid);
+__declspec(dllexport)
+int umad_cancel_recv(int portid);
 
 __declspec(dllexport)
 int umad_register(int portid, int mgmt_class, int mgmt_version,
diff --git a/trunk/ulp/libibumad/src/ibum_exports.src b/trunk/ulp/libibumad/src/ibum_exports.src
index d79244e..b32a837 100644
--- a/trunk/ulp/libibumad/src/ibum_exports.src
+++ b/trunk/ulp/libibumad/src/ibum_exports.src
@@ -36,4 +36,5 @@ EXPORTS
 	umad_debug;
 	umad_addr_dump;
 	umad_dump;
+	umad_cancel_recv;
 #endif
diff --git a/trunk/ulp/libibumad/src/umad.cpp b/trunk/ulp/libibumad/src/umad.cpp
index 19582dc..47a6766 100644
--- a/trunk/ulp/libibumad/src/umad.cpp
+++ b/trunk/ulp/libibumad/src/umad.cpp
@@ -599,12 +599,11 @@ int umad_send(int portid, int agentid, void *umad, int length,
 	return 0;
 }
 
-static HRESULT umad_cancel_recv(um_port_t *port)
+__declspec(dllexport)
+int umad_cancel_recv(int portid)
 {
-	DWORD bytes;
-
-	port->prov->CancelOverlappedRequests();
-	return port->prov->GetOverlappedResult(&port->overlap, &bytes, TRUE);
+	ports[portid].prov->CancelOverlappedRequests();
+	return 0;
 }
 
 __declspec(dllexport)
@@ -613,6 +612,7 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms)
 	WM_MAD		*mad = (WM_MAD *) umad;
 	um_port_t	*port;
 	HRESULT		hr;
+	DWORD		bytes;
 
 	port = &ports[portid];
 	ResetEvent(port->overlap.hEvent);
@@ -620,7 +620,8 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms)
 	if (hr == WV_IO_PENDING) {
 		hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);
 		if (hr == WAIT_TIMEOUT) {
-			hr = umad_cancel_recv(port);
+			port->prov->CancelOverlappedRequests();
+			hr = port->prov->GetOverlappedResult(&port->overlap, &bytes, TRUE);
 			if (hr == WV_CANCELLED) {
 				_set_errno(EWOULDBLOCK);
 				return -EWOULDBLOCK;
@@ -651,6 +652,7 @@ int umad_poll(int portid, int timeout_ms)
 	WM_MAD		mad;
 	um_port_t	*port;
 	HRESULT		hr;
+	DWORD		bytes;
 
 	port = &ports[portid];
 	ResetEvent(port->overlap.hEvent);
@@ -658,7 +660,8 @@ int umad_poll(int portid, int timeout_ms)
 	if (hr == WV_IO_PENDING) {
 		hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);
 		if (hr == WAIT_TIMEOUT) {
-			hr = umad_cancel_recv(port);
+			port->prov->CancelOverlappedRequests();
+			hr = port->prov->GetOverlappedResult(&port->overlap, &bytes, TRUE);
 			if (hr == WV_CANCELLED) {
 				_set_errno(ETIMEDOUT);
 				return -ETIMEDOUT;




More information about the ofw mailing list