From patchwork Fri Jan 4 12:50:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mel Gorman X-Patchwork-Id: 10748345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D56C913B5 for ; Fri, 4 Jan 2019 12:54:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C54B628450 for ; Fri, 4 Jan 2019 12:54:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B910D2847E; Fri, 4 Jan 2019 12:54:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0FE9428450 for ; Fri, 4 Jan 2019 12:54:20 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 0781D8E00E9; Fri, 4 Jan 2019 07:54:19 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 04CBD8E00AE; Fri, 4 Jan 2019 07:54:19 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E333D8E00E9; Fri, 4 Jan 2019 07:54:18 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by kanga.kvack.org (Postfix) with ESMTP id 87EC78E00AE for ; Fri, 4 Jan 2019 07:54:18 -0500 (EST) Received: by mail-ed1-f69.google.com with SMTP id 39so35263097edq.13 for ; Fri, 04 Jan 2019 04:54:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=O9RGkFe8csXG+P7/vbPud3vVSE6KR+MXgQLqDX1fNis=; b=Rky5L6Y7Egxndta7mo6YV10IcXz6LHP3rpB4o7TVIqFHYjSDtRZPtj75guvE65vSvY 1e5uLej94ZiBsvX4k2Q+M/5AeGf1x958y830V32Jyy0RE911f0F09kE87d1jRBOilJZh AdtQYPUuEVo9Pj16cCukKDPOLk64Hc+nSJJ1nTxrjEBrf4bVSEG1Mzi9EV23CiPkbkRl wk64em/oeiKelbXbObBUhD7Lce9tMSSFFaNw2xIbJ84G5bbMAYMAOJi+/5aO/2zNOqTT HcGgcQ1t5dVLUWdSVYSH1tuAGVXeH/5Aj3gArOnF/h9haH+7NYhR187dFB3sDyoKF905 W6pA== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of mgorman@techsingularity.net designates 46.22.139.13 as permitted sender) smtp.mailfrom=mgorman@techsingularity.net X-Gm-Message-State: AA+aEWZU4bMG5tmGXnyrcEShJro896ezbQ0mYb9qCsFFJKwM+JKl2Kue uvyT8qxTs7EYe3tKqx9dRPGQAkrPgTNowGhYj7emO0a3/J986cGWjPwyRyEP33dUMSYWhQiumEM 7TLWuHjHzq1iSLRT2iNsSXajLXzRgMFB68SsyIJxyGEaZN9oDlf7848xfNHGNjKggJA== X-Received: by 2002:a50:8907:: with SMTP id e7mr47257398ede.252.1546606458030; Fri, 04 Jan 2019 04:54:18 -0800 (PST) X-Google-Smtp-Source: AFSGD/WRvEyAN7EOjXpwxnWK9/2fifLqQrhPj6sziqLqWF0ms7RZkTR0vfDrmUZmSF/psmQDH/T+ X-Received: by 2002:a50:8907:: with SMTP id e7mr47257352ede.252.1546606457014; Fri, 04 Jan 2019 04:54:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546606456; cv=none; d=google.com; s=arc-20160816; b=ra3qwirDNLOEQOWCidGysc4cRR/2a8Jbjwbody/eaBrDwyTQ732mkt4D/q8qOngNGk Thc8p64NeglzPjspiXGYnPfGIzUpqgWMM4VxD1BbLFOEoHrfKFTg8Pq9TcB6tqJHb/PA 7jA6q5a3DMiQR7IgdXjgy+ut8xuMtlbHv9+F+bykgMwQeTE777oFgS1SDeDzwJ+fnk4i 3leUVdLwZZ+M1uEkY+97ARHU5L/l6Zk0eEynp8E1FMP+g70Q9mPJlXvwSH9Bl0TYrC6m r6XJjieSw1dDawZeI6iAsU5EDthexu08npZzQ6f/uD6i/HZ/NeDLvv/6QEIU4z+1TGsS uqRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=O9RGkFe8csXG+P7/vbPud3vVSE6KR+MXgQLqDX1fNis=; b=ibgW3sN19Q7Y+y9MyJmXCgxbEbwkOyV3F9Iubw3aicrq0QDflRaNtMwJ/BaXW5Lq8F S9uJXgQ3uTOHZvshmA/XIFrYKieUAZqqRYhRV1ESNt2Yv0CDZNp/JfAcxFN7PJEvl4Gs Qso1IXBB6VIZx8F0rBrc/iUojmeF3sP+al/HoeOCy3aQGmu3hP79y6Em7FcTdihz//3s VSV5sI3rTj1XfgeBEc1x2LAul499yO8zB6YfT/8vB+oZFu+3FyYsRHzANEXXmE1hqXuz ctqy7MmLqe/vF4IBWunv7sK6pClJgkfXDjjufITen/JHwCi9dmB48beLP/tUlnkrqSxY +SBQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of mgorman@techsingularity.net designates 46.22.139.13 as permitted sender) smtp.mailfrom=mgorman@techsingularity.net Received: from outbound-smtp08.blacknight.com (outbound-smtp08.blacknight.com. [46.22.139.13]) by mx.google.com with ESMTPS id r24si206942edp.187.2019.01.04.04.54.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Jan 2019 04:54:16 -0800 (PST) Received-SPF: pass (google.com: domain of mgorman@techsingularity.net designates 46.22.139.13 as permitted sender) client-ip=46.22.139.13; Authentication-Results: mx.google.com; spf=pass (google.com: domain of mgorman@techsingularity.net designates 46.22.139.13 as permitted sender) smtp.mailfrom=mgorman@techsingularity.net Received: from mail.blacknight.com (pemlinmail03.blacknight.ie [81.17.254.16]) by outbound-smtp08.blacknight.com (Postfix) with ESMTPS id A3EF61C1C34 for ; Fri, 4 Jan 2019 12:54:16 +0000 (GMT) Received: (qmail 11447 invoked from network); 4 Jan 2019 12:54:16 -0000 Received: from unknown (HELO stampy.163woodhaven.lan) (mgorman@techsingularity.net@[37.228.229.96]) by 81.17.254.9 with ESMTPA; 4 Jan 2019 12:54:16 -0000 From: Mel Gorman To: Linux-MM Cc: David Rientjes , Andrea Arcangeli , Vlastimil Babka , ying.huang@intel.com, kirill@shutemov.name, Andrew Morton , Linux List Kernel Mailing , Mel Gorman Subject: [PATCH 23/25] mm, compaction: Be selective about what pageblocks to clear skip hints Date: Fri, 4 Jan 2019 12:50:09 +0000 Message-Id: <20190104125011.16071-24-mgorman@techsingularity.net> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190104125011.16071-1-mgorman@techsingularity.net> References: <20190104125011.16071-1-mgorman@techsingularity.net> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Pageblock hints are cleared when compaction restarts or kswapd makes enough progress that it can sleep but it's over-eager in that the bit is cleared for migration sources with no LRU pages and migration targets with no free pages. As pageblock skip hint flushes are relatively rare and out-of-band with respect to kswapd, this patch makes a few more expensive checks to see if it's appropriate to even clear the bit. Every pageblock that is not cleared will avoid 512 pages being scanned unnecessarily on x86-64. The impact is variable with different workloads showing small differences in latency, success rates and scan rates. This is expected as clearing the hints is not that common but doing a small amount of work out-of-band to avoid a large amount of work in-band later is generally a good thing. Signed-off-by: Mel Gorman --- include/linux/mmzone.h | 2 + mm/compaction.c | 119 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 102 insertions(+), 19 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index cc4a507d7ca4..faa1e6523f49 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -480,6 +480,8 @@ struct zone { unsigned long compact_cached_free_pfn; /* pfn where async and sync compaction migration scanner should start */ unsigned long compact_cached_migrate_pfn[2]; + unsigned long compact_init_migrate_pfn; + unsigned long compact_init_free_pfn; #endif #ifdef CONFIG_COMPACTION diff --git a/mm/compaction.c b/mm/compaction.c index cc532e81a7b7..7f316e1a7275 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -231,6 +231,62 @@ static bool pageblock_skip_persistent(struct page *page) return false; } +static bool +__reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source, + bool check_target) +{ + struct page *page = pfn_to_online_page(pfn); + struct page *end_page; + + if (!page) + return false; + if (zone != page_zone(page)) + return false; + if (pageblock_skip_persistent(page)) + return false; + + /* + * If skip is already cleared do no further checking once the + * restart points have been set. + */ + if (check_source && check_target && !get_pageblock_skip(page)) + return true; + + /* + * If clearing skip for the target scanner, do not select a + * non-movable pageblock as the starting point. + */ + if (!check_source && check_target && + get_pageblock_migratetype(page) != MIGRATE_MOVABLE) + return false; + + /* + * Only clear the hint if a sample indicates there is either a + * free page or an LRU page in the block. One or other condition + * is necessary for the block to be a migration source/target. + */ + page = pfn_to_page(pageblock_start_pfn(pfn)); + if (zone != page_zone(page)) + return false; + end_page = page + pageblock_nr_pages; + + do { + if (check_source && PageLRU(page)) { + clear_pageblock_skip(page); + return true; + } + + if (check_target && PageBuddy(page)) { + clear_pageblock_skip(page); + return true; + } + + page += (1 << PAGE_ALLOC_COSTLY_ORDER); + } while (page < end_page); + + return false; +} + /* * This function is called to clear all cached information on pageblocks that * should be skipped for page isolation when the migrate and free page scanner @@ -238,30 +294,54 @@ static bool pageblock_skip_persistent(struct page *page) */ static void __reset_isolation_suitable(struct zone *zone) { - unsigned long start_pfn = zone->zone_start_pfn; - unsigned long end_pfn = zone_end_pfn(zone); - unsigned long pfn; + unsigned long migrate_pfn = zone->zone_start_pfn; + unsigned long free_pfn = zone_end_pfn(zone); + unsigned long reset_migrate = free_pfn; + unsigned long reset_free = migrate_pfn; + bool source_set = false; + bool free_set = false; - zone->compact_blockskip_flush = false; + if (!zone->compact_blockskip_flush) + return; - /* Walk the zone and mark every pageblock as suitable for isolation */ - for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) { - struct page *page; + zone->compact_blockskip_flush = false; + /* + * Walk the zone and update pageblock skip information. Source looks + * for PageLRU while target looks for PageBuddy. When the scanner + * is found, both PageBuddy and PageLRU are checked as the pageblock + * is suitable as both source and target. + */ + for (; migrate_pfn < free_pfn; migrate_pfn += pageblock_nr_pages, + free_pfn -= pageblock_nr_pages) { cond_resched(); - page = pfn_to_online_page(pfn); - if (!page) - continue; - if (zone != page_zone(page)) - continue; - if (pageblock_skip_persistent(page)) - continue; + /* Update the migrate PFN */ + if (__reset_isolation_pfn(zone, migrate_pfn, true, source_set) && + migrate_pfn < reset_migrate) { + source_set = true; + reset_migrate = migrate_pfn; + zone->compact_init_migrate_pfn = reset_migrate; + zone->compact_cached_migrate_pfn[0] = reset_migrate; + zone->compact_cached_migrate_pfn[1] = reset_migrate; + } - clear_pageblock_skip(page); + /* Update the free PFN */ + if (__reset_isolation_pfn(zone, free_pfn, free_set, true) && + free_pfn > reset_free) { + free_set = true; + reset_free = free_pfn; + zone->compact_init_free_pfn = reset_free; + zone->compact_cached_free_pfn = reset_free; + } } - reset_cached_positions(zone); + /* Leave no distance if no suitable block was reset */ + if (reset_migrate >= reset_free) { + zone->compact_cached_migrate_pfn[0] = migrate_pfn; + zone->compact_cached_migrate_pfn[1] = migrate_pfn; + zone->compact_cached_free_pfn = free_pfn; + } } void reset_isolation_suitable(pg_data_t *pgdat) @@ -1193,7 +1273,7 @@ fast_isolate_freepages(struct compact_control *cc) * If starting the scan, use a deeper search and use the highest * PFN found if a suitable one is not found. */ - if (cc->free_pfn == pageblock_start_pfn(zone_end_pfn(cc->zone) - 1)) { + if (cc->free_pfn >= cc->zone->compact_init_free_pfn) { limit = pageblock_nr_pages >> 1; scan_start = true; } @@ -1338,7 +1418,6 @@ static void isolate_freepages(struct compact_control *cc) unsigned long isolate_start_pfn; /* exact pfn we start at */ unsigned long block_end_pfn; /* end of current pageblock */ unsigned long low_pfn; /* lowest pfn scanner is able to scan */ - unsigned long nr_isolated; struct list_head *freelist = &cc->freepages; unsigned int stride; @@ -1374,6 +1453,8 @@ static void isolate_freepages(struct compact_control *cc) block_end_pfn = block_start_pfn, block_start_pfn -= pageblock_nr_pages, isolate_start_pfn = block_start_pfn) { + unsigned long nr_isolated; + /* * This can iterate a massively long zone without finding any * suitable migration targets, so periodically check resched. @@ -2020,7 +2101,7 @@ static enum compact_result compact_zone(struct compact_control *cc) cc->zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn; } - if (cc->migrate_pfn == start_pfn) + if (cc->migrate_pfn <= cc->zone->compact_init_migrate_pfn) cc->whole_zone = true; }