All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel
@ 2014-03-24  3:54 Kinglong Mee
  2014-03-24  3:56 ` [PATCH 1/5][RESEND] NFSD: Using free_conn free connection Kinglong Mee
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Kinglong Mee @ 2014-03-24  3:54 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Trond Myklebust, Linux NFS Mailing List

When using pynfs test-site, I found some memory leak for the backchannel.

Kinglong Mee (5):
  NFSD: Using free_conn free connection
  NFSD: Free backchannel xprt in bc_destroy
  SUNRPC: New helper for creating client with rpc_xprt
  NFSD/SUNRPC: Check rpc_xprt out of xs_setup_bc_tcp
  SUNRPC: Clear xpt_bc_xprt if xs_setup_bc_tcp failed

 fs/nfsd/nfs4callback.c      | 19 ++++++++++++++-
 fs/nfsd/nfs4state.c         |  3 ++-
 include/linux/sunrpc/clnt.h |  2 ++
 include/linux/sunrpc/xprt.h | 13 +++++++++-
 net/sunrpc/clnt.c           | 58 ++++++++++++++++++++++++++-------------------
 net/sunrpc/xprt.c           | 12 ----------
 net/sunrpc/xprtsock.c       | 15 +++++-------
 7 files changed, 73 insertions(+), 49 deletions(-)

-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5][RESEND] NFSD: Using free_conn free connection
  2014-03-24  3:54 [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel Kinglong Mee
@ 2014-03-24  3:56 ` Kinglong Mee
  2014-03-24  3:58 ` [PATCH 2/5][RESEND] NFSD: Free backchannel xprt in bc_destroy Kinglong Mee
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Kinglong Mee @ 2014-03-24  3:56 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Trond Myklebust, Linux NFS Mailing List

Connection from alloc_conn must be freed through free_conn,
otherwise, the reference of svc_xprt will never be put.

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
---
 fs/nfsd/nfs4state.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d5d070f..d7efc4b 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2287,7 +2287,8 @@ out:
 	if (!list_empty(&clp->cl_revoked))
 		seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
 out_no_session:
-	kfree(conn);
+	if (conn)
+		free_conn(conn);
 	spin_unlock(&nn->client_lock);
 	return status;
 out_put_session:
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5][RESEND] NFSD: Free backchannel xprt in bc_destroy
  2014-03-24  3:54 [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel Kinglong Mee
  2014-03-24  3:56 ` [PATCH 1/5][RESEND] NFSD: Using free_conn free connection Kinglong Mee
@ 2014-03-24  3:58 ` Kinglong Mee
  2014-03-24  3:58 ` [PATCH 3/5][RESEND] SUNRPC: New helper for creating client with rpc_xprt Kinglong Mee
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Kinglong Mee @ 2014-03-24  3:58 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Trond Myklebust, Linux NFS Mailing List

Backchannel xprt isn't freed right now.
Free it in bc_destroy, and put the reference of THIS_MODULE.

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
---
 net/sunrpc/xprtsock.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 2cbafa7..da882af 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2549,6 +2549,10 @@ static void bc_close(struct rpc_xprt *xprt)
 
 static void bc_destroy(struct rpc_xprt *xprt)
 {
+	dprintk("RPC:       bc_destroy xprt %p\n", xprt);
+
+	xs_xprt_free(xprt);
+	module_put(THIS_MODULE);
 }
 
 static struct rpc_xprt_ops xs_local_ops = {
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5][RESEND] SUNRPC: New helper for creating client with rpc_xprt
  2014-03-24  3:54 [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel Kinglong Mee
  2014-03-24  3:56 ` [PATCH 1/5][RESEND] NFSD: Using free_conn free connection Kinglong Mee
  2014-03-24  3:58 ` [PATCH 2/5][RESEND] NFSD: Free backchannel xprt in bc_destroy Kinglong Mee
@ 2014-03-24  3:58 ` Kinglong Mee
  2014-03-24  3:59 ` [PATCH 4/5][RESEND] NFSD/SUNRPC: Check rpc_xprt out of xs_setup_bc_tcp Kinglong Mee
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Kinglong Mee @ 2014-03-24  3:58 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Trond Myklebust, Linux NFS Mailing List

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
---
 include/linux/sunrpc/clnt.h |  2 ++
 net/sunrpc/clnt.c           | 58 ++++++++++++++++++++++++++-------------------
 2 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 8af2804..70736b9 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -130,6 +130,8 @@ struct rpc_create_args {
 #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT	(1UL << 9)
 
 struct rpc_clnt *rpc_create(struct rpc_create_args *args);
+struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
+					struct rpc_xprt *xprt);
 struct rpc_clnt	*rpc_bind_new_program(struct rpc_clnt *,
 				const struct rpc_program *, u32);
 void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 0edada9..3c9a0f0 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -438,6 +438,38 @@ out_no_rpciod:
 	return ERR_PTR(err);
 }
 
+struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
+					struct rpc_xprt *xprt)
+{
+	struct rpc_clnt *clnt = NULL;
+
+	clnt = rpc_new_client(args, xprt, NULL);
+	if (IS_ERR(clnt))
+		return clnt;
+
+	if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
+		int err = rpc_ping(clnt);
+		if (err != 0) {
+			rpc_shutdown_client(clnt);
+			return ERR_PTR(err);
+		}
+	}
+
+	clnt->cl_softrtry = 1;
+	if (args->flags & RPC_CLNT_CREATE_HARDRTRY)
+		clnt->cl_softrtry = 0;
+
+	if (args->flags & RPC_CLNT_CREATE_AUTOBIND)
+		clnt->cl_autobind = 1;
+	if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
+		clnt->cl_discrtry = 1;
+	if (!(args->flags & RPC_CLNT_CREATE_QUIET))
+		clnt->cl_chatty = 1;
+
+	return clnt;
+}
+EXPORT_SYMBOL_GPL(rpc_create_xprt);
+
 /**
  * rpc_create - create an RPC client and transport with one call
  * @args: rpc_clnt create argument structure
@@ -451,7 +483,6 @@ out_no_rpciod:
 struct rpc_clnt *rpc_create(struct rpc_create_args *args)
 {
 	struct rpc_xprt *xprt;
-	struct rpc_clnt *clnt;
 	struct xprt_create xprtargs = {
 		.net = args->net,
 		.ident = args->protocol,
@@ -515,30 +546,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
 	if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
 		xprt->resvport = 0;
 
-	clnt = rpc_new_client(args, xprt, NULL);
-	if (IS_ERR(clnt))
-		return clnt;
-
-	if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
-		int err = rpc_ping(clnt);
-		if (err != 0) {
-			rpc_shutdown_client(clnt);
-			return ERR_PTR(err);
-		}
-	}
-
-	clnt->cl_softrtry = 1;
-	if (args->flags & RPC_CLNT_CREATE_HARDRTRY)
-		clnt->cl_softrtry = 0;
-
-	if (args->flags & RPC_CLNT_CREATE_AUTOBIND)
-		clnt->cl_autobind = 1;
-	if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
-		clnt->cl_discrtry = 1;
-	if (!(args->flags & RPC_CLNT_CREATE_QUIET))
-		clnt->cl_chatty = 1;
-
-	return clnt;
+	return rpc_create_xprt(args, xprt);
 }
 EXPORT_SYMBOL_GPL(rpc_create);
 
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5][RESEND] NFSD/SUNRPC: Check rpc_xprt out of xs_setup_bc_tcp
  2014-03-24  3:54 [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel Kinglong Mee
                   ` (2 preceding siblings ...)
  2014-03-24  3:58 ` [PATCH 3/5][RESEND] SUNRPC: New helper for creating client with rpc_xprt Kinglong Mee
@ 2014-03-24  3:59 ` Kinglong Mee
  2014-03-24  4:00 ` [PATCH 5/5][RESEND] SUNRPC: Clear xpt_bc_xprt if xs_setup_bc_tcp failed Kinglong Mee
  2014-03-31 21:37 ` [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel J. Bruce Fields
  5 siblings, 0 replies; 7+ messages in thread
From: Kinglong Mee @ 2014-03-24  3:59 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Trond Myklebust, Linux NFS Mailing List

Besides checking rpc_xprt out of xs_setup_bc_tcp,
increase it's reference (it's important).

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
---
 fs/nfsd/nfs4callback.c      | 19 ++++++++++++++++++-
 include/linux/sunrpc/xprt.h | 13 ++++++++++++-
 net/sunrpc/xprt.c           | 12 ------------
 net/sunrpc/xprtsock.c       |  9 ---------
 4 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 7f05cd1..39c8ef8 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -32,6 +32,7 @@
  */
 
 #include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/xprt.h>
 #include <linux/sunrpc/svc_xprt.h>
 #include <linux/slab.h>
 #include "nfsd.h"
@@ -635,6 +636,22 @@ static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc
 	}
 }
 
+static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args)
+{
+	struct rpc_xprt *xprt;
+
+	if (args->protocol != XPRT_TRANSPORT_BC_TCP)
+		return rpc_create(args);
+
+	xprt = args->bc_xprt->xpt_bc_xprt;
+	if (xprt) {
+		xprt_get(xprt);
+		return rpc_create_xprt(args, xprt);
+	}
+
+	return rpc_create(args);
+}
+
 static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
 {
 	struct rpc_timeout	timeparms = {
@@ -674,7 +691,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
 		args.authflavor = ses->se_cb_sec.flavor;
 	}
 	/* Create RPC client */
-	client = rpc_create(&args);
+	client = create_backchannel_client(&args);
 	if (IS_ERR(client)) {
 		dprintk("NFSD: couldn't create callback client: %ld\n",
 			PTR_ERR(client));
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 8097b9d..3e5efb2 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -295,13 +295,24 @@ int			xprt_adjust_timeout(struct rpc_rqst *req);
 void			xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
 void			xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task);
 void			xprt_release(struct rpc_task *task);
-struct rpc_xprt *	xprt_get(struct rpc_xprt *xprt);
 void			xprt_put(struct rpc_xprt *xprt);
 struct rpc_xprt *	xprt_alloc(struct net *net, size_t size,
 				unsigned int num_prealloc,
 				unsigned int max_req);
 void			xprt_free(struct rpc_xprt *);
 
+/**
+ * xprt_get - return a reference to an RPC transport.
+ * @xprt: pointer to the transport
+ *
+ */
+static inline struct rpc_xprt *xprt_get(struct rpc_xprt *xprt)
+{
+	if (atomic_inc_not_zero(&xprt->count))
+		return xprt;
+	return NULL;
+}
+
 static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *p)
 {
 	return p + xprt->tsh_size;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 7d4df99..d173f79 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -1383,15 +1383,3 @@ void xprt_put(struct rpc_xprt *xprt)
 	if (atomic_dec_and_test(&xprt->count))
 		xprt_destroy(xprt);
 }
-
-/**
- * xprt_get - return a reference to an RPC transport.
- * @xprt: pointer to the transport
- *
- */
-struct rpc_xprt *xprt_get(struct rpc_xprt *xprt)
-{
-	if (atomic_inc_not_zero(&xprt->count))
-		return xprt;
-	return NULL;
-}
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index da882af..252a56e 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2927,15 +2927,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
 	struct svc_sock *bc_sock;
 	struct rpc_xprt *ret;
 
-	if (args->bc_xprt->xpt_bc_xprt) {
-		/*
-		 * This server connection already has a backchannel
-		 * transport; we can't create a new one, as we wouldn't
-		 * be able to match replies based on xid any more.  So,
-		 * reuse the already-existing one:
-		 */
-		 return args->bc_xprt->xpt_bc_xprt;
-	}
 	xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
 			xprt_tcp_slot_table_entries);
 	if (IS_ERR(xprt))
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5][RESEND] SUNRPC: Clear xpt_bc_xprt if xs_setup_bc_tcp failed
  2014-03-24  3:54 [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel Kinglong Mee
                   ` (3 preceding siblings ...)
  2014-03-24  3:59 ` [PATCH 4/5][RESEND] NFSD/SUNRPC: Check rpc_xprt out of xs_setup_bc_tcp Kinglong Mee
@ 2014-03-24  4:00 ` Kinglong Mee
  2014-03-31 21:37 ` [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel J. Bruce Fields
  5 siblings, 0 replies; 7+ messages in thread
From: Kinglong Mee @ 2014-03-24  4:00 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Trond Myklebust, Linux NFS Mailing List

Don't move the assign of args->bc_xprt->xpt_bc_xprt out of xs_setup_bc_tcp,
because rpc_ping (which is in rpc_create) will using it.

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
---
 net/sunrpc/xprtsock.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 252a56e..e8acd9b 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2986,6 +2986,8 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
 
 	if (try_module_get(THIS_MODULE))
 		return xprt;
+
+	args->bc_xprt->xpt_bc_xprt = NULL;
 	xprt_put(xprt);
 	ret = ERR_PTR(-EINVAL);
 out_err:
-- 
1.8.5.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel
  2014-03-24  3:54 [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel Kinglong Mee
                   ` (4 preceding siblings ...)
  2014-03-24  4:00 ` [PATCH 5/5][RESEND] SUNRPC: Clear xpt_bc_xprt if xs_setup_bc_tcp failed Kinglong Mee
@ 2014-03-31 21:37 ` J. Bruce Fields
  5 siblings, 0 replies; 7+ messages in thread
From: J. Bruce Fields @ 2014-03-31 21:37 UTC (permalink / raw)
  To: Kinglong Mee; +Cc: Trond Myklebust, Linux NFS Mailing List

On Mon, Mar 24, 2014 at 11:54:45AM +0800, Kinglong Mee wrote:
> When using pynfs test-site, I found some memory leak for the backchannel.

All applied, thanks.--b.

> 
> Kinglong Mee (5):
>   NFSD: Using free_conn free connection
>   NFSD: Free backchannel xprt in bc_destroy
>   SUNRPC: New helper for creating client with rpc_xprt
>   NFSD/SUNRPC: Check rpc_xprt out of xs_setup_bc_tcp
>   SUNRPC: Clear xpt_bc_xprt if xs_setup_bc_tcp failed
> 
>  fs/nfsd/nfs4callback.c      | 19 ++++++++++++++-
>  fs/nfsd/nfs4state.c         |  3 ++-
>  include/linux/sunrpc/clnt.h |  2 ++
>  include/linux/sunrpc/xprt.h | 13 +++++++++-
>  net/sunrpc/clnt.c           | 58 ++++++++++++++++++++++++++-------------------
>  net/sunrpc/xprt.c           | 12 ----------
>  net/sunrpc/xprtsock.c       | 15 +++++-------
>  7 files changed, 73 insertions(+), 49 deletions(-)
> 
> -- 
> 1.8.5.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-03-31 21:37 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-24  3:54 [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel Kinglong Mee
2014-03-24  3:56 ` [PATCH 1/5][RESEND] NFSD: Using free_conn free connection Kinglong Mee
2014-03-24  3:58 ` [PATCH 2/5][RESEND] NFSD: Free backchannel xprt in bc_destroy Kinglong Mee
2014-03-24  3:58 ` [PATCH 3/5][RESEND] SUNRPC: New helper for creating client with rpc_xprt Kinglong Mee
2014-03-24  3:59 ` [PATCH 4/5][RESEND] NFSD/SUNRPC: Check rpc_xprt out of xs_setup_bc_tcp Kinglong Mee
2014-03-24  4:00 ` [PATCH 5/5][RESEND] SUNRPC: Clear xpt_bc_xprt if xs_setup_bc_tcp failed Kinglong Mee
2014-03-31 21:37 ` [PATCH 0/5][RESEND]NFSD/SUNRPC: Fix memory leak for the backchannel J. Bruce Fields

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.