Skip to content
  • Vlastimil Babka's avatar
    mm, compaction: properly signal and act upon lock and need_sched() contention · be976572
    Vlastimil Babka authored
    
    
    Compaction uses compact_checklock_irqsave() function to periodically check
    for lock contention and need_resched() to either abort async compaction,
    or to free the lock, schedule and retake the lock.  When aborting,
    cc->contended is set to signal the contended state to the caller.  Two
    problems have been identified in this mechanism.
    
    First, compaction also calls directly cond_resched() in both scanners when
    no lock is yet taken.  This call either does not abort async compaction,
    or set cc->contended appropriately.  This patch introduces a new
    compact_should_abort() function to achieve both.  In isolate_freepages(),
    the check frequency is reduced to once by SWAP_CLUSTER_MAX pageblocks to
    match what the migration scanner does in the preliminary page checks.  In
    case a pageblock is found suitable for calling isolate_freepages_block(),
    the checks within there are done on higher frequency.
    
    Second, isolate_freepages() does not check if isolate_freepages_block()
    aborted due to contention, and advances to the next pageblock.  This
    violates the principle of aborting on contention, and might result in
    pageblocks not being scanned completely, since the scanning cursor is
    advanced.  This problem has been noticed in the code by Joonsoo Kim when
    reviewing related patches.  This patch makes isolate_freepages_block()
    check the cc->contended flag and abort.
    
    In case isolate_freepages() has already isolated some pages before
    aborting due to contention, page migration will proceed, which is OK since
    we do not want to waste the work that has been done, and page migration
    has own checks for contention.  However, we do not want another isolation
    attempt by either of the scanners, so cc->contended flag check is added
    also to compaction_alloc() and compact_finished() to make sure compaction
    is aborted right after the migration.
    
    The outcome of the patch should be reduced lock contention by async
    compaction and lower latencies for higher-order allocations where direct
    compaction is involved.
    
    [akpm@linux-foundation.org: fix typo in comment]
    Reported-by: default avatarJoonsoo Kim <iamjoonsoo.kim@lge.com>
    Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
    Reviewed-by: default avatarNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
    Cc: Minchan Kim <minchan@kernel.org>
    Cc: Mel Gorman <mgorman@suse.de>
    Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
    Cc: Michal Nazarewicz <mina86@mina86.com>
    Cc: Christoph Lameter <cl@linux.com>
    Cc: Rik van Riel <riel@redhat.com>
    Acked-by: default avatarMichal Nazarewicz <mina86@mina86.com>
    Tested-by: default avatarShawn Guo <shawn.guo@linaro.org>
    Tested-by: default avatarKevin Hilman <khilman@linaro.org>
    Tested-by: Stephen Warren's avatarStephen Warren <swarren@nvidia.com>
    Tested-by: default avatarFabio Estevam <fabio.estevam@freescale.com>
    Cc: David Rientjes <rientjes@google.com>
    Cc: Stephen Rothwell <sfr@canb.auug.org.au>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    be976572