From patchwork Fri Dec 6 23:08:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamal Mostafa X-Patchwork-Id: 298348 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id CEB1F2C0092 for ; Sat, 7 Dec 2013 10:11:58 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1Vp4Ys-0003EZ-7w; Fri, 06 Dec 2013 23:11:54 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1Vp4Vd-0000zL-Sh for kernel-team@lists.ubuntu.com; Fri, 06 Dec 2013 23:08:33 +0000 Received: from c-67-160-231-162.hsd1.ca.comcast.net ([67.160.231.162] helo=fourier) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Vp4Vd-0004Jk-Gf; Fri, 06 Dec 2013 23:08:33 +0000 Received: from kamal by fourier with local (Exim 4.80) (envelope-from ) id 1Vp4Vb-0008Ot-Be; Fri, 06 Dec 2013 15:08:31 -0800 From: Kamal Mostafa To: Trond Myklebust Subject: [3.8.y.z extended stable] Patch "SUNRPC: Avoid deep recursion in rpc_release_client" has been added to staging queue Date: Fri, 6 Dec 2013 15:08:31 -0800 Message-Id: <1386371311-32260-1-git-send-email-kamal@canonical.com> X-Mailer: git-send-email 1.8.3.2 X-Extended-Stable: 3.8 Cc: Bruce Fields , Kamal Mostafa , Weston Andros Adamson , kernel-team@lists.ubuntu.com, Jeff Layton X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com This is a note to let you know that I have just added a patch titled SUNRPC: Avoid deep recursion in rpc_release_client to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree which can be found at: http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue This patch is scheduled to be released in version 3.8.13.14. 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.8.y.z tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Kamal ------ From f3ae133df1082183df18370d24c6102bcfee4917 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 12 Nov 2013 17:24:36 -0500 Subject: SUNRPC: Avoid deep recursion in rpc_release_client commit d07ba8422f1e58be94cc98a1f475946dc1b89f1b upstream. In cases where an rpc client has a parent hierarchy, then rpc_free_client may end up calling rpc_release_client() on the parent, thus recursing back into rpc_free_client. If the hierarchy is deep enough, then we can get into situations where the stack simply overflows. The fix is to have rpc_release_client() loop so that it can take care of the parent rpc client hierarchy without needing to recurse. Reported-by: Jeff Layton Reported-by: Weston Andros Adamson Reported-by: Bruce Fields Link: http://lkml.kernel.org/r/2C73011F-0939-434C-9E4D-13A1EB1403D7@netapp.com Signed-off-by: Trond Myklebust Signed-off-by: Kamal Mostafa --- net/sunrpc/clnt.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) -- 1.8.3.2 diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 1a3bd4d..d8b6ad9 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -624,14 +624,16 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); /* * Free an RPC client */ -static void +static struct rpc_clnt * rpc_free_client(struct rpc_clnt *clnt) { + struct rpc_clnt *parent = NULL; + dprintk_rcu("RPC: destroying %s client for %s\n", clnt->cl_protname, rcu_dereference(clnt->cl_xprt)->servername); if (clnt->cl_parent != clnt) - rpc_release_client(clnt->cl_parent); + parent = clnt->cl_parent; rpc_clnt_remove_pipedir(clnt); rpc_unregister_client(clnt); rpc_free_iostats(clnt->cl_metrics); @@ -640,18 +642,17 @@ rpc_free_client(struct rpc_clnt *clnt) xprt_put(rcu_dereference_raw(clnt->cl_xprt)); rpciod_down(); kfree(clnt); + return parent; } /* * Free an RPC client */ -static void +static struct rpc_clnt * rpc_free_auth(struct rpc_clnt *clnt) { - if (clnt->cl_auth == NULL) { - rpc_free_client(clnt); - return; - } + if (clnt->cl_auth == NULL) + return rpc_free_client(clnt); /* * Note: RPCSEC_GSS may need to send NULL RPC calls in order to @@ -662,7 +663,8 @@ rpc_free_auth(struct rpc_clnt *clnt) rpcauth_release(clnt->cl_auth); clnt->cl_auth = NULL; if (atomic_dec_and_test(&clnt->cl_count)) - rpc_free_client(clnt); + return rpc_free_client(clnt); + return NULL; } /* @@ -673,10 +675,13 @@ rpc_release_client(struct rpc_clnt *clnt) { dprintk("RPC: rpc_release_client(%p)\n", clnt); - if (list_empty(&clnt->cl_tasks)) - wake_up(&destroy_wait); - if (atomic_dec_and_test(&clnt->cl_count)) - rpc_free_auth(clnt); + do { + if (list_empty(&clnt->cl_tasks)) + wake_up(&destroy_wait); + if (!atomic_dec_and_test(&clnt->cl_count)) + break; + clnt = rpc_free_auth(clnt); + } while (clnt != NULL); } /**