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

SUNRPC: change how svc threads are asked to exit.



svc threads are currently stopped using kthread_stop().  This requires
identifying a specific thread.  However we don't care which thread
stops, just as long as one does.

So instead, set a flag in the svc_pool to say that a thread needs to
die, and have each thread check this flag instead of calling
kthread_should_stop().  The first thread to find and clear this flag
then moves towards exiting.

This removes an explicit dependency on sp_all_threads which will make a
future patch simpler.

Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent f4578ba1
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@
#include <linux/uio.h>
#include <linux/smp.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/inetdevice.h>

@@ -135,11 +134,11 @@ lockd(void *vrqstp)
	 * The main request loop. We don't terminate until the last
	 * NFS mount or NFS daemon has gone away.
	 */
	while (!kthread_should_stop()) {
	while (!svc_thread_should_stop(rqstp)) {
		/* update sv_maxconn if it has changed */
		rqstp->rq_server->sv_maxconn = nlm_max_connections;

		nlmsvc_retry_blocked();
		nlmsvc_retry_blocked(rqstp);
		svc_recv(rqstp);
	}
	if (nlmsvc_ops)
+2 −3
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include <linux/sunrpc/svc_xprt.h>
#include <linux/lockd/nlm.h>
#include <linux/lockd/lockd.h>
#include <linux/kthread.h>
#include <linux/exportfs.h>

#define NLMDBG_FACILITY		NLMDBG_SVCLOCK
@@ -1032,13 +1031,13 @@ retry_deferred_block(struct nlm_block *block)
 * be retransmitted.
 */
void
nlmsvc_retry_blocked(void)
nlmsvc_retry_blocked(struct svc_rqst *rqstp)
{
	unsigned long	timeout = MAX_SCHEDULE_TIMEOUT;
	struct nlm_block *block;

	spin_lock(&nlm_blocked_lock);
	while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
	while (!list_empty(&nlm_blocked) && !svc_thread_should_stop(rqstp)) {
		block = list_entry(nlm_blocked.next, struct nlm_block, b_list);

		if (block->b_when == NLM_NEVER)
+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ nfs4_callback_svc(void *vrqstp)

	set_freezable();

	while (!kthread_should_stop())
	while (!svc_thread_should_stop(rqstp))
		svc_recv(rqstp);

	svc_exit_thread(rqstp);
+5 −3
Original line number Diff line number Diff line
@@ -1329,7 +1329,8 @@ extern void nfs_sb_deactive(struct super_block *sb);
 * setup a work entry in the ssc delayed unmount list.
 */
static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr,
				  struct nfsd4_ssc_umount_item **nsui)
				  struct nfsd4_ssc_umount_item **nsui,
				  struct svc_rqst *rqstp)
{
	struct nfsd4_ssc_umount_item *ni = NULL;
	struct nfsd4_ssc_umount_item *work = NULL;
@@ -1351,7 +1352,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr,
			spin_unlock(&nn->nfsd_ssc_lock);

			/* allow 20secs for mount/unmount for now - revisit */
			if (kthread_should_stop() ||
			if (svc_thread_should_stop(rqstp) ||
					(schedule_timeout(20*HZ) == 0)) {
				finish_wait(&nn->nfsd_ssc_waitq, &wait);
				kfree(work);
@@ -1467,7 +1468,7 @@ nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp,
		goto out_free_rawdata;
	snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep);

	status = nfsd4_ssc_setup_dul(nn, ipaddr, nsui);
	status = nfsd4_ssc_setup_dul(nn, ipaddr, nsui, rqstp);
	if (status)
		goto out_free_devname;
	if ((*nsui)->nsui_vfsmount)
@@ -1642,6 +1643,7 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy,
	if (bytes_total == 0)
		bytes_total = ULLONG_MAX;
	do {
		/* Only async copies can be stopped here */
		if (kthread_should_stop())
			break;
		bytes_copied = nfsd_copy_file_range(src, src_pos, dst, dst_pos,
+1 −1
Original line number Diff line number Diff line
@@ -957,7 +957,7 @@ nfsd(void *vrqstp)
	/*
	 * The main request loop
	 */
	while (!kthread_should_stop()) {
	while (!svc_thread_should_stop(rqstp)) {
		/* Update sv_maxconn if it has changed */
		rqstp->rq_server->sv_maxconn = nn->max_connections;

Loading