public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] lockd: get rid of reference-counted NSM RPC clients
@ 2015-10-07 11:03 Andrey Ryabinin
  2015-10-07 11:28 ` kbuild test robot
  2015-10-07 11:31 ` [PATCH] " kbuild test robot
  0 siblings, 2 replies; 7+ messages in thread
From: Andrey Ryabinin @ 2015-10-07 11:03 UTC (permalink / raw)
  To: Trond Myklebust, Anna Schumaker, J. Bruce Fields, Jeff Layton
  Cc: linux-nfs, linux-kernel, Stanislav Kinsbursky, Andrey Ryabinin

Currently we have reference-counted per-net NSM RPC client
which created on the first monitor request and destroyed
after the last unmonitor request. It's needed because
RPC client need to know 'utsname()->nodename', but utsname()
might be NULL when nsm_unmonitor() called.

So instead of holding the rpc client we could just save nodename
in struct nlm_host and pass it to the rpc_create().
Thus ther is no need in keeping rpc client until last
unmonitor request. We could create separate RPC clients
for each monitor/unmonitor requests.

Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 fs/lockd/host.c             |  1 +
 fs/lockd/mon.c              | 89 ++++++++-------------------------------------
 fs/lockd/netns.h            |  3 --
 fs/lockd/svc.c              |  1 -
 include/linux/lockd/lockd.h |  1 +
 5 files changed, 17 insertions(+), 78 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index b5f3c3a..d716c99 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -161,6 +161,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
 	host->h_nsmhandle  = nsm;
 	host->h_addrbuf    = nsm->sm_addrbuf;
 	host->net	   = ni->net;
+	strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename));
 
 out:
 	return host;
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 6c05cd1..25fa67e 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -42,7 +42,7 @@ struct nsm_args {
 	u32			proc;
 
 	char			*mon_name;
-	char			*nodename;
+	const char		*nodename;
 };
 
 struct nsm_res {
@@ -86,69 +86,18 @@ static struct rpc_clnt *nsm_create(struct net *net, const char *nodename)
 	return rpc_create(&args);
 }
 
-static struct rpc_clnt *nsm_client_set(struct lockd_net *ln,
-		struct rpc_clnt *clnt)
-{
-	spin_lock(&ln->nsm_clnt_lock);
-	if (ln->nsm_users == 0) {
-		if (clnt == NULL)
-			goto out;
-		ln->nsm_clnt = clnt;
-	}
-	clnt = ln->nsm_clnt;
-	ln->nsm_users++;
-out:
-	spin_unlock(&ln->nsm_clnt_lock);
-	return clnt;
-}
-
-static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename)
-{
-	struct rpc_clnt	*clnt, *new;
-	struct lockd_net *ln = net_generic(net, lockd_net_id);
-
-	clnt = nsm_client_set(ln, NULL);
-	if (clnt != NULL)
-		goto out;
-
-	clnt = new = nsm_create(net, nodename);
-	if (IS_ERR(clnt))
-		goto out;
-
-	clnt = nsm_client_set(ln, new);
-	if (clnt != new)
-		rpc_shutdown_client(new);
-out:
-	return clnt;
-}
-
-static void nsm_client_put(struct net *net)
-{
-	struct lockd_net *ln = net_generic(net, lockd_net_id);
-	struct rpc_clnt	*clnt = NULL;
-
-	spin_lock(&ln->nsm_clnt_lock);
-	ln->nsm_users--;
-	if (ln->nsm_users == 0) {
-		clnt = ln->nsm_clnt;
-		ln->nsm_clnt = NULL;
-	}
-	spin_unlock(&ln->nsm_clnt_lock);
-	if (clnt != NULL)
-		rpc_shutdown_client(clnt);
-}
-
 static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
-			 struct rpc_clnt *clnt)
+			 const struct nlm_host *host)
 {
 	int		status;
+	struct rpc_clnt *clnt;
 	struct nsm_args args = {
 		.priv		= &nsm->sm_priv,
 		.prog		= NLM_PROGRAM,
 		.vers		= 3,
 		.proc		= NLMPROC_NSM_NOTIFY,
 		.mon_name	= nsm->sm_mon_name,
-		.nodename	= clnt->cl_nodename,
+		.nodename	= host->nodename,
 	};
 	struct rpc_message msg = {
 		.rpc_argp	= &args,
@@ -157,6 +106,13 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
 
 	memset(res, 0, sizeof(*res));
 
+	clnt = nsm_create(host->net, host->nodename);
+	if (IS_ERR(clnt)) {
+		dprintk("lockd: failed to create NSM upcall transport, "
+			"status=%d, net=%p\n", PTR_ERR(clnt), host->net);
+		return PTR_ERR(clnt);
+	}
+
 	msg.rpc_proc = &clnt->cl_procinfo[proc];
 	status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
 	if (status == -ECONNREFUSED) {
@@ -170,6 +126,8 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
 				status);
 	else
 		status = 0;
+
+	rpc_shutdown_client(clnt);
 	return status;
 }
 
@@ -189,32 +147,19 @@ int nsm_monitor(const struct nlm_host *host)
 	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
 	int		status;
-	struct rpc_clnt *clnt;
-	const char *nodename = NULL;
 
 	dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
 
 	if (nsm->sm_monitored)
 		return 0;
 
-	if (host->h_rpcclnt)
-		nodename = host->h_rpcclnt->cl_nodename;
-
 	/*
 	 * Choose whether to record the caller_name or IP address of
 	 * this peer in the local rpc.statd's database.
 	 */
 	nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
 
-	clnt = nsm_client_get(host->net, nodename);
-	if (IS_ERR(clnt)) {
-		status = PTR_ERR(clnt);
-		dprintk("lockd: failed to create NSM upcall transport, "
-				"status=%d, net=%p\n", status, host->net);
-		return status;
-	}
-
-	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
+	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host);
 	if (unlikely(res.status != 0))
 		status = -EIO;
 	if (unlikely(status < 0)) {
@@ -246,11 +191,9 @@ void nsm_unmonitor(const struct nlm_host *host)
 
 	if (atomic_read(&nsm->sm_count) == 1
 	 && nsm->sm_monitored && !nsm->sm_sticky) {
-		struct lockd_net *ln = net_generic(host->net, lockd_net_id);
-
 		dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
 
-		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt);
+		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host);
 		if (res.status != 0)
 			status = -EIO;
 		if (status < 0)
@@ -258,8 +201,6 @@ void nsm_unmonitor(const struct nlm_host *host)
 					nsm->sm_name);
 		else
 			nsm->sm_monitored = 0;
-
-		nsm_client_put(host->net);
 	}
 }
 
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h
index 89fe011..5426189 100644
--- a/fs/lockd/netns.h
+++ b/fs/lockd/netns.h
@@ -12,9 +12,6 @@ struct lockd_net {
 	struct delayed_work grace_period_end;
 	struct lock_manager lockd_manager;
 
-	spinlock_t nsm_clnt_lock;
-	unsigned int nsm_users;
-	struct rpc_clnt *nsm_clnt;
 	struct list_head nsm_handles;
 };
 
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 0dff13f..5f31ebd 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -592,7 +592,6 @@ static int lockd_init_net(struct net *net)
 	INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
 	INIT_LIST_HEAD(&ln->lockd_manager.list);
 	ln->lockd_manager.block_opens = false;
-	spin_lock_init(&ln->nsm_clnt_lock);
 	INIT_LIST_HEAD(&ln->nsm_handles);
 	return 0;
 }
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index fd3b65b..c153738 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -68,6 +68,7 @@ struct nlm_host {
 	struct nsm_handle	*h_nsmhandle;	/* NSM status handle */
 	char			*h_addrbuf;	/* address eyecatcher */
 	struct net		*net;		/* host net */
+	char			nodename[UNX_MAXNODENAME + 1];
 };
 
 /*
-- 
2.4.9


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

* Re: [PATCH] lockd: get rid of reference-counted NSM RPC clients
  2015-10-07 11:03 [PATCH] lockd: get rid of reference-counted NSM RPC clients Andrey Ryabinin
@ 2015-10-07 11:28 ` kbuild test robot
  2015-10-07 11:39   ` [PATCH v2] " Andrey Ryabinin
  2015-10-07 11:31 ` [PATCH] " kbuild test robot
  1 sibling, 1 reply; 7+ messages in thread
From: kbuild test robot @ 2015-10-07 11:28 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: kbuild-all, Trond Myklebust, Anna Schumaker, J. Bruce Fields,
	Jeff Layton, linux-nfs, linux-kernel, Stanislav Kinsbursky,
	Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 2511 bytes --]

Hi Andrey,

[auto build test WARNING on next-20151007 -- if it's inappropriate base, please ignore]

config: mips-allyesconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=mips 

All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:6:0,
                    from include/linux/kernel.h:13,
                    from fs/lockd/mon.c:10:
   fs/lockd/mon.c: In function 'nsm_mon_unmon':
   include/linux/kern_levels.h:4:18: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
    #define KERN_SOH "\001"  /* ASCII Start Of Header */
                     ^
   include/linux/kern_levels.h:16:22: note: in expansion of macro 'KERN_SOH'
    #define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel */
                         ^
>> include/linux/sunrpc/debug.h:33:11: note: in expansion of macro 'KERN_DEFAULT'
       printk(KERN_DEFAULT args); \
              ^
>> include/linux/sunrpc/debug.h:23:26: note: in expansion of macro 'dfprintk'
    #define dprintk(args...) dfprintk(FACILITY, ## args)
                             ^
>> fs/lockd/mon.c:111:3: note: in expansion of macro 'dprintk'
      dprintk("lockd: failed to create NSM upcall transport, "
      ^

vim +/dprintk +111 fs/lockd/mon.c

    95			.priv		= &nsm->sm_priv,
    96			.prog		= NLM_PROGRAM,
    97			.vers		= 3,
    98			.proc		= NLMPROC_NSM_NOTIFY,
    99			.mon_name	= nsm->sm_mon_name,
   100			.nodename	= host->nodename,
   101		};
   102		struct rpc_message msg = {
   103			.rpc_argp	= &args,
   104			.rpc_resp	= res,
   105		};
   106	
   107		memset(res, 0, sizeof(*res));
   108	
   109		clnt = nsm_create(host->net, host->nodename);
   110		if (IS_ERR(clnt)) {
 > 111			dprintk("lockd: failed to create NSM upcall transport, "
   112				"status=%d, net=%p\n", PTR_ERR(clnt), host->net);
   113			return PTR_ERR(clnt);
   114		}
   115	
   116		msg.rpc_proc = &clnt->cl_procinfo[proc];
   117		status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
   118		if (status == -ECONNREFUSED) {
   119			dprintk("lockd:	NSM upcall RPC failed, status=%d, forcing rebind\n",

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 39683 bytes --]

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

* Re: [PATCH] lockd: get rid of reference-counted NSM RPC clients
  2015-10-07 11:03 [PATCH] lockd: get rid of reference-counted NSM RPC clients Andrey Ryabinin
  2015-10-07 11:28 ` kbuild test robot
@ 2015-10-07 11:31 ` kbuild test robot
  1 sibling, 0 replies; 7+ messages in thread
From: kbuild test robot @ 2015-10-07 11:31 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: kbuild-all, Trond Myklebust, Anna Schumaker, J. Bruce Fields,
	Jeff Layton, linux-nfs, linux-kernel, Stanislav Kinsbursky,
	Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 1725 bytes --]

Hi Andrey,

[auto build test WARNING on next-20151007 -- if it's inappropriate base, please ignore]

config: xtensa-allyesconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All warnings (new ones prefixed by >>):

   fs/lockd/mon.c: In function 'nsm_mon_unmon':
>> fs/lockd/mon.c:111:3: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
      dprintk("lockd: failed to create NSM upcall transport, "
      ^

vim +111 fs/lockd/mon.c

    95			.priv		= &nsm->sm_priv,
    96			.prog		= NLM_PROGRAM,
    97			.vers		= 3,
    98			.proc		= NLMPROC_NSM_NOTIFY,
    99			.mon_name	= nsm->sm_mon_name,
   100			.nodename	= host->nodename,
   101		};
   102		struct rpc_message msg = {
   103			.rpc_argp	= &args,
   104			.rpc_resp	= res,
   105		};
   106	
   107		memset(res, 0, sizeof(*res));
   108	
   109		clnt = nsm_create(host->net, host->nodename);
   110		if (IS_ERR(clnt)) {
 > 111			dprintk("lockd: failed to create NSM upcall transport, "
   112				"status=%d, net=%p\n", PTR_ERR(clnt), host->net);
   113			return PTR_ERR(clnt);
   114		}
   115	
   116		msg.rpc_proc = &clnt->cl_procinfo[proc];
   117		status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
   118		if (status == -ECONNREFUSED) {
   119			dprintk("lockd:	NSM upcall RPC failed, status=%d, forcing rebind\n",

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 42875 bytes --]

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

* [PATCH v2] lockd: get rid of reference-counted NSM RPC clients
  2015-10-07 11:28 ` kbuild test robot
@ 2015-10-07 11:39   ` Andrey Ryabinin
  2015-10-07 20:41     ` J. Bruce Fields
  2015-10-07 21:45     ` Trond Myklebust
  0 siblings, 2 replies; 7+ messages in thread
From: Andrey Ryabinin @ 2015-10-07 11:39 UTC (permalink / raw)
  To: Trond Myklebust, Anna Schumaker, J. Bruce Fields, Jeff Layton
  Cc: linux-nfs, linux-kernel, Stanislav Kinsbursky, kbuild test robot,
	kbuild-all, Andrey Ryabinin

Currently we have reference-counted per-net NSM RPC client
which created on the first monitor request and destroyed
after the last unmonitor request. It's needed because
RPC client need to know 'utsname()->nodename', but utsname()
might be NULL when nsm_unmonitor() called.

So instead of holding the rpc client we could just save nodename
in struct nlm_host and pass it to the rpc_create().
Thus ther is no need in keeping rpc client until last
unmonitor request. We could create separate RPC clients
for each monitor/unmonitor requests.

Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 Changes since v1:
  - fixed build warning:
	 fs/lockd/mon.c:111:3: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]

 fs/lockd/host.c             |  1 +
 fs/lockd/mon.c              | 89 ++++++++-------------------------------------
 fs/lockd/netns.h            |  3 --
 fs/lockd/svc.c              |  1 -
 include/linux/lockd/lockd.h |  1 +
 5 files changed, 17 insertions(+), 78 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index b5f3c3a..d716c99 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -161,6 +161,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
 	host->h_nsmhandle  = nsm;
 	host->h_addrbuf    = nsm->sm_addrbuf;
 	host->net	   = ni->net;
+	strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename));
 
 out:
 	return host;
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 6c05cd1..19166d4 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -42,7 +42,7 @@ struct nsm_args {
 	u32			proc;
 
 	char			*mon_name;
-	char			*nodename;
+	const char		*nodename;
 };
 
 struct nsm_res {
@@ -86,69 +86,18 @@ static struct rpc_clnt *nsm_create(struct net *net, const char *nodename)
 	return rpc_create(&args);
 }
 
-static struct rpc_clnt *nsm_client_set(struct lockd_net *ln,
-		struct rpc_clnt *clnt)
-{
-	spin_lock(&ln->nsm_clnt_lock);
-	if (ln->nsm_users == 0) {
-		if (clnt == NULL)
-			goto out;
-		ln->nsm_clnt = clnt;
-	}
-	clnt = ln->nsm_clnt;
-	ln->nsm_users++;
-out:
-	spin_unlock(&ln->nsm_clnt_lock);
-	return clnt;
-}
-
-static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename)
-{
-	struct rpc_clnt	*clnt, *new;
-	struct lockd_net *ln = net_generic(net, lockd_net_id);
-
-	clnt = nsm_client_set(ln, NULL);
-	if (clnt != NULL)
-		goto out;
-
-	clnt = new = nsm_create(net, nodename);
-	if (IS_ERR(clnt))
-		goto out;
-
-	clnt = nsm_client_set(ln, new);
-	if (clnt != new)
-		rpc_shutdown_client(new);
-out:
-	return clnt;
-}
-
-static void nsm_client_put(struct net *net)
-{
-	struct lockd_net *ln = net_generic(net, lockd_net_id);
-	struct rpc_clnt	*clnt = NULL;
-
-	spin_lock(&ln->nsm_clnt_lock);
-	ln->nsm_users--;
-	if (ln->nsm_users == 0) {
-		clnt = ln->nsm_clnt;
-		ln->nsm_clnt = NULL;
-	}
-	spin_unlock(&ln->nsm_clnt_lock);
-	if (clnt != NULL)
-		rpc_shutdown_client(clnt);
-}
-
 static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
-			 struct rpc_clnt *clnt)
+			 const struct nlm_host *host)
 {
 	int		status;
+	struct rpc_clnt *clnt;
 	struct nsm_args args = {
 		.priv		= &nsm->sm_priv,
 		.prog		= NLM_PROGRAM,
 		.vers		= 3,
 		.proc		= NLMPROC_NSM_NOTIFY,
 		.mon_name	= nsm->sm_mon_name,
-		.nodename	= clnt->cl_nodename,
+		.nodename	= host->nodename,
 	};
 	struct rpc_message msg = {
 		.rpc_argp	= &args,
@@ -157,6 +106,13 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
 
 	memset(res, 0, sizeof(*res));
 
+	clnt = nsm_create(host->net, host->nodename);
+	if (IS_ERR(clnt)) {
+		dprintk("lockd: failed to create NSM upcall transport, "
+			"status=%ld, net=%p\n", PTR_ERR(clnt), host->net);
+		return PTR_ERR(clnt);
+	}
+
 	msg.rpc_proc = &clnt->cl_procinfo[proc];
 	status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
 	if (status == -ECONNREFUSED) {
@@ -170,6 +126,8 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
 				status);
 	else
 		status = 0;
+
+	rpc_shutdown_client(clnt);
 	return status;
 }
 
@@ -189,32 +147,19 @@ int nsm_monitor(const struct nlm_host *host)
 	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
 	int		status;
-	struct rpc_clnt *clnt;
-	const char *nodename = NULL;
 
 	dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
 
 	if (nsm->sm_monitored)
 		return 0;
 
-	if (host->h_rpcclnt)
-		nodename = host->h_rpcclnt->cl_nodename;
-
 	/*
 	 * Choose whether to record the caller_name or IP address of
 	 * this peer in the local rpc.statd's database.
 	 */
 	nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
 
-	clnt = nsm_client_get(host->net, nodename);
-	if (IS_ERR(clnt)) {
-		status = PTR_ERR(clnt);
-		dprintk("lockd: failed to create NSM upcall transport, "
-				"status=%d, net=%p\n", status, host->net);
-		return status;
-	}
-
-	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
+	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host);
 	if (unlikely(res.status != 0))
 		status = -EIO;
 	if (unlikely(status < 0)) {
@@ -246,11 +191,9 @@ void nsm_unmonitor(const struct nlm_host *host)
 
 	if (atomic_read(&nsm->sm_count) == 1
 	 && nsm->sm_monitored && !nsm->sm_sticky) {
-		struct lockd_net *ln = net_generic(host->net, lockd_net_id);
-
 		dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
 
-		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt);
+		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host);
 		if (res.status != 0)
 			status = -EIO;
 		if (status < 0)
@@ -258,8 +201,6 @@ void nsm_unmonitor(const struct nlm_host *host)
 					nsm->sm_name);
 		else
 			nsm->sm_monitored = 0;
-
-		nsm_client_put(host->net);
 	}
 }
 
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h
index 89fe011..5426189 100644
--- a/fs/lockd/netns.h
+++ b/fs/lockd/netns.h
@@ -12,9 +12,6 @@ struct lockd_net {
 	struct delayed_work grace_period_end;
 	struct lock_manager lockd_manager;
 
-	spinlock_t nsm_clnt_lock;
-	unsigned int nsm_users;
-	struct rpc_clnt *nsm_clnt;
 	struct list_head nsm_handles;
 };
 
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 0dff13f..5f31ebd 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -592,7 +592,6 @@ static int lockd_init_net(struct net *net)
 	INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
 	INIT_LIST_HEAD(&ln->lockd_manager.list);
 	ln->lockd_manager.block_opens = false;
-	spin_lock_init(&ln->nsm_clnt_lock);
 	INIT_LIST_HEAD(&ln->nsm_handles);
 	return 0;
 }
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index fd3b65b..c153738 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -68,6 +68,7 @@ struct nlm_host {
 	struct nsm_handle	*h_nsmhandle;	/* NSM status handle */
 	char			*h_addrbuf;	/* address eyecatcher */
 	struct net		*net;		/* host net */
+	char			nodename[UNX_MAXNODENAME + 1];
 };
 
 /*
-- 
2.4.9


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

* Re: [PATCH v2] lockd: get rid of reference-counted NSM RPC clients
  2015-10-07 11:39   ` [PATCH v2] " Andrey Ryabinin
@ 2015-10-07 20:41     ` J. Bruce Fields
  2015-10-07 21:45     ` Trond Myklebust
  1 sibling, 0 replies; 7+ messages in thread
From: J. Bruce Fields @ 2015-10-07 20:41 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: Trond Myklebust, Anna Schumaker, Jeff Layton, linux-nfs,
	linux-kernel, Stanislav Kinsbursky, kbuild test robot, kbuild-all

On Wed, Oct 07, 2015 at 02:39:55PM +0300, Andrey Ryabinin wrote:
> Currently we have reference-counted per-net NSM RPC client
> which created on the first monitor request and destroyed
> after the last unmonitor request. It's needed because
> RPC client need to know 'utsname()->nodename', but utsname()
> might be NULL when nsm_unmonitor() called.
> 
> So instead of holding the rpc client we could just save nodename
> in struct nlm_host and pass it to the rpc_create().
> Thus ther is no need in keeping rpc client until last
> unmonitor request. We could create separate RPC clients
> for each monitor/unmonitor requests.
> 
> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
> ---
>  Changes since v1:
>   - fixed build warning:
> 	 fs/lockd/mon.c:111:3: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
> 
>  fs/lockd/host.c             |  1 +
>  fs/lockd/mon.c              | 89 ++++++++-------------------------------------
>  fs/lockd/netns.h            |  3 --
>  fs/lockd/svc.c              |  1 -
>  include/linux/lockd/lockd.h |  1 +
>  5 files changed, 17 insertions(+), 78 deletions(-)

That's certainly a nice diffstat, thanks for the cleanup.  But
unfortunately this isn't code I look at very often.  One thing I'm
unsure about:

> 
> diff --git a/fs/lockd/host.c b/fs/lockd/host.c
> index b5f3c3a..d716c99 100644
> --- a/fs/lockd/host.c
> +++ b/fs/lockd/host.c
> @@ -161,6 +161,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
>  	host->h_nsmhandle  = nsm;
>  	host->h_addrbuf    = nsm->sm_addrbuf;
>  	host->net	   = ni->net;
> +	strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename));
>  
>  out:
>  	return host;
> diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
> index 6c05cd1..19166d4 100644
> --- a/fs/lockd/mon.c
> +++ b/fs/lockd/mon.c
> @@ -42,7 +42,7 @@ struct nsm_args {
>  	u32			proc;
>  
>  	char			*mon_name;
> -	char			*nodename;
> +	const char		*nodename;
>  };
>  
>  struct nsm_res {
> @@ -86,69 +86,18 @@ static struct rpc_clnt *nsm_create(struct net *net, const char *nodename)
>  	return rpc_create(&args);
>  }
>  
> -static struct rpc_clnt *nsm_client_set(struct lockd_net *ln,
> -		struct rpc_clnt *clnt)
> -{
> -	spin_lock(&ln->nsm_clnt_lock);
> -	if (ln->nsm_users == 0) {
> -		if (clnt == NULL)
> -			goto out;
> -		ln->nsm_clnt = clnt;
> -	}
> -	clnt = ln->nsm_clnt;
> -	ln->nsm_users++;
> -out:
> -	spin_unlock(&ln->nsm_clnt_lock);
> -	return clnt;
> -}
> -
> -static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename)
> -{
> -	struct rpc_clnt	*clnt, *new;
> -	struct lockd_net *ln = net_generic(net, lockd_net_id);
> -
> -	clnt = nsm_client_set(ln, NULL);
> -	if (clnt != NULL)
> -		goto out;
> -
> -	clnt = new = nsm_create(net, nodename);
> -	if (IS_ERR(clnt))
> -		goto out;
> -
> -	clnt = nsm_client_set(ln, new);
> -	if (clnt != new)
> -		rpc_shutdown_client(new);
> -out:
> -	return clnt;
> -}
> -
> -static void nsm_client_put(struct net *net)
> -{
> -	struct lockd_net *ln = net_generic(net, lockd_net_id);
> -	struct rpc_clnt	*clnt = NULL;
> -
> -	spin_lock(&ln->nsm_clnt_lock);
> -	ln->nsm_users--;
> -	if (ln->nsm_users == 0) {
> -		clnt = ln->nsm_clnt;
> -		ln->nsm_clnt = NULL;
> -	}
> -	spin_unlock(&ln->nsm_clnt_lock);
> -	if (clnt != NULL)
> -		rpc_shutdown_client(clnt);
> -}
> -
>  static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
> -			 struct rpc_clnt *clnt)
> +			 const struct nlm_host *host)
>  {
>  	int		status;
> +	struct rpc_clnt *clnt;
>  	struct nsm_args args = {
>  		.priv		= &nsm->sm_priv,
>  		.prog		= NLM_PROGRAM,
>  		.vers		= 3,
>  		.proc		= NLMPROC_NSM_NOTIFY,
>  		.mon_name	= nsm->sm_mon_name,
> -		.nodename	= clnt->cl_nodename,
> +		.nodename	= host->nodename,
>  	};
>  	struct rpc_message msg = {
>  		.rpc_argp	= &args,
> @@ -157,6 +106,13 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
>  
>  	memset(res, 0, sizeof(*res));
>  
> +	clnt = nsm_create(host->net, host->nodename);
> +	if (IS_ERR(clnt)) {
> +		dprintk("lockd: failed to create NSM upcall transport, "
> +			"status=%ld, net=%p\n", PTR_ERR(clnt), host->net);
> +		return PTR_ERR(clnt);
> +	}
> +
>  	msg.rpc_proc = &clnt->cl_procinfo[proc];
>  	status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
>  	if (status == -ECONNREFUSED) {
> @@ -170,6 +126,8 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
>  				status);
>  	else
>  		status = 0;
> +
> +	rpc_shutdown_client(clnt);
>  	return status;
>  }
>  
> @@ -189,32 +147,19 @@ int nsm_monitor(const struct nlm_host *host)
>  	struct nsm_handle *nsm = host->h_nsmhandle;
>  	struct nsm_res	res;
>  	int		status;
> -	struct rpc_clnt *clnt;
> -	const char *nodename = NULL;
>  
>  	dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
>  
>  	if (nsm->sm_monitored)
>  		return 0;
>  
> -	if (host->h_rpcclnt)
> -		nodename = host->h_rpcclnt->cl_nodename;
> -
>  	/*
>  	 * Choose whether to record the caller_name or IP address of
>  	 * this peer in the local rpc.statd's database.
>  	 */
>  	nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
>  
> -	clnt = nsm_client_get(host->net, nodename);
> -	if (IS_ERR(clnt)) {
> -		status = PTR_ERR(clnt);
> -		dprintk("lockd: failed to create NSM upcall transport, "
> -				"status=%d, net=%p\n", status, host->net);
> -		return status;
> -	}
> -
> -	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
> +	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host);

OK, so here and in nsm_unmonitor we're unconditionally creating a new
rpc client every time, where previously we might have been reusing a
cached one?

In particular, I *think* the reference counting means that we never
actually had to create a new rpc client in the nsm_unmonitor case.  Are
we sure doing so doesn't cause any problems?

But I don't know this code well and haven't tried to review this
carefully, I may be worrying about nothing.

--b.

>  	if (unlikely(res.status != 0))
>  		status = -EIO;
>  	if (unlikely(status < 0)) {
> @@ -246,11 +191,9 @@ void nsm_unmonitor(const struct nlm_host *host)
>  
>  	if (atomic_read(&nsm->sm_count) == 1
>  	 && nsm->sm_monitored && !nsm->sm_sticky) {
> -		struct lockd_net *ln = net_generic(host->net, lockd_net_id);
> -
>  		dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
>  
> -		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt);
> +		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host);
>  		if (res.status != 0)
>  			status = -EIO;
>  		if (status < 0)
> @@ -258,8 +201,6 @@ void nsm_unmonitor(const struct nlm_host *host)
>  					nsm->sm_name);
>  		else
>  			nsm->sm_monitored = 0;
> -
> -		nsm_client_put(host->net);
>  	}
>  }
>  
> diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h
> index 89fe011..5426189 100644
> --- a/fs/lockd/netns.h
> +++ b/fs/lockd/netns.h
> @@ -12,9 +12,6 @@ struct lockd_net {
>  	struct delayed_work grace_period_end;
>  	struct lock_manager lockd_manager;
>  
> -	spinlock_t nsm_clnt_lock;
> -	unsigned int nsm_users;
> -	struct rpc_clnt *nsm_clnt;
>  	struct list_head nsm_handles;
>  };
>  
> diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
> index 0dff13f..5f31ebd 100644
> --- a/fs/lockd/svc.c
> +++ b/fs/lockd/svc.c
> @@ -592,7 +592,6 @@ static int lockd_init_net(struct net *net)
>  	INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
>  	INIT_LIST_HEAD(&ln->lockd_manager.list);
>  	ln->lockd_manager.block_opens = false;
> -	spin_lock_init(&ln->nsm_clnt_lock);
>  	INIT_LIST_HEAD(&ln->nsm_handles);
>  	return 0;
>  }
> diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
> index fd3b65b..c153738 100644
> --- a/include/linux/lockd/lockd.h
> +++ b/include/linux/lockd/lockd.h
> @@ -68,6 +68,7 @@ struct nlm_host {
>  	struct nsm_handle	*h_nsmhandle;	/* NSM status handle */
>  	char			*h_addrbuf;	/* address eyecatcher */
>  	struct net		*net;		/* host net */
> +	char			nodename[UNX_MAXNODENAME + 1];
>  };
>  
>  /*
> -- 
> 2.4.9

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

* Re: [PATCH v2] lockd: get rid of reference-counted NSM RPC clients
  2015-10-07 11:39   ` [PATCH v2] " Andrey Ryabinin
  2015-10-07 20:41     ` J. Bruce Fields
@ 2015-10-07 21:45     ` Trond Myklebust
  2015-10-08 12:16       ` J. Bruce Fields
  1 sibling, 1 reply; 7+ messages in thread
From: Trond Myklebust @ 2015-10-07 21:45 UTC (permalink / raw)
  To: Andrey Ryabinin
  Cc: Anna Schumaker, J. Bruce Fields, Jeff Layton,
	Linux NFS Mailing List, Linux Kernel Mailing List,
	Stanislav Kinsbursky, kbuild test robot, kbuild-all

On Wed, Oct 7, 2015 at 7:39 AM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
> Currently we have reference-counted per-net NSM RPC client
> which created on the first monitor request and destroyed
> after the last unmonitor request. It's needed because
> RPC client need to know 'utsname()->nodename', but utsname()
> might be NULL when nsm_unmonitor() called.
>

The other reason for keeping the rpc_client around is to avoid a need
to do portmapper/rpcbind lookups in a net namespace that may be in the
process of shutting down. This patchset will reintroduce that
requirement.

Cheers
  Trond

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

* Re: [PATCH v2] lockd: get rid of reference-counted NSM RPC clients
  2015-10-07 21:45     ` Trond Myklebust
@ 2015-10-08 12:16       ` J. Bruce Fields
  0 siblings, 0 replies; 7+ messages in thread
From: J. Bruce Fields @ 2015-10-08 12:16 UTC (permalink / raw)
  To: Trond Myklebust
  Cc: Andrey Ryabinin, Anna Schumaker, Jeff Layton,
	Linux NFS Mailing List, Linux Kernel Mailing List,
	Stanislav Kinsbursky, kbuild test robot, kbuild-all

On Wed, Oct 07, 2015 at 05:45:15PM -0400, Trond Myklebust wrote:
> On Wed, Oct 7, 2015 at 7:39 AM, Andrey Ryabinin <aryabinin@virtuozzo.com> wrote:
> > Currently we have reference-counted per-net NSM RPC client
> > which created on the first monitor request and destroyed
> > after the last unmonitor request. It's needed because
> > RPC client need to know 'utsname()->nodename', but utsname()
> > might be NULL when nsm_unmonitor() called.
> >
> 
> The other reason for keeping the rpc_client around is to avoid a need
> to do portmapper/rpcbind lookups in a net namespace that may be in the
> process of shutting down. This patchset will reintroduce that
> requirement.

Oops, yes, I think I remember now our dealing with that issue before.

So, that dooms this approach, sorry!

--b.

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

end of thread, other threads:[~2015-10-08 12:16 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-07 11:03 [PATCH] lockd: get rid of reference-counted NSM RPC clients Andrey Ryabinin
2015-10-07 11:28 ` kbuild test robot
2015-10-07 11:39   ` [PATCH v2] " Andrey Ryabinin
2015-10-07 20:41     ` J. Bruce Fields
2015-10-07 21:45     ` Trond Myklebust
2015-10-08 12:16       ` J. Bruce Fields
2015-10-07 11:31 ` [PATCH] " kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox