SUNRPC: Fix a server shutdown leak
authorBenjamin Coddington <bcodding@redhat.com>
Fri, 3 Mar 2023 21:08:32 +0000 (16:08 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Mar 2023 07:48:57 +0000 (08:48 +0100)
[ 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

index 08ca797bb8a46346c1204f8e868ca6a8e621529f..74a1c9116a7851bd714e7ad0e48188787950fe86 100644 (file)
@@ -806,6 +806,7 @@ EXPORT_SYMBOL_GPL(svc_set_num_threads);
 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;
 
@@ -814,7 +815,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;