On Mon, Mar 29, 2010 at 08:57:48PM -0400, J. Bruce Fields wrote: > Hm, OK, so it does look like tcp_close() can sleep, so we are wrong to > be calling svc_xprt_put() while holding sv_lock. > > The commit ab1b18f "sunrpc: remove unnecessary svc_xprt_put" gets rid of > one svc_xprt_put(), and the remaining final svc_xprt_put() could easily > be delayed till after we drop the lock. So, perhaps we want the following. --b. commit 788e69e548cc8d127b90f0de1f7b7e983d1d587a Author: J. Bruce Fields <bfields@xxxxxxxxxxxxxx> Date: Mon Mar 29 21:02:31 2010 -0400 svcrpc: don't hold sv_lock over svc_xprt_put() svc_xprt_put() can call tcp_close(), which can sleep, so we shouldn't be holding this lock. In fact, only the xpt_list removal and the sv_tmpcnt decrement should need the sv_lock here. Reported-by: Mi Jinlong <mijinlong@xxxxxxxxxxxxxx> Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxxxxxx> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 8f0f1fb..c334f54 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -892,12 +892,12 @@ void svc_delete_xprt(struct svc_xprt *xprt) */ if (test_bit(XPT_TEMP, &xprt->xpt_flags)) serv->sv_tmpcnt--; + spin_unlock_bh(&serv->sv_lock); while ((dr = svc_deferred_dequeue(xprt)) != NULL) kfree(dr); svc_xprt_put(xprt); - spin_unlock_bh(&serv->sv_lock); } void svc_close_xprt(struct svc_xprt *xprt) -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html