| From cb529ff70a8ed8ed56149d9c0cd340f67e6598bd Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 3 Mar 2023 16:08:32 -0500 |
| Subject: SUNRPC: Fix a server shutdown leak |
| |
| From: Benjamin Coddington <bcodding@redhat.com> |
| |
| [ Upstream commit 9ca6705d9d609441d34f8b853e1e4a6369b3b171 ] |
| |
| 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: ed6473ddc704 ("NFSv4: Fix callback server shutdown") |
| Signed-off-by: Benjamin Coddington <bcodding@redhat.com> |
| Reviewed-by: Jeff Layton <jlayton@kernel.org> |
| Signed-off-by: Chuck Lever <chuck.lever@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/sunrpc/svc.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c |
| index 24577d1b99079..9ee32e06f877e 100644 |
| --- a/net/sunrpc/svc.c |
| +++ b/net/sunrpc/svc.c |
| @@ -787,6 +787,7 @@ svc_start_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) |
| static int |
| svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) |
| { |
| + struct svc_rqst *rqstp; |
| struct task_struct *task; |
| unsigned int state = serv->sv_nrthreads-1; |
| |
| @@ -795,7 +796,10 @@ svc_stop_kthreads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) |
| task = choose_victim(serv, pool, &state); |
| if (task == NULL) |
| 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++; |
| } while (nrservs < 0); |
| return 0; |
| -- |
| 2.39.2 |
| |