[ofw] [PATCH] ibat/resolve: retry ibat resolution

Sean Hefty sean.hefty at intel.com
Wed Feb 17 12:30:24 PST 2010


Winverbs ND scale out testing showed that IBAT::Resolve() can
return E_PENDING, which requires that the resolution be retried.
A similar issue to this was seen when testing with the librdmacm.
Rather than duplicating retry logic in the winverbs ND provider,
add new functionality to ibat, with retry capability.  To
avoid breaking the ibat interface, extend the API with a
new call ResolvePath() that takes a timeout value.

ResolvePath() automatically retries Resolve() while the result
is E_PENDING, until the request times out.  Modify the winverbs
ND provider to call ResolvePath().  Also update other places
where Resolve() is called in a loop: the librdmacm and wsd.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
If acceptable, this patch should work its way into the 2.2 release.


diff --git a/trunk/core/ibat/user/ibat.cpp b/trunk/core/ibat/user/ibat.cpp
index 69d9186..ede0a5e 100644
--- a/trunk/core/ibat/user/ibat.cpp
+++ b/trunk/core/ibat/user/ibat.cpp
@@ -358,9 +358,32 @@ Resolve(
     return S_OK;
 }
 
-#endif
+#endif // WINVER >= 0x600
+
+
+HRESULT
+ResolvePath(
+    __in const struct sockaddr* pSrcAddr,
+    __in const struct sockaddr* pDestAddr,
+    __out IBAT_PATH_BLOB* pPath,
+	__in int Timeout)
+{
+	HRESULT hr;
+
+	do {
+		hr = Resolve(pSrcAddr, pDestAddr, pPath);
+		if( hr != E_PENDING || Timeout <= 0 )
+			break;
+
+		Timeout -= 10;
+		Sleep(10);
+	} while( Timeout > 0 );
+
+	return hr;
 }
 
+} /* IBAT namespace */
+
 extern "C"
 {
 
@@ -374,4 +397,14 @@ IbatResolve(
     return IBAT::Resolve( pSrcAddr, pDestAddr, pPath );
 }
 
+HRESULT
+IbatResolvePath(
+    __in const struct sockaddr* pSrcAddr,
+    __in const struct sockaddr* pDestAddr,
+    __out IBAT_PATH_BLOB* pPath,
+	__in const int Timeout)
+{
+	return IBAT::ResolvePath(pSrcAddr, pDestAddr, pPath, Timeout);
+}
+
 } /* extern "C" */
diff --git a/trunk/inc/user/iba/ibat.h b/trunk/inc/user/iba/ibat.h
index c9a1740..e7f2c06 100644
--- a/trunk/inc/user/iba/ibat.h
+++ b/trunk/inc/user/iba/ibat.h
@@ -41,6 +41,8 @@ typedef struct _IBAT_PATH_BLOB
 
 } IBAT_PATH_BLOB;
 
+#define IBAT_MAX_TIMEOUT 0x0FFFFFFF
+
 #ifdef __cplusplus
 namespace IBAT
 {
@@ -52,6 +54,14 @@ Resolve(
     __out IBAT_PATH_BLOB* pPath
     );
 
+HRESULT
+ResolvePath(
+    __in const struct sockaddr* pSrcAddr,
+    __in const struct sockaddr* pDestAddr,
+    __out IBAT_PATH_BLOB* pPath,
+	__in int Timeout	/* ms */
+    );
+
 }
 #else /* __cplusplus */
 
@@ -62,6 +72,14 @@ IbatResolve(
     __out IBAT_PATH_BLOB* pPath
     );
 
+HRESULT
+IbatResolvePath(
+    __in const struct sockaddr* pSrcAddr,
+    __in const struct sockaddr* pDestAddr,
+    __out IBAT_PATH_BLOB* pPath,
+	__in int Timeout	/* ms */
+    );
+
 #endif /* __cplusplus */
 
 #endif	// _IBAT_H_
\ No newline at end of file
diff --git a/trunk/ulp/librdmacm/src/cma.cpp b/trunk/ulp/librdmacm/src/cma.cpp
index cde309b..40e7411 100644
--- a/trunk/ulp/librdmacm/src/cma.cpp
+++ b/trunk/ulp/librdmacm/src/cma.cpp
@@ -506,25 +506,6 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
 	return 0;
 }
 
-static int
-ucma_resolve_ibat_path(struct rdma_cm_id *id, int timeout_ms,
-					   IBAT_PATH_BLOB *path)
-{
-	HRESULT hr;
-
-	do {
-		hr = IBAT::Resolve(&id->route.addr.src_addr, &id->route.addr.dst_addr,
-						   path);
-		if (hr != E_PENDING || timeout_ms <= 0) {
-			break;
-		}
-		timeout_ms -= 10;
-		Sleep(10);
-	} while (timeout_ms > 0);
-
-	return hr;
-}
-
 __declspec(dllexport)
 int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
 {
@@ -532,7 +513,8 @@ int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)
 	IBAT_PATH_BLOB path;
 	HRESULT hr;
 
-	hr = ucma_resolve_ibat_path(id, timeout_ms, &path);
+	hr = IBAT::ResolvePath(&id->route.addr.src_addr, &id->route.addr.dst_addr,
+						   &path, timeout_ms);
 	if (FAILED(hr)) {
 		return hr;
 	}
diff --git a/trunk/ulp/netdirect/user/nd_connect.cpp b/trunk/ulp/netdirect/user/nd_connect.cpp
index aa46ada..6ee6fa0 100644
--- a/trunk/ulp/netdirect/user/nd_connect.cpp
+++ b/trunk/ulp/netdirect/user/nd_connect.cpp
@@ -138,12 +138,13 @@ Connect(INDEndpoint* pEndpoint,
 	} else {
 		addr.Sin6.sin6_port = LocalPort;
 	}
-	hr = m_pWvConnEp->BindAddress(&addr.Sa);
+
+	hr = IBAT::ResolvePath(&addr.Sa, pAddress, &path, IBAT_MAX_TIMEOUT);
 	if (FAILED(hr)) {
 		goto out;
 	}
 
-	hr = IBAT::Resolve(&addr.Sa, pAddress, &path);
+	hr = m_pWvConnEp->BindAddress(&addr.Sa);
 	if (FAILED(hr)) {
 		goto out;
 	}
diff --git a/trunk/ulp/wsd/user/ibsp_ip.c b/trunk/ulp/wsd/user/ibsp_ip.c
index a0afe89..0da0c0e 100644
--- a/trunk/ulp/wsd/user/ibsp_ip.c
+++ b/trunk/ulp/wsd/user/ibsp_ip.c
@@ -270,20 +270,9 @@ query_guid_address(
 	HRESULT hr;
 
 	IBSP_ENTER( IBSP_DBG_HW );
+	hr = IbatResolvePath(p_src_addr, p_dest_addr, (IBAT_PATH_BLOB*)&path,
+		IBAT_MAX_TIMEOUT);
 
-	for(;;)
-	{
-		hr = IbatResolve(
-			p_src_addr,
-			p_dest_addr,
-			(IBAT_PATH_BLOB*)&path
-			);
-
-		if( hr != E_PENDING )
-			break;
-
-		Sleep( 100 );
-	}
 	if( hr == S_OK )
 	{
 		*port_guid = path.dgid.unicast.interface_id;





More information about the ofw mailing list