Hi Neil- > On Sep 6, 2021, at 12:44 AM, NeilBrown <neilb@xxxxxxx> wrote: > > > 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 When we first considered the alloc_pages_bulk() API, the SUNRPC patch in that series replaced this schedule_timeout(). Mel suggested we postpone that to a separate patch. Now is an ideal time to consider this change again. I've added the MM folks for expert commentary. I would rather see a shorter timeout, since that will be less disruptive in practice and today's systems shouldn't have to wait that long for free memory to become available. DEFAULT_IO_TIMEOUT might be a defensible choice -- it will slow down this loop effectively without adding a significant delay. > 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 > -- Chuck Lever