linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Huang, Ying" <ying.huang@intel.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Huang Ying <ying.huang@intel.com>,
	David Hildenbrand <david@redhat.com>,
	Mel Gorman <mgorman@suse.de>, Vlastimil Babka <vbabka@suse.cz>,
	Zi Yan <ziy@nvidia.com>, Michal Hocko <mhocko@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Minchan Kim <minchan@kernel.org>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Hugh Dickins <hughd@google.com>
Subject: [RFC 3/3] mm: Discard lazily freed pages when migrating
Date: Fri, 28 Feb 2020 11:38:19 +0800	[thread overview]
Message-ID: <20200228033819.3857058-4-ying.huang@intel.com> (raw)
In-Reply-To: <20200228033819.3857058-1-ying.huang@intel.com>

From: Huang Ying <ying.huang@intel.com>

MADV_FREE is a lazy free mechanism in Linux.  According to the manpage
of mavise(2), the semantics of MADV_FREE is,

  The application no longer requires the pages in the range specified
  by addr and len.  The kernel can thus free these pages, but the
  freeing could be delayed until memory pressure occurs. ...

Originally, the pages freed lazily by MADV_FREE will only be freed
really by page reclaiming when there is memory pressure or when
unmapping the address range.  In addition to that, there's another
opportunity to free these pages really, when we try to migrate them.

The main value to do that is to avoid to create the new memory
pressure immediately if possible.  Instead, even if the pages are
required again, they will be allocated gradually on demand.  That is,
the memory will be allocated lazily when necessary.  This follows the
common philosophy in the Linux kernel, allocate resources lazily on
demand.

Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Hugh Dickins <hughd@google.com>
---
 include/linux/migrate.h |  4 ++++
 mm/huge_memory.c        | 20 +++++++++++++++-----
 mm/migrate.c            | 16 +++++++++++++++-
 mm/rmap.c               | 10 ++++++++++
 4 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 72120061b7d4..2c6cf985a8d3 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -14,8 +14,12 @@ typedef void free_page_t(struct page *page, unsigned long private);
  * Return values from addresss_space_operations.migratepage():
  * - negative errno on page migration failure;
  * - zero on page migration success;
+ *
+ * __unmap_and_move() can also return 1 to indicate the page can be
+ * discarded instead of migrated.
  */
 #define MIGRATEPAGE_SUCCESS		0
+#define MIGRATEPAGE_DISCARD		1
 
 enum migrate_reason {
 	MR_COMPACTION,
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index b1e069e68189..b64f356ab77e 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3063,11 +3063,21 @@ void set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,
 	pmdval = pmdp_invalidate(vma, address, pvmw->pmd);
 	if (pmd_dirty(pmdval))
 		set_page_dirty(page);
-	entry = make_migration_entry(page, pmd_write(pmdval));
-	pmdswp = swp_entry_to_pmd(entry);
-	if (pmd_soft_dirty(pmdval))
-		pmdswp = pmd_swp_mksoft_dirty(pmdswp);
-	set_pmd_at(mm, address, pvmw->pmd, pmdswp);
+	/* Clean lazyfree page, discard instead of migrate */
+	if (PageLazyFree(page) && !PageDirty(page)) {
+		pmd_clear(pvmw->pmd);
+		zap_deposited_table(mm, pvmw->pmd);
+		/* Invalidate as we cleared the pmd */
+		mmu_notifier_invalidate_range(mm, address,
+					      address + HPAGE_PMD_SIZE);
+		add_mm_counter(mm, MM_ANONPAGES, -HPAGE_PMD_NR);
+	} else {
+		entry = make_migration_entry(page, pmd_write(pmdval));
+		pmdswp = swp_entry_to_pmd(entry);
+		if (pmd_soft_dirty(pmdval))
+			pmdswp = pmd_swp_mksoft_dirty(pmdswp);
+		set_pmd_at(mm, address, pvmw->pmd, pmdswp);
+	}
 	page_remove_rmap(page, true);
 	put_page(page);
 }
diff --git a/mm/migrate.c b/mm/migrate.c
index 981f8374a6ef..b7e7d18af94c 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1122,6 +1122,11 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
 			goto out_unlock_both;
 		}
 		page_was_mapped = 1;
+		/* Clean lazyfree page, discard instead of migrate */
+		if (PageLazyFree(page) && !PageDirty(page)) {
+			rc = MIGRATEPAGE_DISCARD;
+			goto out_unlock_both;
+		}
 	}
 
 	if (!page_mapped(page))
@@ -1242,7 +1247,16 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
 				num_poisoned_pages_inc();
 		}
 	} else {
-		if (rc != -EAGAIN) {
+		/*
+		 * If page is discard instead of migrated, release
+		 * reference grabbed during isolation, free the new
+		 * page.  For the caller, this is same as migrating
+		 * successfully.
+		 */
+		if (rc == MIGRATEPAGE_DISCARD) {
+			put_page(page);
+			rc = MIGRATEPAGE_SUCCESS;
+		} else if (rc != -EAGAIN) {
 			if (likely(!__PageMovable(page))) {
 				putback_lru_page(page);
 				goto put_new;
diff --git a/mm/rmap.c b/mm/rmap.c
index 1dcbb1771dd7..bb52883f7b2d 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1569,6 +1569,16 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 			swp_entry_t entry;
 			pte_t swp_pte;
 
+			/* Clean lazyfree page, discard instead of migrate */
+			if (PageLazyFree(page) && !PageDirty(page) &&
+			    !(flags & TTU_SPLIT_FREEZE)) {
+				/* Invalidate as we cleared the pte */
+				mmu_notifier_invalidate_range(mm,
+						address, address + PAGE_SIZE);
+				dec_mm_counter(mm, MM_ANONPAGES);
+				goto discard;
+			}
+
 			if (arch_unmap_one(mm, vma, address, pteval) < 0) {
 				set_pte_at(mm, address, pvmw.pte, pteval);
 				ret = false;
-- 
2.25.0


  parent reply	other threads:[~2020-02-28  3:38 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-28  3:38 [RFC 0/3] mm: Discard lazily freed pages when migrating Huang, Ying
2020-02-28  3:38 ` [RFC 1/3] mm, migrate: Check return value of try_to_unmap() Huang, Ying
2020-02-28  3:38 ` [RFC 2/3] mm: Add a new page flag PageLayzyFree() for MADV_FREE Huang, Ying
2020-02-28  6:13   ` David Hildenbrand
2020-02-28  6:47     ` Huang, Ying
2020-03-15  8:18   ` Wei Yang
2020-03-15  8:54     ` Mika Penttilä
2020-03-15 12:22       ` Wei Yang
2020-03-16  1:21         ` Huang, Ying
2020-03-16 22:38           ` Wei Yang
2020-02-28  3:38 ` Huang, Ying [this message]
2020-02-28  3:42 ` [RFC 0/3] mm: Discard lazily freed pages when migrating Matthew Wilcox
2020-02-28  7:25   ` Huang, Ying
2020-02-28  8:22     ` David Hildenbrand
2020-02-28  8:55       ` Huang, Ying
2020-02-28  9:49         ` Mel Gorman
2020-03-02 11:23           ` Huang, Ying
2020-03-02 15:16             ` Mel Gorman
2020-03-03  1:51               ` Huang, Ying
2020-03-03  8:09                 ` Michal Hocko
2020-03-03  8:47                   ` Huang, Ying
2020-03-03  8:58                     ` Michal Hocko
2020-03-03 11:49                       ` Huang, Ying
2020-03-04  9:58                         ` Michal Hocko
2020-03-04 10:56                           ` Mel Gorman
2020-03-05  1:42                             ` Huang, Ying
2020-03-04 11:15                           ` Huang, Ying
2020-03-04 11:26                             ` Michal Hocko
2020-03-05  1:45                               ` Huang, Ying
2020-03-05 10:48                             ` Mel Gorman
2020-03-06  4:05                               ` Huang, Ying
2020-03-09  5:26                               ` Huang, Ying
2020-03-03 13:02                 ` Mel Gorman
2020-03-04  0:33                   ` Huang, Ying
2020-02-28  9:50         ` Michal Hocko
2020-02-28 10:15           ` Michal Hocko
2020-02-28 13:45           ` Johannes Weiner
2020-03-02 14:12           ` Huang, Ying
2020-03-02 14:23             ` David Hildenbrand
2020-03-03  0:25               ` Huang, Ying
2020-03-02 14:25             ` Michal Hocko
2020-03-03  1:30               ` Huang, Ying
2020-03-03  8:19                 ` Michal Hocko
2020-03-03 11:36                   ` Huang, Ying

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200228033819.3857058-4-ying.huang@intel.com \
    --to=ying.huang@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@redhat.com \
    --cc=hannes@cmpxchg.org \
    --cc=hughd@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@suse.de \
    --cc=mhocko@kernel.org \
    --cc=minchan@kernel.org \
    --cc=peterz@infradead.org \
    --cc=vbabka@suse.cz \
    --cc=ziy@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).