Commit c5983232 authored by Chuck Lever's avatar Chuck Lever Committed by Linus Torvalds

[PATCH] eliminate hangs during RPC client shutdown

this eliminates an infinite loop in rpciod if an RPC client's reference
counter accidentally goes negative.  i've been running this under load
since 2.5.30 with no ill effects.
parent a0a7d715
...@@ -138,19 +138,27 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname, ...@@ -138,19 +138,27 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
int int
rpc_shutdown_client(struct rpc_clnt *clnt) rpc_shutdown_client(struct rpc_clnt *clnt)
{ {
dprintk("RPC: shutting down %s client for %s\n", dprintk("RPC: shutting down %s client for %s, tasks=%d\n",
clnt->cl_protname, clnt->cl_server); clnt->cl_protname, clnt->cl_server,
while (atomic_read(&clnt->cl_users)) { atomic_read(&clnt->cl_users));
#ifdef RPC_DEBUG
dprintk("RPC: rpc_shutdown_client: client %s, tasks=%d\n", while (atomic_read(&clnt->cl_users) > 0) {
clnt->cl_protname, atomic_read(&clnt->cl_users));
#endif
/* Don't let rpc_release_client destroy us */ /* Don't let rpc_release_client destroy us */
clnt->cl_oneshot = 0; clnt->cl_oneshot = 0;
clnt->cl_dead = 0; clnt->cl_dead = 0;
rpc_killall_tasks(clnt); rpc_killall_tasks(clnt);
sleep_on_timeout(&destroy_wait, 1*HZ); sleep_on_timeout(&destroy_wait, 1*HZ);
} }
if (atomic_read(&clnt->cl_users) < 0) {
printk(KERN_ERR "RPC: rpc_shutdown_client clnt %p tasks=%d\n",
clnt, atomic_read(&clnt->cl_users));
#ifdef RPC_DEBUG
rpc_show_tasks();
#endif
BUG();
}
return rpc_destroy_client(clnt); return rpc_destroy_client(clnt);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment