Patchwork [3.5.y.z,extended,stable] Patch "svcrpc: make svc_age_temp_xprts enqueue under sv_lock" has been added to staging queue

mail settings
Submitter Luis Henriques
Date March 4, 2013, 8:48 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/224795/
State New
Headers show


Luis Henriques - March 4, 2013, 8:48 p.m.
This is a note to let you know that I have just added a patch titled

    svcrpc: make svc_age_temp_xprts enqueue under sv_lock

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From c050375de24d473b6745f0d21219e272c8a669f5 Mon Sep 17 00:00:00 2001
From: "J. Bruce Fields" <>
Date: Sun, 10 Feb 2013 11:33:48 -0500
Subject: [PATCH] svcrpc: make svc_age_temp_xprts enqueue under sv_lock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

commit e75bafbff2270993926abcc31358361db74a9bc2 upstream.

svc_age_temp_xprts expires xprts in a two-step process: first it takes
the sv_lock and moves the xprts to expire off their server-wide list
(sv_tempsocks or sv_permsocks) to a local list.  Then it drops the
sv_lock and enqueues and puts each one.

I see no reason for this: svc_xprt_enqueue() will take sp_lock, but the
sv_lock and sp_lock are not otherwise nested anywhere (and documentation
at the top of this file claims it's correct to nest these with sp_lock

Tested-by: Jason Tibbitts <>
Tested-by: PaweĊ‚ Sikora <>
Signed-off-by: J. Bruce Fields <>
Signed-off-by: Luis Henriques <>
 net/sunrpc/svc_xprt.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)



diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index bac973a..3e74e01 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -814,7 +814,6 @@  static void svc_age_temp_xprts(unsigned long closure)
 	struct svc_serv *serv = (struct svc_serv *)closure;
 	struct svc_xprt *xprt;
 	struct list_head *le, *next;
-	LIST_HEAD(to_be_aged);


@@ -835,25 +834,15 @@  static void svc_age_temp_xprts(unsigned long closure)
 		if (atomic_read(&xprt->xpt_ref.refcount) > 1 ||
 		    test_bit(XPT_BUSY, &xprt->xpt_flags))
-		svc_xprt_get(xprt);
-		list_move(le, &to_be_aged);
+		list_del_init(le);
 		set_bit(XPT_CLOSE, &xprt->xpt_flags);
 		set_bit(XPT_DETACHED, &xprt->xpt_flags);
-	}
-	spin_unlock_bh(&serv->sv_lock);
-	while (!list_empty(&to_be_aged)) {
-		le =;
-		/* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */
-		list_del_init(le);
-		xprt = list_entry(le, struct svc_xprt, xpt_list);
 		dprintk("queuing xprt %p for closing\n", xprt);

 		/* a thread will dequeue and close it soon */
-		svc_xprt_put(xprt);
+	spin_unlock_bh(&serv->sv_lock);

 	mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);