Commit 6b044fba authored by NeilBrown's avatar NeilBrown Committed by Chuck Lever
Browse files

lockd: use svc_set_num_threads() for thread start and stop



svc_set_num_threads() does everything that lockd_start_svc() does, except
set sv_maxconn.  It also (when passed 0) finds the threads and
stops them with kthread_stop().

So move the setting for sv_maxconn, and use svc_set_num_thread()

We now don't need nlmsvc_task.

Now that we use svc_set_num_threads() it makes sense to set svo_module.
This request that the thread exists with module_put_and_exit().
Also fix the documentation for svo_module to make this explicit.

svc_prepare_thread is now only used where it is defined, so it can be
made static.

Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 93aa619e
Loading
Loading
Loading
Loading
+8 −50
Original line number Diff line number Diff line
@@ -55,7 +55,6 @@ EXPORT_SYMBOL_GPL(nlmsvc_ops);
static DEFINE_MUTEX(nlmsvc_mutex);
static unsigned int		nlmsvc_users;
static struct svc_serv		*nlmsvc_serv;
static struct task_struct	*nlmsvc_task;
unsigned long			nlmsvc_timeout;

unsigned int lockd_net_id;
@@ -186,7 +185,7 @@ lockd(void *vrqstp)

	svc_exit_thread(rqstp);

	return 0;
	module_put_and_exit(0);
}

static int create_lockd_listener(struct svc_serv *serv, const char *name,
@@ -292,8 +291,8 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net)
				__func__, net->ns.inum);
		}
	} else {
		pr_err("%s: no users! task=%p, net=%x\n",
			__func__, nlmsvc_task, net->ns.inum);
		pr_err("%s: no users! net=%x\n",
			__func__, net->ns.inum);
		BUG();
	}
}
@@ -351,49 +350,11 @@ static struct notifier_block lockd_inet6addr_notifier = {
};
#endif

static int lockd_start_svc(struct svc_serv *serv)
{
	int error;
	struct svc_rqst *rqst;

	/*
	 * Create the kernel thread and wait for it to start.
	 */
	rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
	if (IS_ERR(rqst)) {
		error = PTR_ERR(rqst);
		printk(KERN_WARNING
			"lockd_up: svc_rqst allocation failed, error=%d\n",
			error);
		goto out_rqst;
	}

	svc_sock_update_bufs(serv);
	serv->sv_maxconn = nlm_max_connections;

	nlmsvc_task = kthread_create(lockd, rqst, "%s", serv->sv_name);
	if (IS_ERR(nlmsvc_task)) {
		error = PTR_ERR(nlmsvc_task);
		printk(KERN_WARNING
			"lockd_up: kthread_run failed, error=%d\n", error);
		goto out_task;
	}
	rqst->rq_task = nlmsvc_task;
	wake_up_process(nlmsvc_task);

	dprintk("lockd_up: service started\n");
	return 0;

out_task:
	svc_exit_thread(rqst);
	nlmsvc_task = NULL;
out_rqst:
	return error;
}

static const struct svc_serv_ops lockd_sv_ops = {
	.svo_shutdown		= svc_rpcb_cleanup,
	.svo_function		= lockd,
	.svo_enqueue_xprt	= svc_xprt_do_enqueue,
	.svo_module		= THIS_MODULE,
};

static int lockd_get(void)
@@ -425,7 +386,8 @@ static int lockd_get(void)
		return -ENOMEM;
	}

	error = lockd_start_svc(serv);
	serv->sv_maxconn = nlm_max_connections;
	error = svc_set_num_threads(serv, NULL, 1);
	/* The thread now holds the only reference */
	svc_put(serv);
	if (error < 0)
@@ -453,11 +415,7 @@ static void lockd_put(void)
	unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
#endif

	if (nlmsvc_task) {
		kthread_stop(nlmsvc_task);
		dprintk("lockd_down: service stopped\n");
		nlmsvc_task = NULL;
	}
	svc_set_num_threads(nlmsvc_serv, NULL, 0);
	nlmsvc_serv = NULL;
	dprintk("lockd_down: service destroyed\n");
}
+3 −3
Original line number Diff line number Diff line
@@ -64,7 +64,9 @@ struct svc_serv_ops {
	/* queue up a transport for servicing */
	void		(*svo_enqueue_xprt)(struct svc_xprt *);

	/* optional module to count when adding threads (pooled svcs only) */
	/* optional module to count when adding threads.
	 * Thread function must call module_put_and_exit() to exit.
	 */
	struct module	*svo_module;
};

@@ -504,8 +506,6 @@ struct svc_serv *svc_create(struct svc_program *, unsigned int,
			    const struct svc_serv_ops *);
struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv,
					struct svc_pool *pool, int node);
struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
					struct svc_pool *pool, int node);
void		   svc_rqst_replace_page(struct svc_rqst *rqstp,
					 struct page *page);
void		   svc_rqst_free(struct svc_rqst *);
+1 −2
Original line number Diff line number Diff line
@@ -652,7 +652,7 @@ svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node)
}
EXPORT_SYMBOL_GPL(svc_rqst_alloc);

struct svc_rqst *
static struct svc_rqst *
svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
{
	struct svc_rqst	*rqstp;
@@ -672,7 +672,6 @@ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
	spin_unlock_bh(&pool->sp_lock);
	return rqstp;
}
EXPORT_SYMBOL_GPL(svc_prepare_thread);

/*
 * Choose a pool in which to create a new thread, for svc_set_num_threads