提交 ed6473dd 编写于 作者: T Trond Myklebust 提交者: J. Bruce Fields

NFSv4: Fix callback server shutdown

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.
Tested-and-reviewed-by: NKinglong Mee <kinglongmee@gmail.com>
Reported-by: NKinglong Mee <kinglongmee@gmail.com>
Fixes: bb6aeba7 ("NFSv4.x: Switch to using svc_set_num_threads()...")
Signed-off-by: NTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: NJ. Bruce Fields <bfields@redhat.com>
上级 9e0d8768
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
...@@ -76,7 +76,10 @@ nfs4_callback_svc(void *vrqstp) ...@@ -76,7 +76,10 @@ nfs4_callback_svc(void *vrqstp)
set_freezable(); 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 * Listen for a request on the socket
*/ */
...@@ -85,6 +88,8 @@ nfs4_callback_svc(void *vrqstp) ...@@ -85,6 +88,8 @@ nfs4_callback_svc(void *vrqstp)
continue; continue;
svc_process(rqstp); svc_process(rqstp);
} }
svc_exit_thread(rqstp);
module_put_and_exit(0);
return 0; return 0;
} }
...@@ -103,9 +108,10 @@ nfs41_callback_svc(void *vrqstp) ...@@ -103,9 +108,10 @@ nfs41_callback_svc(void *vrqstp)
set_freezable(); set_freezable();
while (!kthread_should_stop()) { while (!kthread_freezable_should_stop(NULL)) {
if (try_to_freeze())
continue; if (signal_pending(current))
flush_signals(current);
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE); prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
spin_lock_bh(&serv->sv_cb_lock); spin_lock_bh(&serv->sv_cb_lock);
...@@ -121,11 +127,13 @@ nfs41_callback_svc(void *vrqstp) ...@@ -121,11 +127,13 @@ nfs41_callback_svc(void *vrqstp)
error); error);
} else { } else {
spin_unlock_bh(&serv->sv_cb_lock); spin_unlock_bh(&serv->sv_cb_lock);
schedule(); if (!kthread_should_stop())
schedule();
finish_wait(&serv->sv_cb_waitq, &wq); finish_wait(&serv->sv_cb_waitq, &wq);
} }
flush_signals(current);
} }
svc_exit_thread(rqstp);
module_put_and_exit(0);
return 0; return 0;
} }
...@@ -221,14 +229,14 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, ...@@ -221,14 +229,14 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
static struct svc_serv_ops nfs40_cb_sv_ops = { static struct svc_serv_ops nfs40_cb_sv_ops = {
.svo_function = nfs4_callback_svc, .svo_function = nfs4_callback_svc,
.svo_enqueue_xprt = svc_xprt_do_enqueue, .svo_enqueue_xprt = svc_xprt_do_enqueue,
.svo_setup = svc_set_num_threads, .svo_setup = svc_set_num_threads_sync,
.svo_module = THIS_MODULE, .svo_module = THIS_MODULE,
}; };
#if defined(CONFIG_NFS_V4_1) #if defined(CONFIG_NFS_V4_1)
static struct svc_serv_ops nfs41_cb_sv_ops = { static struct svc_serv_ops nfs41_cb_sv_ops = {
.svo_function = nfs41_callback_svc, .svo_function = nfs41_callback_svc,
.svo_enqueue_xprt = svc_xprt_do_enqueue, .svo_enqueue_xprt = svc_xprt_do_enqueue,
.svo_setup = svc_set_num_threads, .svo_setup = svc_set_num_threads_sync,
.svo_module = THIS_MODULE, .svo_module = THIS_MODULE,
}; };
......
...@@ -473,6 +473,7 @@ void svc_pool_map_put(void); ...@@ -473,6 +473,7 @@ void svc_pool_map_put(void);
struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int,
struct svc_serv_ops *); struct svc_serv_ops *);
int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); 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); int svc_pool_stats_open(struct svc_serv *serv, struct file *file);
void svc_destroy(struct svc_serv *); void svc_destroy(struct svc_serv *);
void svc_shutdown_net(struct svc_serv *, struct net *); void svc_shutdown_net(struct svc_serv *, struct net *);
......
...@@ -795,6 +795,44 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) ...@@ -795,6 +795,44 @@ svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
} }
EXPORT_SYMBOL_GPL(svc_set_num_threads); 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 * Called from a server thread as it's exiting. Caller must hold the "service
* mutex" for the service. * mutex" for the service.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部