[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1588812129-8596-6-git-send-email-anthony.yznaga@oracle.com>
Date: Wed, 6 May 2020 17:41:31 -0700
From: Anthony Yznaga <anthony.yznaga@...cle.com>
To: linux-mm@...ck.org, linux-kernel@...r.kernel.org
Cc: willy@...radead.org, corbet@....net, tglx@...utronix.de,
mingo@...hat.com, bp@...en8.de, x86@...nel.org, hpa@...or.com,
dave.hansen@...ux.intel.com, luto@...nel.org, peterz@...radead.org,
rppt@...ux.ibm.com, akpm@...ux-foundation.org, hughd@...gle.com,
ebiederm@...ssion.com, masahiroy@...nel.org, ardb@...nel.org,
ndesaulniers@...gle.com, dima@...ovin.in, daniel.kiper@...cle.com,
nivedita@...m.mit.edu, rafael.j.wysocki@...el.com,
dan.j.williams@...el.com, zhenzhong.duan@...cle.com,
jroedel@...e.de, bhe@...hat.com, guro@...com,
Thomas.Lendacky@....com, andriy.shevchenko@...ux.intel.com,
keescook@...omium.org, hannes@...xchg.org, minchan@...nel.org,
mhocko@...nel.org, ying.huang@...el.com,
yang.shi@...ux.alibaba.com, gustavo@...eddedor.com,
ziqian.lzq@...fin.com, vdavydov.dev@...il.com,
jason.zeng@...el.com, kevin.tian@...el.com, zhiyuan.lv@...el.com,
lei.l.li@...el.com, paul.c.lai@...el.com, ashok.raj@...el.com,
linux-fsdevel@...r.kernel.org, linux-doc@...r.kernel.org,
kexec@...ts.infradead.org
Subject: [RFC 05/43] mm: PKRAM: support preserving transparent hugepages
Support preserving a transparent hugepage by recording the page order and
a flag indicating it is a THP. Use these values when the page is
restored to reconstruct the THP.
Signed-off-by: Anthony Yznaga <anthony.yznaga@...cle.com>
---
include/linux/pkram.h | 2 ++
mm/pkram.c | 20 ++++++++++++++++----
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/include/linux/pkram.h b/include/linux/pkram.h
index f338d1c2aeb6..584cadb662b4 100644
--- a/include/linux/pkram.h
+++ b/include/linux/pkram.h
@@ -33,6 +33,8 @@ int pkram_prepare_load_obj(struct pkram_stream *ps);
void pkram_finish_load(struct pkram_stream *ps);
void pkram_finish_load_obj(struct pkram_stream *ps);
+#define PKRAM_PAGE_TRANS_HUGE 0x1 /* page is a transparent hugepage */
+
int pkram_save_page(struct pkram_stream *ps, struct page *page, short flags);
struct page *pkram_load_page(struct pkram_stream *ps, unsigned long *index,
short *flags);
diff --git a/mm/pkram.c b/mm/pkram.c
index ab3053ca3539..9164060e36f5 100644
--- a/mm/pkram.c
+++ b/mm/pkram.c
@@ -21,6 +21,7 @@ typedef __u64 pkram_entry_t;
#define PKRAM_ENTRY_FLAGS_SHIFT 0x5
#define PKRAM_ENTRY_FLAGS_MASK 0x7f
+#define PKRAM_ENTRY_ORDER_MASK 0x1f
/*
* Keeps references to data pages saved to PKRAM.
@@ -434,6 +435,7 @@ static int __pkram_save_page(struct pkram_stream *ps,
struct pkram_link *link = ps->link;
struct pkram_obj *obj = ps->obj;
pkram_entry_t p;
+ int order;
if (!link || ps->entry_idx >= PKRAM_LINK_ENTRIES_MAX ||
index != ps->next_index) {
@@ -452,10 +454,15 @@ static int __pkram_save_page(struct pkram_stream *ps,
ps->next_index = link->index = index;
}
- ps->next_index++;
+ if (PageTransHuge(page))
+ flags |= PKRAM_PAGE_TRANS_HUGE;
+
+ order = compound_order(page);
+ ps->next_index += (1 << order);
get_page(page);
p = page_to_phys(page);
+ p |= order;
p |= ((flags & PKRAM_ENTRY_FLAGS_MASK) << PKRAM_ENTRY_FLAGS_SHIFT);
link->entry[ps->entry_idx] = p;
ps->entry_idx++;
@@ -485,8 +492,6 @@ int pkram_save_page(struct pkram_stream *ps, struct page *page, short flags)
BUG_ON((node->flags & PKRAM_ACCMODE_MASK) != PKRAM_SAVE);
- BUG_ON(PageCompound(page));
-
return __pkram_save_page(ps, page, flags, page->index);
}
@@ -499,6 +504,7 @@ static struct page *__pkram_load_page(struct pkram_stream *ps, unsigned long *in
struct pkram_link *link = ps->link;
struct page *page;
pkram_entry_t p;
+ int order;
short flgs;
if (!link) {
@@ -517,14 +523,20 @@ static struct page *__pkram_load_page(struct pkram_stream *ps, unsigned long *in
BUG_ON(!p);
flgs = (p >> PKRAM_ENTRY_FLAGS_SHIFT) & PKRAM_ENTRY_FLAGS_MASK;
+ order = p & PKRAM_ENTRY_ORDER_MASK;
page = pfn_to_page(PHYS_PFN(p));
+ if (flgs & PKRAM_PAGE_TRANS_HUGE) {
+ prep_compound_page(page, order);
+ prep_transhuge_page(page);
+ }
+
if (flags)
*flags = flgs;
if (index)
*index = ps->next_index;
- ps->next_index++;
+ ps->next_index += (1 << order);
/* clear to avoid double free (see pkram_truncate_link()) */
link->entry[ps->entry_idx] = 0;
--
2.13.3
Powered by blists - more mailing lists