Re: [PATCH 4/5] knfsd: convert knfsd to kthread API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 6 Jun 2008 13:24:31 -0400
"J. Bruce Fields" <bfields@xxxxxxxxxxxx> wrote:

> On Fri, Jun 06, 2008 at 11:12:50AM -0400, Jeff Layton wrote:
> > This patch is rather large, but I couldn't figure out a way to break it
> > up that would remain bisectable. It does several things:
> > 
> > - change svc_thread_fn typedef to better match what kthread_create expects
> > - change svc_pool_map_set_cpumask to be more kthread friendly. Make it
> >   take a task arg and and get rid of the "oldmask"
> > - have svc_set_num_threads call kthread_create directly
> > - eliminate __svc_create_thread
> > 
> > Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> > ---
> >  fs/nfsd/nfssvc.c           |   52 ++++++++++++++--------
> >  include/linux/sunrpc/svc.h |    2 +-
> >  net/sunrpc/svc.c           |  102 +++++++++++++++-----------------------------
> >  3 files changed, 68 insertions(+), 88 deletions(-)
> > 
> > diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> > index 6339cb7..fe62ec8 100644
> > --- a/fs/nfsd/nfssvc.c
> > +++ b/fs/nfsd/nfssvc.c
> > @@ -21,6 +21,7 @@
> >  #include <linux/smp_lock.h>
> >  #include <linux/freezer.h>
> >  #include <linux/fs_struct.h>
> > +#include <linux/kthread.h>
> >  
> >  #include <linux/sunrpc/types.h>
> >  #include <linux/sunrpc/stats.h>
> > @@ -46,7 +47,7 @@
> >  #define SHUTDOWN_SIGS	(sigmask(SIGKILL) | sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT))
> >  
> >  extern struct svc_program	nfsd_program;
> > -static void			nfsd(struct svc_rqst *rqstp);
> > +static int			nfsd(void *vrqstp);
> >  struct timeval			nfssvc_boot;
> >  static atomic_t			nfsd_busy;
> >  static unsigned long		nfsd_last_call;
> > @@ -407,18 +408,19 @@ update_thread_usage(int busy_threads)
> >  /*
> >   * This is the NFS server kernel thread
> >   */
> > -static void
> > -nfsd(struct svc_rqst *rqstp)
> > +static int
> > +nfsd(void *vrqstp)
> >  {
> > +	struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
> >  	struct fs_struct *fsp;
> > -	int		err;
> >  	sigset_t shutdown_mask, allowed_mask;
> > +	int err, preverr = 0;
> > +	unsigned int signo;
> >  
> >  	/* Lock module and set up kernel thread */
> >  	mutex_lock(&nfsd_mutex);
> > -	daemonize("nfsd");
> >  
> > -	/* After daemonize() this kernel thread shares current->fs
> > +	/* At this point, the thread shares current->fs
> >  	 * with the init process. We need to create files with a
> >  	 * umask of 0 instead of init's umask. */
> >  	fsp = copy_fs_struct(current->fs);
> > @@ -433,14 +435,18 @@ nfsd(struct svc_rqst *rqstp)
> >  	siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS);
> >  	siginitsetinv(&allowed_mask, ALLOWED_SIGS);
> >  
> > +	/*
> > +	 * thread is spawned with all signals set to SIG_IGN, re-enable
> > +	 * the ones that matter
> > +	 */
> > +	for (signo = 1; signo <= _NSIG; signo++) {
> > +		if (!sigismember(&shutdown_mask, signo))
> > +			allow_signal(signo);
> > +	}
> >  
> >  	nfsdstats.th_cnt++;
> > -
> > -	rqstp->rq_task = current;
> > -
> >  	mutex_unlock(&nfsd_mutex);
> >  
> > -
> >  	/*
> >  	 * We want less throttling in balance_dirty_pages() so that nfs to
> >  	 * localhost doesn't cause nfsd to lock up due to all the client's
> > @@ -462,15 +468,25 @@ nfsd(struct svc_rqst *rqstp)
> >  		 */
> >  		while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
> >  			;
> > -		if (err < 0)
> > +		if (err == -EINTR)
> >  			break;
> > +		else if (err < 0) {
> > +			if (err != preverr) {
> > +				printk(KERN_WARNING "%s: unexpected error "
> > +					"from svc_recv (%d)\n", __func__, -err);
> > +				preverr = err;
> > +			}
> > +			schedule_timeout_uninterruptible(HZ);
> > +			continue;
> > +		}
> > +
> >  		update_thread_usage(atomic_read(&nfsd_busy));
> >  		atomic_inc(&nfsd_busy);
> >  
> >  		/* Lock the export hash tables for reading. */
> >  		exp_readlock();
> >  
> > -		/* Process request with signals blocked.  */
> > +		/* Process request with signals blocked. */
> >  		sigprocmask(SIG_SETMASK, &allowed_mask, NULL);
> >  
> >  		svc_process(rqstp);
> > @@ -479,25 +495,23 @@ nfsd(struct svc_rqst *rqstp)
> >  		exp_readunlock();
> >  		update_thread_usage(atomic_read(&nfsd_busy));
> >  		atomic_dec(&nfsd_busy);
> > -	}
> >  
> > -	if (err != -EINTR)
> > -		printk(KERN_WARNING "nfsd: terminating on error %d\n", -err);
> > +		/* reset err in case kthread_stop is called */
> > +		err = 0;
> > +	}
> 
> There's no use of err here until it's next set in
> 
> 	while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN)
> 
> so I assume the comment and this "err = 0" are artifacts of a previous
> implementation.
> 

That's correct. An earlier patch has the main loop as
"while(!kthread_should_stop())". Since we're using signals to take the
thread down though, there's not much point in checking
kthread_should_stop(). I can remove the "err = 0;" there.

> >  
> >  	/* Clear signals before calling svc_exit_thread() */
> >  	flush_signals(current);
> >  
> >  	mutex_lock(&nfsd_mutex);
> > -
> >  	nfsdstats.th_cnt --;
> >  
> >  out:
> >  	/* Release the thread */
> >  	svc_exit_thread(rqstp);
> > -
> > -	/* Release module */
> >  	mutex_unlock(&nfsd_mutex);
> > -	module_put_and_exit(0);
> 
> How does the module refcounting work after this patch?
> 
> --b.
> 

I think I've goofed this part, actually. I was thinking that we didn't
need to bump the refcount here, and that the kernel would realize that
nfsd() hadn't returned and would prevent unloading until it had. This
doesn't seem to be the case. I'll need to go back and add refcounting
back in.

-- 
Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux