diff options
author | Tom Talpey <talpey@netapp.com> | 2008-10-09 15:01:41 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-10-10 15:13:31 -0400 |
commit | 5675add36e76b9487e7f9e689f854cb8d6afd9b4 (patch) | |
tree | 414b5e26b099c6aa42ee989925c0dfb8b717366e /net | |
parent | 1a954051b0cf79bd67e5f9db40333e3a9b1d05d2 (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.c | 11 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 3 |
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 | */ |