[lkml]   [2009]   [Aug]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[patch 38/74] page-allocator: preserve PFN ordering when __GFP_COLD is set
    2.6.30-stable review patch.  If anyone has any objections, please let us know.


    From: Mel Gorman <>

    commit e084b2d95e48b31aa45f9c49ffc6cdae8bdb21d4 upstream.

    Fix a post-2.6.24 performace regression caused by
    3dfa5721f12c3d5a441448086bee156887daa961 ("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

    Signed-off-by: Mel Gorman <>
    Reported-by: Narayananu Gopalakrishnan <>
    Tested-by: Narayanan Gopalakrishnan <>
    Cc: KAMEZAWA Hiroyuki <>
    Signed-off-by: Andrew Morton <>
    Signed-off-by: Linus Torvalds <>
    Signed-off-by: Greg Kroah-Hartman <>

    mm/page_alloc.c | 13 +++++++++----
    1 file changed, 9 insertions(+), 4 deletions(-)

    --- a/mm/page_alloc.c
    +++ b/mm/page_alloc.c
    @@ -858,7 +858,7 @@ static struct page *__rmqueue(struct zon
    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;

    @@ -877,7 +877,10 @@ static int rmqueue_bulk(struct zone *zon
    * 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;
    @@ -1077,7 +1080,8 @@ again:
    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;
    @@ -1096,7 +1100,8 @@ again:
    /* 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->, struct page, lru);

     \ /
      Last update: 2009-08-13 22:27    [W:0.021 / U:108.136 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site