Skip to content

Commit 93aa619

Browse files
neilbrownchucklever
authored andcommitted
SUNRPC: always treat sv_nrpools==1 as "not pooled"
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 svo_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> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent cf0e124 commit 93aa619

1 file changed

Lines changed: 29 additions & 25 deletions

File tree

net/sunrpc/svc.c

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737

3838
static void svc_unregister(const struct svc_serv *serv, struct net *net);
3939

40-
#define svc_serv_is_pooled(serv) ((serv)->sv_ops->svo_function)
41-
4240
#define SVC_POOL_DEFAULT SVC_POOL_GLOBAL
4341

4442
/*
@@ -240,8 +238,10 @@ svc_pool_map_init_pernode(struct svc_pool_map *m)
240238

241239
/*
242240
* Add a reference to the global map of cpus to pools (and
243-
* vice versa). Initialise the map if we're the first user.
244-
* Returns the number of pools.
241+
* vice versa) if pools are in use.
242+
* Initialise the map if we're the first user.
243+
* Returns the number of pools. If this is '1', no reference
244+
* was taken.
245245
*/
246246
static unsigned int
247247
svc_pool_map_get(void)
@@ -253,6 +253,7 @@ svc_pool_map_get(void)
253253

254254
if (m->count++) {
255255
mutex_unlock(&svc_pool_map_mutex);
256+
WARN_ON_ONCE(m->npools <= 1);
256257
return m->npools;
257258
}
258259

@@ -268,29 +269,36 @@ svc_pool_map_get(void)
268269
break;
269270
}
270271

271-
if (npools < 0) {
272+
if (npools <= 0) {
272273
/* default, or memory allocation failure */
273274
npools = 1;
274275
m->mode = SVC_POOL_GLOBAL;
275276
}
276277
m->npools = npools;
277278

279+
if (npools == 1)
280+
/* service is unpooled, so doesn't hold a reference */
281+
m->count--;
282+
278283
mutex_unlock(&svc_pool_map_mutex);
279-
return m->npools;
284+
return npools;
280285
}
281286

282287
/*
283-
* Drop a reference to the global map of cpus to pools.
288+
* Drop a reference to the global map of cpus to pools, if
289+
* pools were in use, i.e. if npools > 1.
284290
* When the last reference is dropped, the map data is
285291
* freed; this allows the sysadmin to change the pool
286292
* mode using the pool_mode module option without
287293
* rebooting or re-loading sunrpc.ko.
288294
*/
289295
static void
290-
svc_pool_map_put(void)
296+
svc_pool_map_put(int npools)
291297
{
292298
struct svc_pool_map *m = &svc_pool_map;
293299

300+
if (npools <= 1)
301+
return;
294302
mutex_lock(&svc_pool_map_mutex);
295303

296304
if (!--m->count) {
@@ -359,21 +367,18 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
359367
struct svc_pool_map *m = &svc_pool_map;
360368
unsigned int pidx = 0;
361369

362-
/*
363-
* An uninitialised map happens in a pure client when
364-
* lockd is brought up, so silently treat it the
365-
* same as SVC_POOL_GLOBAL.
366-
*/
367-
if (svc_serv_is_pooled(serv)) {
368-
switch (m->mode) {
369-
case SVC_POOL_PERCPU:
370-
pidx = m->to_pool[cpu];
371-
break;
372-
case SVC_POOL_PERNODE:
373-
pidx = m->to_pool[cpu_to_node(cpu)];
374-
break;
375-
}
370+
if (serv->sv_nrpools <= 1)
371+
return serv->sv_pools;
372+
373+
switch (m->mode) {
374+
case SVC_POOL_PERCPU:
375+
pidx = m->to_pool[cpu];
376+
break;
377+
case SVC_POOL_PERNODE:
378+
pidx = m->to_pool[cpu_to_node(cpu)];
379+
break;
376380
}
381+
377382
return &serv->sv_pools[pidx % serv->sv_nrpools];
378383
}
379384

@@ -526,7 +531,7 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
526531
goto out_err;
527532
return serv;
528533
out_err:
529-
svc_pool_map_put();
534+
svc_pool_map_put(npools);
530535
return NULL;
531536
}
532537
EXPORT_SYMBOL_GPL(svc_create_pooled);
@@ -561,8 +566,7 @@ svc_destroy(struct kref *ref)
561566

562567
cache_clean_deferred(serv);
563568

564-
if (svc_serv_is_pooled(serv))
565-
svc_pool_map_put();
569+
svc_pool_map_put(serv->sv_nrpools);
566570

567571
kfree(serv->sv_pools);
568572
kfree(serv);

0 commit comments

Comments
 (0)