Many places that need to wait before retrying a memory allocation use congestion_wait(). xfs_buf_alloc_pages() is a good example which follows a similar pattern to that in svc_alloc_args(). It make sense to do the same thing in svc_alloc_args(); This will allow the allocation to be retried sooner if some backing device becomes non-congested before the timeout. Every call to congestion_wait() in the entire kernel passes BLK_RW_ASYNC as the first argument, so we should so. The second argument - an upper limit for waiting - seem fairly arbitrary. Many places use "HZ/50" or "HZ/10". As there is no obvious choice, it seems reasonable to leave the maximum time unchanged. If a service using svc_alloc_args() is terminated, it may now have to wait up to the full 500ms before termination completes as congestion_wait() cannot be interrupted. I don't believe this will be a problem in practice, though it might be justification for using a smaller timeout. Signed-off-by: NeilBrown <neilb@xxxxxxx> --- I happened to notice this inconsistency between svc_alloc_args() and xfs_buf_alloc_pages() despite them doing very similar things, so thought I'd send a patch. NeilBrown net/sunrpc/svc_xprt.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 796eebf1787d..161433ae0fab 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -10,6 +10,7 @@ #include <linux/freezer.h> #include <linux/kthread.h> #include <linux/slab.h> +#include <linux/backing-dev.h> #include <net/sock.h> #include <linux/sunrpc/addr.h> #include <linux/sunrpc/stats.h> @@ -682,12 +683,10 @@ static int svc_alloc_arg(struct svc_rqst *rqstp) /* Made progress, don't sleep yet */ continue; - set_current_state(TASK_INTERRUPTIBLE); - if (signalled() || kthread_should_stop()) { - set_current_state(TASK_RUNNING); + if (signalled() || kthread_should_stop()) return -EINTR; - } - schedule_timeout(msecs_to_jiffies(500)); + + congestion_wait(BLK_RW_ASYNC, 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() */ -- 2.33.0