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.dll 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@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1@2703
ad392aa1-c5ef-ae45-8dd8-
e69d62a5ef86
return S_OK;\r
}\r
\r
-#endif\r
+#endif // WINVER >= 0x600\r
+\r
+\r
+HRESULT\r
+ResolvePath(\r
+ __in const struct sockaddr* pSrcAddr,\r
+ __in const struct sockaddr* pDestAddr,\r
+ __out IBAT_PATH_BLOB* pPath,\r
+ __in DWORD Timeout)\r
+{\r
+ INT64 to;\r
+ HRESULT hr;\r
+\r
+ to = (Timeout == INFINITE) ? MAXINT64 : (INT64) ((UINT64) Timeout);\r
+ for (;;) {\r
+ hr = Resolve(pSrcAddr, pDestAddr, pPath);\r
+ if( hr != E_PENDING || to <= 0 )\r
+ break;\r
+\r
+ to -= 10;\r
+ Sleep(10);\r
+ };\r
+\r
+ return hr;\r
}\r
\r
+} /* IBAT namespace */\r
+\r
extern "C"\r
{\r
\r
return IBAT::Resolve( pSrcAddr, pDestAddr, pPath );\r
}\r
\r
+HRESULT\r
+IbatResolvePath(\r
+ __in const struct sockaddr* pSrcAddr,\r
+ __in const struct sockaddr* pDestAddr,\r
+ __out IBAT_PATH_BLOB* pPath,\r
+ __in DWORD Timeout)\r
+{\r
+ return IBAT::ResolvePath(pSrcAddr, pDestAddr, pPath, Timeout);\r
+}\r
+\r
} /* extern "C" */\r
__out IBAT_PATH_BLOB* pPath\r
);\r
\r
+HRESULT\r
+ResolvePath(\r
+ __in const struct sockaddr* pSrcAddr,\r
+ __in const struct sockaddr* pDestAddr,\r
+ __out IBAT_PATH_BLOB* pPath,\r
+ __in DWORD Timeout /* ms */\r
+ );\r
+\r
}\r
#else /* __cplusplus */\r
\r
__out IBAT_PATH_BLOB* pPath\r
);\r
\r
+HRESULT\r
+IbatResolvePath(\r
+ __in const struct sockaddr* pSrcAddr,\r
+ __in const struct sockaddr* pDestAddr,\r
+ __out IBAT_PATH_BLOB* pPath,\r
+ __in DWORD Timeout /* ms */\r
+ );\r
+\r
#endif /* __cplusplus */\r
\r
-#endif // _IBAT_H_
\ No newline at end of file
+#endif // _IBAT_H_\r
return 0;\r
}\r
\r
-static int\r
-ucma_resolve_ibat_path(struct rdma_cm_id *id, int timeout_ms,\r
- IBAT_PATH_BLOB *path)\r
-{\r
- HRESULT hr;\r
-\r
- do {\r
- hr = IBAT::Resolve(&id->route.addr.src_addr, &id->route.addr.dst_addr,\r
- path);\r
- if (hr != E_PENDING || timeout_ms <= 0) {\r
- break;\r
- }\r
- timeout_ms -= 10;\r
- Sleep(10);\r
- } while (timeout_ms > 0);\r
-\r
- return hr;\r
-}\r
-\r
__declspec(dllexport)\r
int rdma_resolve_route(struct rdma_cm_id *id, int timeout_ms)\r
{\r
IBAT_PATH_BLOB path;\r
HRESULT hr;\r
\r
- hr = ucma_resolve_ibat_path(id, timeout_ms, &path);\r
+ hr = IBAT::ResolvePath(&id->route.addr.src_addr, &id->route.addr.dst_addr,\r
+ &path, timeout_ms);\r
if (FAILED(hr)) {\r
return hr;\r
}\r
} else {\r
addr.Sin6.sin6_port = LocalPort;\r
}\r
- hr = m_pWvConnEp->BindAddress(&addr.Sa);\r
+\r
+ hr = IBAT::ResolvePath(&addr.Sa, pAddress, &path, INFINITE);\r
if (FAILED(hr)) {\r
goto out;\r
}\r
\r
- hr = IBAT::Resolve(&addr.Sa, pAddress, &path);\r
+ hr = m_pWvConnEp->BindAddress(&addr.Sa);\r
if (FAILED(hr)) {\r
goto out;\r
}\r
HRESULT hr;\r
\r
IBSP_ENTER( IBSP_DBG_HW );\r
+ hr = IbatResolvePath(p_src_addr, p_dest_addr, (IBAT_PATH_BLOB*)&path,\r
+ INFINITE);\r
\r
- for(;;)\r
- {\r
- hr = IbatResolve(\r
- p_src_addr,\r
- p_dest_addr,\r
- (IBAT_PATH_BLOB*)&path\r
- );\r
-\r
- if( hr != E_PENDING )\r
- break;\r
-\r
- Sleep( 100 );\r
- }\r
if( hr == S_OK )\r
{\r
*port_guid = path.dgid.unicast.interface_id;\r