[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190215220856.29749-22-zi.yan@sent.com>
Date: Fri, 15 Feb 2019 14:08:46 -0800
From: Zi Yan <zi.yan@...t.com>
To: linux-mm@...ck.org, linux-kernel@...r.kernel.org
Cc: Dave Hansen <dave.hansen@...ux.intel.com>,
Michal Hocko <mhocko@...nel.org>,
"Kirill A . Shutemov" <kirill.shutemov@...ux.intel.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Vlastimil Babka <vbabka@...e.cz>,
Mel Gorman <mgorman@...hsingularity.net>,
John Hubbard <jhubbard@...dia.com>,
Mark Hairgrove <mhairgrove@...dia.com>,
Nitin Gupta <nigupta@...dia.com>,
David Nellans <dnellans@...dia.com>, Zi Yan <ziy@...dia.com>
Subject: [RFC PATCH 21/31] mm: thp: 1GB zero page shrinker.
From: Zi Yan <ziy@...dia.com>
Remove 1GB zero page when we are under memory pressure.
Signed-off-by: Zi Yan <ziy@...dia.com>
---
mm/huge_memory.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index bbdbc9ae06bf..41adc103ead1 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -207,6 +207,32 @@ static struct shrinker huge_zero_page_shrinker = {
.seeks = DEFAULT_SEEKS,
};
+static unsigned long shrink_huge_pud_zero_page_count(struct shrinker *shrink,
+ struct shrink_control *sc)
+{
+ /* we can free zero page only if last reference remains */
+ return atomic_read(&huge_pud_zero_refcount) == 1 ? HPAGE_PUD_NR : 0;
+}
+
+static unsigned long shrink_huge_pud_zero_page_scan(struct shrinker *shrink,
+ struct shrink_control *sc)
+{
+ if (atomic_cmpxchg(&huge_pud_zero_refcount, 1, 0) == 1) {
+ struct page *zero_page = xchg(&huge_pud_zero_page, NULL);
+ BUG_ON(zero_page == NULL);
+ __free_pages(zero_page, compound_order(zero_page));
+ return HPAGE_PUD_NR;
+ }
+
+ return 0;
+}
+
+static struct shrinker huge_pud_zero_page_shrinker = {
+ .count_objects = shrink_huge_pud_zero_page_count,
+ .scan_objects = shrink_huge_pud_zero_page_scan,
+ .seeks = DEFAULT_SEEKS,
+};
+
#ifdef CONFIG_SYSFS
static ssize_t enabled_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
@@ -474,6 +500,9 @@ static int __init hugepage_init(void)
err = register_shrinker(&huge_zero_page_shrinker);
if (err)
goto err_hzp_shrinker;
+ err = register_shrinker(&huge_pud_zero_page_shrinker);
+ if (err)
+ goto err_hpzp_shrinker;
err = register_shrinker(&deferred_split_shrinker);
if (err)
goto err_split_shrinker;
@@ -496,6 +525,8 @@ static int __init hugepage_init(void)
err_khugepaged:
unregister_shrinker(&deferred_split_shrinker);
err_split_shrinker:
+ unregister_shrinker(&huge_pud_zero_page_shrinker);
+err_hpzp_shrinker:
unregister_shrinker(&huge_zero_page_shrinker);
err_hzp_shrinker:
khugepaged_destroy();
--
2.20.1
Powered by blists - more mailing lists