Skip to content

Commit

Permalink
page-allocator: preserve PFN ordering when __GFP_COLD is set
Browse files Browse the repository at this point in the history
Fix a post-2.6.24 performace regression caused by
3dfa572 ("page-allocator: preserve PFN
ordering when __GFP_COLD is set").

Narayanan reports "The regression is around 15%.  There is no disk controller
as our setup is based on Samsung OneNAND used as a memory mapped device on a
OMAP2430 based board."

The page allocator tries to preserve contiguous PFN ordering when returning
pages such that repeated callers to the allocator have a strong chance of
getting physically contiguous pages, particularly when external fragmentation
is low.  However, of the bulk of the allocations have __GFP_COLD set as they
are due to aio_read() for example, then the PFNs are in reverse PFN order.
This can cause performance degration when used with IO controllers that could
have merged the requests.

This patch attempts to preserve the contiguous ordering of PFNs for users of
__GFP_COLD.

Signed-off-by: Mel Gorman <[email protected]>
Reported-by: Narayananu Gopalakrishnan <[email protected]>
Tested-by: Narayanan Gopalakrishnan <[email protected]>
Cc: KAMEZAWA Hiroyuki <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
gormanm authored and torvalds committed Jul 30, 2009
1 parent 51fbb4b commit e084b2d
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order,
*/
static int rmqueue_bulk(struct zone *zone, unsigned int order,
unsigned long count, struct list_head *list,
int migratetype)
int migratetype, int cold)
{
int i;

Expand All @@ -901,7 +901,10 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
* merge IO requests if the physical pages are ordered
* properly.
*/
list_add(&page->lru, list);
if (likely(cold == 0))
list_add(&page->lru, list);
else
list_add_tail(&page->lru, list);
set_page_private(page, migratetype);
list = &page->lru;
}
Expand Down Expand Up @@ -1119,7 +1122,8 @@ struct page *buffered_rmqueue(struct zone *preferred_zone,
local_irq_save(flags);
if (!pcp->count) {
pcp->count = rmqueue_bulk(zone, 0,
pcp->batch, &pcp->list, migratetype);
pcp->batch, &pcp->list,
migratetype, cold);
if (unlikely(!pcp->count))
goto failed;
}
Expand All @@ -1138,7 +1142,8 @@ struct page *buffered_rmqueue(struct zone *preferred_zone,
/* Allocate more to the pcp list if necessary */
if (unlikely(&page->lru == &pcp->list)) {
pcp->count += rmqueue_bulk(zone, 0,
pcp->batch, &pcp->list, migratetype);
pcp->batch, &pcp->list,
migratetype, cold);
page = list_entry(pcp->list.next, struct page, lru);
}

Expand Down

0 comments on commit e084b2d

Please sign in to comment.