From 1693da704c4277706445a9f820bcef5402ad42cb Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 18 Feb 2010 21:51:19 +0000 Subject: [PATCH] ibat/resolve: retry ibat resolution 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 git-svn-id: svn://openib.tc.cornell.edu/gen1@2703 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/core/ibat/user/ibat.cpp | 37 ++++++++++++++++++++++++- trunk/inc/user/iba/ibat.h | 18 +++++++++++- trunk/ulp/librdmacm/src/cma.cpp | 22 ++------------- trunk/ulp/netdirect/user/nd_connect.cpp | 5 ++-- trunk/ulp/wsd/user/ibsp_ip.c | 15 ++-------- 5 files changed, 60 insertions(+), 37 deletions(-) diff --git a/trunk/core/ibat/user/ibat.cpp b/trunk/core/ibat/user/ibat.cpp index 69d91861..773bfd87 100644 --- a/trunk/core/ibat/user/ibat.cpp +++ b/trunk/core/ibat/user/ibat.cpp @@ -358,9 +358,34 @@ 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 DWORD Timeout) +{ + INT64 to; + HRESULT hr; + + to = (Timeout == INFINITE) ? MAXINT64 : (INT64) ((UINT64) Timeout); + for (;;) { + hr = Resolve(pSrcAddr, pDestAddr, pPath); + if( hr != E_PENDING || to <= 0 ) + break; + + to -= 10; + Sleep(10); + }; + + return hr; } +} /* IBAT namespace */ + extern "C" { @@ -374,4 +399,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 DWORD 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 c9a17405..6e84486c 100644 --- a/trunk/inc/user/iba/ibat.h +++ b/trunk/inc/user/iba/ibat.h @@ -52,6 +52,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 DWORD Timeout /* ms */ + ); + } #else /* __cplusplus */ @@ -62,6 +70,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 DWORD Timeout /* ms */ + ); + #endif /* __cplusplus */ -#endif // _IBAT_H_ \ No newline at end of file +#endif // _IBAT_H_ diff --git a/trunk/ulp/librdmacm/src/cma.cpp b/trunk/ulp/librdmacm/src/cma.cpp index cde309b8..40e74113 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 aa46adac..81d5f7bd 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, INFINITE); 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 a0afe894..b0124bb4 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, + INFINITE); - 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; -- 2.41.0