Patch "NFSv4: Fix callback server shutdown" has been added to the 4.9-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
NFSv4: Fix callback server shutdown
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
nfsv4-fix-callback-server-shutdown.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
ed6473ddc704a2005b9900ca08e236ebb2d8540aMon Sep 17 00:00:00 2001
From: Trond Myklebust <[email protected]>
Date: Wed, 26 Apr 2017 11:55:27 -0400
Subject: NFSv4: Fix callback server shutdown
From: Trond Myklebust <[email protected]>
commit ed6473ddc704a2005b9900ca08e236ebb2d8540a upstream.
We want to use kthread_stop() in order to ensure the threads are shut down before we tear down the nfs_callback_info in nfs_callback_down.
--- fs/nfs/callback.c | 24 ++++++++++++++++-------- include/linux/sunrpc/svc.h | 1 + net/sunrpc/svc.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-)
fs/nfs/callback.c +16 -8
@@ -75,7 +75,10 @@ nfs4_callback_svc(void *vrqstp)set_freezable (); -while (!kthread_should_stop ()) { +while (!kthread_freezable_should_stop (NULL )) { + +if (signal_pending (current)) +flush_signals (current);/* * Listen for a request on the socket */
@@ -84,6 +87,8 @@ nfs4_callback_svc(void *vrqstp)continue ;svc_process (rqstp); } +svc_exit_thread (rqstp); +module_put_and_exit (0 );return 0 ; }
@@ -102,9 +107,10 @@ nfs41_callback_svc(void *vrqstp)set_freezable (); -while (!kthread_should_stop ()) { -if (try_to_freeze ()) -continue ; +while (!kthread_freezable_should_stop (NULL )) { + +if (signal_pending (current)) +flush_signals (current);prepare_to_wait (&serv->sv_cb_waitq, &wq,TASK_INTERRUPTIBLE );spin_lock_bh (&serv->sv_cb_lock);
@@ -120,11 +126,13 @@ nfs41_callback_svc(void *vrqstp) error); }else {spin_unlock_bh (&serv->sv_cb_lock); -schedule (); +if (!kthread_should_stop ()) +schedule ();finish_wait (&serv->sv_cb_waitq, &wq); } -flush_signals (current); } +svc_exit_thread (rqstp); +module_put_and_exit (0 );return 0 ; }
@@ -220,14 +228,14 @@ err_bind:static struct svc_serv_ops nfs40_cb_sv_ops = { .svo_function = nfs4_callback_svc, .svo_enqueue_xprt = svc_xprt_do_enqueue, - .svo_setup = svc_set_num_threads, + .svo_setup = svc_set_num_threads_sync, .svo_module =THIS_MODULE , };#if defined(CONFIG_NFS_V4_1 )static struct svc_serv_ops nfs41_cb_sv_ops = { .svo_function = nfs41_callback_svc, .svo_enqueue_xprt = svc_xprt_do_enqueue, - .svo_setup = svc_set_num_threads, + .svo_setup = svc_set_num_threads_sync, .svo_module =THIS_MODULE , };
include/linux/sunrpc/svc.h +1 -0
@@ -470,6 +470,7 @@ void svc_pool_map_put(void);struct svc_serv *svc_create_pooled (struct svc_program *,unsigned int ,struct svc_serv_ops *);int svc_set_num_threads (struct svc_serv *,struct svc_pool *,int ); +int svc_set_num_threads_sync (struct svc_serv *,struct svc_pool *,int );int svc_pool_stats_open (struct svc_serv *serv,struct file *file);void svc_destroy (struct svc_serv *);void svc_shutdown_net (struct svc_serv *,struct net *);
net/sunrpc/svc.c +38 -0
@@ -795,6 +795,44 @@ svc_set_num_threads(struct svc_serv *ser }EXPORT_SYMBOL_GPL (svc_set_num_threads); +/* destroy old threads */ +static int +svc_stop_kthreads (struct svc_serv *serv,struct svc_pool *pool,int nrservs) +{ +struct task_struct *task; +unsigned int state = serv->sv_nrthreads-1 ; + +/* destroy old threads */ +do { + task =choose_victim (serv, pool, &state); +if (task ==NULL ) +break ; +kthread_stop (task); + nrservs++; + }while (nrservs <0 ); +return 0 ; +} + +int +svc_set_num_threads_sync (struct svc_serv *serv,struct svc_pool *pool,int nrservs) +{ +if (pool ==NULL ) { +/* The -1 assumes caller has done a svc_get() */ + nrservs -= (serv->sv_nrthreads-1 ); + }else { +spin_lock_bh (&pool->sp_lock); + nrservs -= pool->sp_nrthreads; +spin_unlock_bh (&pool->sp_lock); + } + +if (nrservs >0 ) +return svc_start_kthreads (serv, pool, nrservs); +if (nrservs <0 ) +return svc_stop_kthreads (serv, pool, nrservs); +return 0 ; +} +EXPORT_SYMBOL_GPL (svc_set_num_threads_sync); +/* * Called from a server thread as it's exiting. Caller must hold the "service * mutex" for the service.
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/sunrpc-refactor-svc_set_num_threads.patch queue-4.9/nfsv4-fix-callback-server-shutdown.patch