aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-06-14 18:00:42 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:31 -0400
commitc1384c9c4c184543375b52a0997d06cd98145164 (patch)
tree26bb2ee42dc2fddfe1817d3066844669912adef2 /net/sunrpc/xprt.c
parent6e5b70e9d1e712d8dad5514e0ab5240ac4b5fb57 (diff)
SUNRPC: fix hang due to eventd deadlock...
Brian Behlendorf writes: The root cause of the NFS hang we were observing appears to be a rare deadlock between the kernel provided usermodehelper API and the linux NFS client. The deadlock can arise because both of these services use the generic linux work queues. The usermodehelper API run the specified user application in the context of the work queue. And NFS submits both cleanup and reconnect work to the generic work queue for handling. Normally this is fine but a deadlock can result in the following situation. - NFS client is in a disconnected state - [events/0] runs a usermodehelper app with an NFS dependent operation, this triggers an NFS reconnect. - NFS reconnect happens to be submitted to [events/0] work queue. - Deadlock, the [events/0] work queue will never process the reconnect because it is blocked on the previous NFS dependent operation which will not complete.` The solution is simply to run reconnect requests on rpciod. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 5b05b73e4c1d..518acb74a5bb 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -127,7 +127,7 @@ static void xprt_clear_locked(struct rpc_xprt *xprt)
127 clear_bit(XPRT_LOCKED, &xprt->state); 127 clear_bit(XPRT_LOCKED, &xprt->state);
128 smp_mb__after_clear_bit(); 128 smp_mb__after_clear_bit();
129 } else 129 } else
130 schedule_work(&xprt->task_cleanup); 130 queue_work(rpciod_workqueue, &xprt->task_cleanup);
131} 131}
132 132
133/* 133/*
@@ -515,7 +515,7 @@ xprt_init_autodisconnect(unsigned long data)
515 if (xprt_connecting(xprt)) 515 if (xprt_connecting(xprt))
516 xprt_release_write(xprt, NULL); 516 xprt_release_write(xprt, NULL);
517 else 517 else
518 schedule_work(&xprt->task_cleanup); 518 queue_work(rpciod_workqueue, &xprt->task_cleanup);
519 return; 519 return;
520out_abort: 520out_abort:
521 spin_unlock(&xprt->transport_lock); 521 spin_unlock(&xprt->transport_lock);