Skip to content

Commit

Permalink
SUNRPC: don't pause on incomplete allocation
Browse files Browse the repository at this point in the history
alloc_pages_bulk_array() attempts to allocate at least one page based on
the provided pages, and then opportunistically allocates more if that
can be done without dropping the spinlock.

So if it returns fewer than requested, that could just mean that it
needed to drop the lock.  In that case, try again immediately.

Only pause for a time if no progress could be made.

Reported-and-tested-by: Mike Javorski <mike.javorski@gmail.com>
Reported-and-tested-by: Lothar Paltins <lopa@mailbox.org>
Fixes: f6e70aa ("SUNRPC: refresh rq_pages using a bulk page allocator")
Signed-off-by: NeilBrown <neilb@suse.de>
Acked-by: Mel Gorman <mgorman@suse.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
  • Loading branch information
NeilBrown authored and Chuck Lever committed Sep 1, 2021
1 parent 0bcc7ca commit e38b3f2
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions net/sunrpc/svc_xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ static int svc_alloc_arg(struct svc_rqst *rqstp)
{
struct svc_serv *serv = rqstp->rq_server;
struct xdr_buf *arg = &rqstp->rq_arg;
unsigned long pages, filled;
unsigned long pages, filled, ret;

pagevec_init(&rqstp->rq_pvec);

Expand All @@ -675,11 +675,12 @@ static int svc_alloc_arg(struct svc_rqst *rqstp)
pages = RPCSVC_MAXPAGES;
}

for (;;) {
filled = alloc_pages_bulk_array(GFP_KERNEL, pages,
rqstp->rq_pages);
if (filled == pages)
break;
for (filled = 0; filled < pages; filled = ret) {
ret = alloc_pages_bulk_array(GFP_KERNEL, pages,
rqstp->rq_pages);
if (ret > filled)
/* Made progress, don't sleep yet */
continue;

set_current_state(TASK_INTERRUPTIBLE);
if (signalled() || kthread_should_stop()) {
Expand Down

0 comments on commit e38b3f2

Please sign in to comment.