lkml.org 
[lkml]   [2014]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 2/2] mm, compaction: return failed migration target pages back to freelist
    Memory compaction works by having a "freeing scanner" scan from one end of a 
    zone which isolates pages as migration targets while another "migrating scanner"
    scans from the other end of the same zone which isolates pages for migration.

    When page migration fails for an isolated page, the target page is returned to
    the system rather than the freelist built by the freeing scanner. This may
    require the freeing scanner to continue scanning memory after suitable migration
    targets have already been returned to the system needlessly.

    This patch returns destination pages to the freeing scanner freelist when page
    migration fails. This prevents unnecessary work done by the freeing scanner but
    also encourages memory to be as compacted as possible at the end of the zone.

    Reported-by: Greg Thelen <gthelen@google.com>
    Signed-off-by: David Rientjes <rientjes@google.com>
    ---
    mm/compaction.c | 17 +++++++++++++++--
    1 file changed, 15 insertions(+), 2 deletions(-)

    diff --git a/mm/compaction.c b/mm/compaction.c
    --- a/mm/compaction.c
    +++ b/mm/compaction.c
    @@ -797,6 +797,19 @@ static struct page *compaction_alloc(struct page *migratepage,
    }

    /*
    + * This is a migrate-callback that "frees" freepages back to the isolated
    + * freelist. All pages on the freelist are from the same zone, so there is no
    + * special handling needed for NUMA.
    + */
    +static void compaction_free(struct page *page, unsigned long data)
    +{
    + struct compact_control *cc = (struct compact_control *)data;
    +
    + list_add(&page->lru, &cc->freepages);
    + cc->nr_freepages++;
    +}
    +
    +/*
    * We cannot control nr_migratepages and nr_freepages fully when migration is
    * running as migrate_pages() has no knowledge of compact_control. When
    * migration is complete, we count the number of pages on the lists by hand.
    @@ -1023,8 +1036,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
    }

    nr_migrate = cc->nr_migratepages;
    - err = migrate_pages(&cc->migratepages, compaction_alloc, NULL,
    - (unsigned long)cc,
    + err = migrate_pages(&cc->migratepages, compaction_alloc,
    + compaction_free, (unsigned long)cc,
    cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC,
    MR_COMPACTION);
    update_nr_listpages(cc);

    \
     
     \ /
      Last update: 2014-05-01 03:21    [W:9.225 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site