sunrpc: exclude from freezer when waiting for requests:

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>
This commit is contained in:
NeilBrown 2024-06-07 09:10:48 -04:00 committed by Greg Kroah-Hartman
parent a89f73ed56
commit 3feac2b552
3 changed files with 5 additions and 4 deletions

View 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);
}
}

View 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;

View 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);