Skip to content

Commit

Permalink
SUNRPC: refresh rq_pages using a bulk page allocator
Browse files Browse the repository at this point in the history
Reduce the rate at which nfsd threads hammer on the page allocator.  This
improves throughput scalability by enabling the threads to run more
independently of each other.

[mgorman: Update interpretation of alloc_pages_bulk return value]

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Chuck Lever <[email protected]>
Signed-off-by: Mel Gorman <[email protected]>
Reviewed-by: Alexander Lobakin <[email protected]>
Cc: Alexander Duyck <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: David Miller <[email protected]>
Cc: Ilias Apalodimas <[email protected]>
Cc: Jesper Dangaard Brouer <[email protected]>
Cc: Matthew Wilcox (Oracle) <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
chucklever authored and torvalds committed Apr 30, 2021
1 parent ab83626 commit f6e70aa
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions net/sunrpc/svc_xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,30 +662,29 @@ static int svc_alloc_arg(struct svc_rqst *rqstp)
{
struct svc_serv *serv = rqstp->rq_server;
struct xdr_buf *arg = &rqstp->rq_arg;
int pages;
int i;
unsigned long pages, filled;

/* now allocate needed pages. If we get a failure, sleep briefly */
pages = (serv->sv_max_mesg + 2 * PAGE_SIZE) >> PAGE_SHIFT;
if (pages > RPCSVC_MAXPAGES) {
pr_warn_once("svc: warning: pages=%u > RPCSVC_MAXPAGES=%lu\n",
pr_warn_once("svc: warning: pages=%lu > RPCSVC_MAXPAGES=%lu\n",
pages, RPCSVC_MAXPAGES);
/* use as many pages as possible */
pages = RPCSVC_MAXPAGES;
}
for (i = 0; i < pages ; i++)
while (rqstp->rq_pages[i] == NULL) {
struct page *p = alloc_page(GFP_KERNEL);
if (!p) {
set_current_state(TASK_INTERRUPTIBLE);
if (signalled() || kthread_should_stop()) {
set_current_state(TASK_RUNNING);
return -EINTR;
}
schedule_timeout(msecs_to_jiffies(500));
}
rqstp->rq_pages[i] = p;

for (;;) {
filled = alloc_pages_bulk_array(GFP_KERNEL, pages,
rqstp->rq_pages);
if (filled == pages)
break;

set_current_state(TASK_INTERRUPTIBLE);
if (signalled() || kthread_should_stop()) {
set_current_state(TASK_RUNNING);
return -EINTR;
}
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() */

Expand Down

0 comments on commit f6e70aa

Please sign in to comment.