lkml.org 
[lkml]   [2013]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 011/171] mm: use aligned zone start for pfn_to_bitidx calculation
    Date
    3.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Laura Abbott <lauraa@codeaurora.org>

    commit c060f943d0929f3e429c5d9522290584f6281d6e upstream.

    The current calculation in pfn_to_bitidx assumes that (pfn -
    zone->zone_start_pfn) >> pageblock_order will return the same bit for
    all pfn in a pageblock. If zone_start_pfn is not aligned to
    pageblock_nr_pages, this may not always be correct.

    Consider the following with pageblock order = 10, zone start 2MB:

    pfn | pfn - zone start | (pfn - zone start) >> page block order
    ----------------------------------------------------------------
    0x26000 | 0x25e00 | 0x97
    0x26100 | 0x25f00 | 0x97
    0x26200 | 0x26000 | 0x98
    0x26300 | 0x26100 | 0x98

    This means that calling {get,set}_pageblock_migratetype on a single page
    will not set the migratetype for the full block. Fix this by rounding
    down zone_start_pfn when doing the bitidx calculation.

    For our use case, the effects of this bug were mostly tied to the fact
    that CMA allocations would either take a long time or fail to happen.
    Depending on the driver using CMA, this could result in anything from
    visual glitches to application failures.

    Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
    Acked-by: Mel Gorman <mgorman@suse.de>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    mm/page_alloc.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    --- a/mm/page_alloc.c
    +++ b/mm/page_alloc.c
    @@ -5340,7 +5340,7 @@ static inline int pfn_to_bitidx(struct z
    pfn &= (PAGES_PER_SECTION-1);
    return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
    #else
    - pfn = pfn - zone->zone_start_pfn;
    + pfn = pfn - round_down(zone->zone_start_pfn, pageblock_nr_pages);
    return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
    #endif /* CONFIG_SPARSEMEM */
    }



    \
     
     \ /
      Last update: 2013-01-16 02:21    [W:2.205 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site