]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
sunrpc: exclude from freezer when waiting for requests:
authorNeilBrown <neilb@suse.de>
Fri, 7 Jun 2024 13:10:48 +0000 (09:10 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 16 Jun 2024 11:39:55 +0000 (13:39 +0200)
Prior to v6.1, the freezer will only wake a kernel thread from an
uninterruptible sleep.  Since we changed svc_get_next_xprt() to use and
IDLE sleep the freezer cannot wake it.  We need to tell the freezer to
ignore it instead.

To make this work with only upstream commits, 5.15.y would need
commit f5d39b020809 ("freezer,sched: Rewrite core freezer logic")
which allows non-interruptible sleeps to be woken by the freezer.

Fixes: 9b8a8e5e8129 ("nfsd: don't allow nfsd threads to be signalled.")
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/nfs/callback.c
fs/nfsd/nfs4proc.c
net/sunrpc/svc_xprt.c

index 46a0a2d6962e1c81b8dbb6663748befb5bb93f3a..8fe143cad4a2bb442a1f1b8cea6d52ed64bd140a 100644 (file)
@@ -124,7 +124,7 @@ nfs41_callback_svc(void *vrqstp)
                } else {
                        spin_unlock_bh(&serv->sv_cb_lock);
                        if (!kthread_should_stop())
-                               schedule();
+                               freezable_schedule();
                        finish_wait(&serv->sv_cb_waitq, &wq);
                }
        }
index 6779291efca9ede8fda556123e8900211f76e1c0..e0ff2212866a4eb84f04fb7ae8071c4bc8d91739 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/namei.h>
+#include <linux/freezer.h>
 
 #include <linux/sunrpc/addr.h>
 #include <linux/nfs_ssc.h>
@@ -1322,7 +1323,7 @@ try_again:
 
                        /* allow 20secs for mount/unmount for now - revisit */
                        if (kthread_should_stop() ||
-                                       (schedule_timeout(20*HZ) == 0)) {
+                                       (freezable_schedule_timeout(20*HZ) == 0)) {
                                finish_wait(&nn->nfsd_ssc_waitq, &wait);
                                kfree(work);
                                return nfserr_eagain;
index b19592673eef2bca6cc19cf11ccc49cbe79b3f4f..3cf53e3140a5a1ea504831fd0f3fee9484ac8506 100644 (file)
@@ -705,7 +705,7 @@ static int svc_alloc_arg(struct svc_rqst *rqstp)
                        set_current_state(TASK_RUNNING);
                        return -EINTR;
                }
-               schedule_timeout(msecs_to_jiffies(500));
+               freezable_schedule_timeout(msecs_to_jiffies(500));
        }
        rqstp->rq_page_end = &rqstp->rq_pages[pages];
        rqstp->rq_pages[pages] = NULL; /* this might be seen in nfsd_splice_actor() */
@@ -765,7 +765,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
        smp_mb__after_atomic();
 
        if (likely(rqst_should_sleep(rqstp)))
-               time_left = schedule_timeout(timeout);
+               time_left = freezable_schedule_timeout(timeout);
        else
                __set_current_state(TASK_RUNNING);