sunrpc: have svc tasks sleep in TASK_INTERRUPTIBLE instead of TASK_IDLE

JIRA: https://issues.redhat.com/browse/RHEL-22742
Upstream Status: RHEL-only

RHEL9 doesn't have f5d39b020809 ("freezer,sched: Rewrite core freezer
logic"), which means that when the freezer runs, it wakes kthreads that
are in TASK_INTERRUPTIBLE and not ones that are sleeping in TASK_IDLE.

A recent sunrpc patch backport switched svc threads to sleep in
TASK_IDLE instead of TASK_INTERRUPTIBLE. This caused a regression where
nfs client or server services could block the freezer.

It doesn't make much practical difference what state the threads sleep
in, so switch them back to TASK_INTERRUPTIBLE. kthreads silently drop
signals by default anyway.

Signed-off-by: Jeffrey Layton <jlayton@redhat.com>
This commit is contained in:
Jeffrey Layton 2024-02-19 09:37:10 -05:00
parent e490777386
commit d654df46f8
3 changed files with 4 additions and 4 deletions

View File

@ -101,7 +101,7 @@ nfs41_callback_svc(void *vrqstp)
set_freezable();
while (!kthread_freezable_should_stop(NULL)) {
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_IDLE);
prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
spin_lock_bh(&serv->sv_cb_lock);
if (!list_empty(&serv->sv_cb_list)) {
req = list_first_entry(&serv->sv_cb_list,

View File

@ -1369,7 +1369,7 @@ try_again:
/* found a match */
if (ni->nsui_busy) {
/* wait - and try again */
prepare_to_wait(&nn->nfsd_ssc_waitq, &wait, TASK_IDLE);
prepare_to_wait(&nn->nfsd_ssc_waitq, &wait, TASK_INTERRUPTIBLE);
spin_unlock(&nn->nfsd_ssc_lock);
/* allow 20secs for mount/unmount for now - revisit */

View File

@ -672,7 +672,7 @@ static bool svc_alloc_arg(struct svc_rqst *rqstp)
/* Made progress, don't sleep yet */
continue;
set_current_state(TASK_IDLE);
set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop()) {
set_current_state(TASK_RUNNING);
return false;
@ -732,7 +732,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp)
if (rqstp->rq_xprt)
goto out_found;
set_current_state(TASK_IDLE);
set_current_state(TASK_INTERRUPTIBLE);
smp_mb__before_atomic();
clear_bit(SP_CONGESTED, &pool->sp_flags);
clear_bit(RQ_BUSY, &rqstp->rq_flags);