aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTom Talpey <talpey@netapp.com>2008-10-09 15:01:41 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-10-10 15:13:31 -0400
commit5675add36e76b9487e7f9e689f854cb8d6afd9b4 (patch)
tree414b5e26b099c6aa42ee989925c0dfb8b717366e /net
parent1a954051b0cf79bd67e5f9db40333e3a9b1d05d2 (diff)
RPC/RDMA: harden connection logic against missing/late rdma_cm upcalls.
Add defensive timeouts to wait_for_completion() calls in RDMA address resolution, and make them interruptible. Fix the timeout units to milliseconds (formerly jiffies) and move to private header. Signed-off-by: Tom Talpey <talpey@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtrdma/verbs.c11
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h3
2 files changed, 10 insertions, 4 deletions
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index a63d0c0ec017..f46fb93f421b 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -284,6 +284,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
284 switch (event->event) { 284 switch (event->event) {
285 case RDMA_CM_EVENT_ADDR_RESOLVED: 285 case RDMA_CM_EVENT_ADDR_RESOLVED:
286 case RDMA_CM_EVENT_ROUTE_RESOLVED: 286 case RDMA_CM_EVENT_ROUTE_RESOLVED:
287 ia->ri_async_rc = 0;
287 complete(&ia->ri_done); 288 complete(&ia->ri_done);
288 break; 289 break;
289 case RDMA_CM_EVENT_ADDR_ERROR: 290 case RDMA_CM_EVENT_ADDR_ERROR:
@@ -363,26 +364,28 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
363 return id; 364 return id;
364 } 365 }
365 366
366 ia->ri_async_rc = 0; 367 ia->ri_async_rc = -ETIMEDOUT;
367 rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT); 368 rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT);
368 if (rc) { 369 if (rc) {
369 dprintk("RPC: %s: rdma_resolve_addr() failed %i\n", 370 dprintk("RPC: %s: rdma_resolve_addr() failed %i\n",
370 __func__, rc); 371 __func__, rc);
371 goto out; 372 goto out;
372 } 373 }
373 wait_for_completion(&ia->ri_done); 374 wait_for_completion_interruptible_timeout(&ia->ri_done,
375 msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
374 rc = ia->ri_async_rc; 376 rc = ia->ri_async_rc;
375 if (rc) 377 if (rc)
376 goto out; 378 goto out;
377 379
378 ia->ri_async_rc = 0; 380 ia->ri_async_rc = -ETIMEDOUT;
379 rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT); 381 rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
380 if (rc) { 382 if (rc) {
381 dprintk("RPC: %s: rdma_resolve_route() failed %i\n", 383 dprintk("RPC: %s: rdma_resolve_route() failed %i\n",
382 __func__, rc); 384 __func__, rc);
383 goto out; 385 goto out;
384 } 386 }
385 wait_for_completion(&ia->ri_done); 387 wait_for_completion_interruptible_timeout(&ia->ri_done,
388 msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
386 rc = ia->ri_async_rc; 389 rc = ia->ri_async_rc;
387 if (rc) 390 if (rc)
388 goto out; 391 goto out;
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index fde6499a53b2..c7a7eba991bc 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -51,6 +51,9 @@
51#include <linux/sunrpc/rpc_rdma.h> /* RPC/RDMA protocol */ 51#include <linux/sunrpc/rpc_rdma.h> /* RPC/RDMA protocol */
52#include <linux/sunrpc/xprtrdma.h> /* xprt parameters */ 52#include <linux/sunrpc/xprtrdma.h> /* xprt parameters */
53 53
54#define RDMA_RESOLVE_TIMEOUT (5000) /* 5 seconds */
55#define RDMA_CONNECT_RETRY_MAX (2) /* retries if no listener backlog */
56
54/* 57/*
55 * Interface Adapter -- one per transport instance 58 * Interface Adapter -- one per transport instance
56 */ 59 */