Commit 9ca6705d authored by Benjamin Coddington's avatar Benjamin Coddington Committed by Chuck Lever

SUNRPC: Fix a server shutdown leak

Fix a race where kthread_stop() may prevent the threadfn from ever getting
called.  If that happens the svc_rqst will not be cleaned up.

Fixes: ed6473dd ("NFSv4: Fix callback server shutdown")
Signed-off-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent fd9a2e1d
...@@ -798,6 +798,7 @@ svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) ...@@ -798,6 +798,7 @@ svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
static int static int
svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
{ {
struct svc_rqst *rqstp;
struct task_struct *task; struct task_struct *task;
unsigned int state = serv->sv_nrthreads-1; unsigned int state = serv->sv_nrthreads-1;
...@@ -806,7 +807,10 @@ svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) ...@@ -806,7 +807,10 @@ svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs)
task = choose_victim(serv, pool, &state); task = choose_victim(serv, pool, &state);
if (task == NULL) if (task == NULL)
break; break;
kthread_stop(task); rqstp = kthread_data(task);
/* Did we lose a race to svo_function threadfn? */
if (kthread_stop(task) == -EINTR)
svc_exit_thread(rqstp);
nrservs++; nrservs++;
} while (nrservs < 0); } while (nrservs < 0);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment