All of lore.kernel.org
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: "J. Bruce Fields" <bfields@fieldses.org>,
	Chuck Lever <chuck.lever@oracle.com>
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH 17/19] SUNRPC: always treat sv_nrpools==1 as "not pooled"
Date: Tue, 23 Nov 2021 12:29:35 +1100	[thread overview]
Message-ID: <163763097550.7284.8119486795641356296.stgit@noble.brown> (raw)
In-Reply-To: <163763078330.7284.10141477742275086758.stgit@noble.brown>

Currently 'pooled' services hold a reference on the pool_map, and
'unpooled' services do not.
svc_destroy() uses the presence of ->svo_function (via
svc_serv_is_pooled()) to determine if the reference should be dropped.
There is no direct correlation between being pooled and the use of
svo_function, though in practice, lockd is the only non-pooled service,
and the only one not to use svc_function.

This is untidy and would cause problems if we changed lockd to use
svc_set_num_threads(), which requires the use of ->svo_function.

So change the test for "is the service pooled" to "is sv_nrpools > 1".

This means that when svc_pool_map_get() returns 1, it must NOT take a
reference to the pool.

We discard svc_serv_is_pooled(), and test sv_nrpools directly.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 net/sunrpc/svc.c |   54 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index f0dd9ef7e0cd..5fbe7f55289e 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -37,8 +37,6 @@
 
 static void svc_unregister(const struct svc_serv *serv, struct net *net);
 
-#define svc_serv_is_pooled(serv)    ((serv)->sv_ops->svo_function)
-
 #define SVC_POOL_DEFAULT	SVC_POOL_GLOBAL
 
 /*
@@ -240,8 +238,10 @@ svc_pool_map_init_pernode(struct svc_pool_map *m)
 
 /*
  * Add a reference to the global map of cpus to pools (and
- * vice versa).  Initialise the map if we're the first user.
- * Returns the number of pools.
+ * vice versa) if pools are in use.
+ * Initialise the map if we're the first user.
+ * Returns the number of pools. If this is '1', no reference
+ * was taken.
  */
 static unsigned int
 svc_pool_map_get(void)
@@ -253,6 +253,7 @@ svc_pool_map_get(void)
 
 	if (m->count++) {
 		mutex_unlock(&svc_pool_map_mutex);
+		WARN_ON_ONCE(m->npools <= 1);
 		return m->npools;
 	}
 
@@ -268,29 +269,36 @@ svc_pool_map_get(void)
 		break;
 	}
 
-	if (npools < 0) {
+	if (npools <= 0) {
 		/* default, or memory allocation failure */
 		npools = 1;
 		m->mode = SVC_POOL_GLOBAL;
 	}
 	m->npools = npools;
 
+	if (npools == 1)
+		/* service is unpooled, so doesn't hold a reference */
+		m->count--;
+
 	mutex_unlock(&svc_pool_map_mutex);
-	return m->npools;
+	return npools;
 }
 
 /*
- * Drop a reference to the global map of cpus to pools.
+ * Drop a reference to the global map of cpus to pools, if
+ * pools were in use, i.e. if npools > 1.
  * When the last reference is dropped, the map data is
  * freed; this allows the sysadmin to change the pool
  * mode using the pool_mode module option without
  * rebooting or re-loading sunrpc.ko.
  */
 static void
-svc_pool_map_put(void)
+svc_pool_map_put(int npools)
 {
 	struct svc_pool_map *m = &svc_pool_map;
 
+	if (npools <= 1)
+		return;
 	mutex_lock(&svc_pool_map_mutex);
 
 	if (!--m->count) {
@@ -359,21 +367,18 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
 	struct svc_pool_map *m = &svc_pool_map;
 	unsigned int pidx = 0;
 
-	/*
-	 * An uninitialised map happens in a pure client when
-	 * lockd is brought up, so silently treat it the
-	 * same as SVC_POOL_GLOBAL.
-	 */
-	if (svc_serv_is_pooled(serv)) {
-		switch (m->mode) {
-		case SVC_POOL_PERCPU:
-			pidx = m->to_pool[cpu];
-			break;
-		case SVC_POOL_PERNODE:
-			pidx = m->to_pool[cpu_to_node(cpu)];
-			break;
-		}
+	if (serv->sv_nrpools <= 1)
+		return serv->sv_pools;
+
+	switch (m->mode) {
+	case SVC_POOL_PERCPU:
+		pidx = m->to_pool[cpu];
+		break;
+	case SVC_POOL_PERNODE:
+		pidx = m->to_pool[cpu_to_node(cpu)];
+		break;
 	}
+
 	return &serv->sv_pools[pidx % serv->sv_nrpools];
 }
 
@@ -526,7 +531,7 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
 		goto out_err;
 	return serv;
 out_err:
-	svc_pool_map_put();
+	svc_pool_map_put(npools);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(svc_create_pooled);
@@ -561,8 +566,7 @@ svc_destroy(struct kref *ref)
 
 	cache_clean_deferred(serv);
 
-	if (svc_serv_is_pooled(serv))
-		svc_pool_map_put();
+	svc_pool_map_put(serv->sv_nrpools);
 
 	kfree(serv->sv_pools);
 	kfree(serv);



  parent reply	other threads:[~2021-11-23  1:32 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-23  1:29 [PATCH 00/19 v2] SUNRPC: clean up server thread management NeilBrown
2021-11-23  1:29 ` [PATCH 15/19] lockd: rename lockd_create_svc() to lockd_get() NeilBrown
2021-11-23  1:29 ` [PATCH 13/19] lockd: move svc_exit_thread() into the thread NeilBrown
2021-11-23  1:29 ` [PATCH 06/19] NFSD: narrow nfsd_mutex protection in nfsd thread NeilBrown
2021-11-23  1:29 ` [PATCH 05/19] SUNRPC: use sv_lock to protect updates to sv_nrthreads NeilBrown
2021-11-23 16:43   ` Chuck Lever III
2021-11-29  0:11     ` NeilBrown
2021-11-23  1:29 ` [PATCH 10/19] lockd: introduce nlmsvc_serv NeilBrown
2021-11-23  1:29 ` [PATCH 14/19] lockd: introduce lockd_put() NeilBrown
2021-11-23  1:29 ` [PATCH 02/19] NFSD: handle error better in write_ports_addfd() NeilBrown
2021-11-23 16:44   ` Chuck Lever III
2021-11-28 23:49     ` NeilBrown
2021-11-23  1:29 ` [PATCH 12/19] lockd: move lockd_start_svc() call into lockd_create_svc() NeilBrown
2021-11-23  1:29 ` [PATCH 16/19] SUNRPC: move the pool_map definitions (back) into svc.c NeilBrown
2021-11-23  1:29 ` [PATCH 07/19] NFSD: Make it possible to use svc_set_num_threads_sync NeilBrown
2021-11-23  1:29 ` [PATCH 04/19] nfsd: make nfsd_stats.th_cnt atomic_t NeilBrown
2021-11-23  1:29 ` [PATCH 01/19] SUNRPC/NFSD: clean up get/put functions NeilBrown
2021-11-23 16:45   ` Chuck Lever III
2021-11-28 23:36     ` NeilBrown
2021-11-23  1:29 ` [PATCH 18/19] lockd: use svc_set_num_threads() for thread start and stop NeilBrown
2021-11-23  1:29 ` [PATCH 09/19] NFSD: simplify locking for network notifier NeilBrown
2021-11-23  1:29 ` [PATCH 11/19] lockd: simplify management of network status notifiers NeilBrown
2021-11-23  1:29 ` [PATCH 08/19] SUNRPC: discard svo_setup and rename svc_set_num_threads_sync() NeilBrown
2021-11-23  1:29 ` [PATCH 19/19] NFS: switch the callback service back to non-pooled NeilBrown
2021-11-23  1:29 ` [PATCH 03/19] SUNRPC: stop using ->sv_nrthreads as a refcount NeilBrown
2021-11-23  1:29 ` NeilBrown [this message]
2021-11-23 14:49 ` [PATCH 00/19 v2] SUNRPC: clean up server thread management J. Bruce Fields
2021-11-24 18:42   ` Chuck Lever III

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=163763097550.7284.8119486795641356296.stgit@noble.brown \
    --to=neilb@suse.de \
    --cc=bfields@fieldses.org \
    --cc=chuck.lever@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.