lkml.org 
[lkml]   [2012]   [Feb]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: mm: compaction: Check for overlapping nodes during isolation for migration
    From
    On Mon, Feb 6, 2012 at 5:08 PM, Mel Gorman <mgorman@suse.de> wrote:
    > When isolating pages for migration, migration starts at the start of a
    > zone while the free scanner starts at the end of the zone. Migration
    > avoids entering a new zone by never going beyond the free scanned.
    > Unfortunately, in very rare cases nodes can overlap. When this happens,
    > migration isolates pages without the LRU lock held, corrupting lists
    > which will trigger errors in reclaim or during page free such as in the
    > following oops
    >
    > [ 8739.994311] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
    > [ 8739.994331] IP: [<ffffffff810f795c>] free_pcppages_bulk+0xcc/0x450
    > [ 8739.994344] PGD 1dda554067 PUD 1e1cb58067 PMD 0
    > [ 8739.994350] Oops: 0000 [#1] SMP
    > [ 8739.994357] CPU 37
    > [ 8739.994359] Modules linked in: veth(X) <SNIPPED>
    > [ 8739.994457] Supported: Yes
    > [ 8739.994461]
    > [ 8739.994465] Pid: 17088, comm: memcg_process_s Tainted: G            X
    > [ 8739.994477] RIP: 0010:[<ffffffff810f795c>]  [<ffffffff810f795c>] free_pcppages_bulk+0xcc/0x450
    > [ 8739.994483] RSP: 0000:ffff881c2926f7a8  EFLAGS: 00010082
    > [ 8739.994488] RAX: 0000000000000010 RBX: 0000000000000000 RCX: ffff881e7f4546c8
    > [ 8739.994491] RDX: ffff881e7f4546b0 RSI: 0000000000000000 RDI: 0000000000000167
    > [ 8739.994498] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
    > [ 8739.994502] R10: 0000000000000166 R11: ffffea0060ea0e50 R12: ffffffffffffffd8
    > [ 8739.994506] R13: 0000000000000001 R14: ffff881c7ffd9e00 R15: 0000000000000000
    > [ 8739.994511] FS:  00007f5072690700(0000) GS:ffff881e7f440000(0000) knlGS:0000000000000000
    > [ 8739.994517] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    > [ 8739.994522] CR2: 0000000000000008 CR3: 0000001e1f1f9000 CR4: 00000000000006e0
    > [ 8739.994525] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    > [ 8739.994530] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    > [ 8739.994535] Process memcg_process_s (pid: 17088, threadinfo ffff881c2926e000, task ffff881c2926c0c0)
    > [ 8739.994539] Stack:
    > [ 8739.994541]  0000000000000000 ffff881e7f4546c8 0000000000000010 ffff881c7ffd9e60
    > [ 8739.994557]  ffff881e7f4546b0 0000001f814498ee 0000000000000000 0000001d81245255
    > [ 8739.994565]  ffff881e7f4546c0 ffffea005ecd2f40 ffff881e7f4546b0 0020000000200010
    > [ 8739.994573] Call Trace:
    > [ 8739.994590]  [<ffffffff810f8bfe>] free_hot_cold_page+0x17e/0x1f0
    > [ 8739.994600]  [<ffffffff810f8ff0>] __pagevec_free+0x90/0xb0
    > [ 8739.994610]  [<ffffffff810fc08a>] release_pages+0x22a/0x260
    > [ 8739.994617]  [<ffffffff810fc1b3>] pagevec_lru_move_fn+0xf3/0x110
    > [ 8739.994627]  [<ffffffff81101e76>] putback_lru_page+0x66/0xe0
    > [ 8739.994639]  [<ffffffff8113fde6>] unmap_and_move+0x156/0x180
    > [ 8739.994647]  [<ffffffff8113feae>] migrate_pages+0x9e/0x1b0
    > [ 8739.994656]  [<ffffffff81136313>] compact_zone+0x1f3/0x2f0
    > [ 8739.994665]  [<ffffffff81136672>] compact_zone_order+0xa2/0xe0
    > [ 8739.994672]  [<ffffffff8113678f>] try_to_compact_pages+0xdf/0x110
    > [ 8739.994678]  [<ffffffff810f7eae>] __alloc_pages_direct_compact+0xee/0x1c0
    > [ 8739.994686]  [<ffffffff810f82f0>] __alloc_pages_slowpath+0x370/0x830
    > [ 8739.994694]  [<ffffffff810f8961>] __alloc_pages_nodemask+0x1b1/0x1c0
    > [ 8739.994701]  [<ffffffff81134d2b>] alloc_pages_vma+0x9b/0x160
    > [ 8739.994712]  [<ffffffff811449a0>] do_huge_pmd_anonymous_page+0x160/0x270
    > [ 8739.994725]  [<ffffffff81444ba7>] do_page_fault+0x207/0x4c0
    > [ 8739.994735]  [<ffffffff814418e5>] page_fault+0x25/0x30
    > [ 8739.994748]  [<0000000000400997>] 0x400996
    >
    > The "X" in the taint flag means that external modules were loaded but
    > but is unrelated to the bug triggering. The real problem was because
    > the PFN layout looks like this
    >
    > [    0.000000] Zone PFN ranges:
    > [    0.000000]   DMA      0x00000010 -> 0x00001000
    > [    0.000000]   DMA32    0x00001000 -> 0x00100000
    > [    0.000000]   Normal   0x00100000 -> 0x01e80000
    > [    0.000000] Movable zone start PFN for each node
    > [    0.000000] early_node_map[14] active PFN ranges
    > [    0.000000]     0: 0x00000010 -> 0x0000009b
    > [    0.000000]     0: 0x00000100 -> 0x0007a1ec
    > [    0.000000]     0: 0x0007a354 -> 0x0007a379
    > [    0.000000]     0: 0x0007f7ff -> 0x0007f800
    > [    0.000000]     0: 0x00100000 -> 0x00680000
    > [    0.000000]     1: 0x00680000 -> 0x00e80000
    > [    0.000000]     0: 0x00e80000 -> 0x01080000
    > [    0.000000]     1: 0x01080000 -> 0x01280000
    > [    0.000000]     0: 0x01280000 -> 0x01480000
    > [    0.000000]     1: 0x01480000 -> 0x01680000
    > [    0.000000]     0: 0x01680000 -> 0x01880000
    > [    0.000000]     1: 0x01880000 -> 0x01a80000
    > [    0.000000]     0: 0x01a80000 -> 0x01c80000
    > [    0.000000]     1: 0x01c80000 -> 0x01e80000
    >
    > The fix is straight-forward. isolate_migratepages() has to make a
    > similar check to isolate_freepage to ensure that it never isolates
    > pages from a zone it does not hold the LRU lock for.
    >
    > This was discovered in a 3.0-based kernel but it affects 3.1.x, 3.2.x
    > and current mainline.
    >
    > Signed-off-by: Mel Gorman <mgorman@suse.de>
    > Cc: <stable@vger.kernel.org>

    Acked-by: Hillf Danton <dhillf@gmail.com>

    > ---
    >  mm/compaction.c |   11 ++++++++++-
    >  1 files changed, 10 insertions(+), 1 deletions(-)
    >
    > diff --git a/mm/compaction.c b/mm/compaction.c
    > index bd6e739..6042644 100644
    > --- a/mm/compaction.c
    > +++ b/mm/compaction.c
    > @@ -330,8 +330,17 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone,
    >                        continue;
    >                nr_scanned++;
    >
    > -               /* Get the page and skip if free */
    > +               /*
    > +                * Get the page and ensure the page is within the same zone.
    > +                * See the comment in isolate_freepages about overlapping
    > +                * nodes. It is deliberate that the new zone lock is not taken
    > +                * as memory compaction should not move pages between nodes.
    > +                */
    >                page = pfn_to_page(low_pfn);
    > +               if (page_zone(page) != zone)
    > +                       continue;
    > +
    > +               /* Skip if free */
    >                if (PageBuddy(page))
    >                        continue;
    >
    >
    > --
    > Mel Gorman
    > SUSE Labs
    > --
    > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    > the body of a message to majordomo@vger.kernel.org
    > More majordomo info at  http://vger.kernel.org/majordomo-info.html
    > Please read the FAQ at  http://www.tux.org/lkml/
    >
    >
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2012-02-09 13:13    [W:0.031 / U:0.892 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site