[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201113105952.11638-13-songmuchun@bytedance.com>
Date: Fri, 13 Nov 2020 18:59:43 +0800
From: Muchun Song <songmuchun@...edance.com>
To: corbet@....net, mike.kravetz@...cle.com, 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,
viro@...iv.linux.org.uk, akpm@...ux-foundation.org,
paulmck@...nel.org, mchehab+huawei@...nel.org,
pawan.kumar.gupta@...ux.intel.com, rdunlap@...radead.org,
oneukum@...e.com, anshuman.khandual@....com, jroedel@...e.de,
almasrymina@...gle.com, rientjes@...gle.com, willy@...radead.org,
osalvador@...e.de, mhocko@...e.com
Cc: duanxiongchun@...edance.com, linux-doc@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-mm@...ck.org,
linux-fsdevel@...r.kernel.org,
Muchun Song <songmuchun@...edance.com>
Subject: [PATCH v4 12/21] mm/hugetlb: Introduce remap_huge_page_pmd_vmemmap helper
The __free_huge_page_pmd_vmemmap and __remap_huge_page_pmd_vmemmap are
almost the same code. So introduce remap_free_huge_page_pmd_vmemmap
helper to simplify the code.
Signed-off-by: Muchun Song <songmuchun@...edance.com>
---
mm/hugetlb_vmemmap.c | 108 +++++++++++++++++++++------------------------------
1 file changed, 45 insertions(+), 63 deletions(-)
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 9918dc63c062..ae9dbfb682ab 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -221,6 +221,47 @@ static inline int freed_vmemmap_hpage_dec(struct page *page)
return atomic_dec_return_relaxed(&page->_mapcount) + 1;
}
+static inline void free_vmemmap_page_list(struct list_head *list)
+{
+ struct page *page, *next;
+
+ list_for_each_entry_safe(page, next, list, lru) {
+ list_del(&page->lru);
+ free_vmemmap_page(page);
+ }
+}
+
+typedef void (*remap_pte_fn)(struct page *reuse, pte_t *ptep,
+ unsigned long start, unsigned long end,
+ struct list_head *pages);
+
+static void remap_huge_page_pmd_vmemmap(struct hstate *h, pmd_t *pmd,
+ unsigned long addr,
+ struct list_head *pages,
+ remap_pte_fn remap_fn)
+{
+ unsigned long next;
+ unsigned long start = addr + RESERVE_VMEMMAP_SIZE;
+ unsigned long end = addr + vmemmap_pages_size_per_hpage(h);
+ struct page *reuse = NULL;
+
+ flush_cache_vunmap(start, end);
+
+ addr = start;
+ do {
+ pte_t *ptep;
+
+ ptep = pte_offset_kernel(pmd, addr);
+ if (!reuse)
+ reuse = pte_page(ptep[TAIL_PAGE_REUSE]);
+
+ next = vmemmap_hpage_addr_end(addr, end);
+ remap_fn(reuse, ptep, addr, next, pages);
+ } while (pmd++, addr = next, addr != end);
+
+ flush_tlb_kernel_range(start, end);
+}
+
static void __remap_huge_page_pte_vmemmap(struct page *reuse, pte_t *ptep,
unsigned long start,
unsigned long end,
@@ -255,31 +296,6 @@ static void __remap_huge_page_pte_vmemmap(struct page *reuse, pte_t *ptep,
}
}
-static void __remap_huge_page_pmd_vmemmap(struct hstate *h, pmd_t *pmd,
- unsigned long addr,
- struct list_head *remap_pages)
-{
- unsigned long next;
- unsigned long start = addr + RESERVE_VMEMMAP_SIZE;
- unsigned long end = addr + vmemmap_pages_size_per_hpage(h);
- struct page *reuse = NULL;
-
- addr = start;
- do {
- pte_t *ptep;
-
- ptep = pte_offset_kernel(pmd, addr);
- if (!reuse)
- reuse = pte_page(ptep[TAIL_PAGE_REUSE]);
-
- next = vmemmap_hpage_addr_end(addr, end);
- __remap_huge_page_pte_vmemmap(reuse, ptep, addr, next,
- remap_pages);
- } while (pmd++, addr = next, addr != end);
-
- flush_tlb_kernel_range(start, end);
-}
-
static inline void alloc_vmemmap_pages(struct hstate *h, struct list_head *list)
{
int i;
@@ -308,8 +324,8 @@ void alloc_huge_page_vmemmap(struct hstate *h, struct page *head)
BUG_ON(!pmd);
ptl = vmemmap_pmd_lock(pmd);
- __remap_huge_page_pmd_vmemmap(h, pmd, (unsigned long)head,
- &remap_pages);
+ remap_huge_page_pmd_vmemmap(h, pmd, (unsigned long)head, &remap_pages,
+ __remap_huge_page_pte_vmemmap);
if (!freed_vmemmap_hpage_dec(pmd_page(*pmd))) {
/*
* Todo:
@@ -319,16 +335,6 @@ void alloc_huge_page_vmemmap(struct hstate *h, struct page *head)
spin_unlock(ptl);
}
-static inline void free_vmemmap_page_list(struct list_head *list)
-{
- struct page *page, *next;
-
- list_for_each_entry_safe(page, next, list, lru) {
- list_del(&page->lru);
- free_vmemmap_page(page);
- }
-}
-
static void __free_huge_page_pte_vmemmap(struct page *reuse, pte_t *ptep,
unsigned long start,
unsigned long end,
@@ -351,31 +357,6 @@ static void __free_huge_page_pte_vmemmap(struct page *reuse, pte_t *ptep,
}
}
-static void __free_huge_page_pmd_vmemmap(struct hstate *h, pmd_t *pmd,
- unsigned long addr,
- struct list_head *free_pages)
-{
- unsigned long next;
- unsigned long start = addr + RESERVE_VMEMMAP_SIZE;
- unsigned long end = addr + vmemmap_pages_size_per_hpage(h);
- struct page *reuse = NULL;
-
- addr = start;
- do {
- pte_t *ptep;
-
- ptep = pte_offset_kernel(pmd, addr);
- if (!reuse)
- reuse = pte_page(ptep[TAIL_PAGE_REUSE]);
-
- next = vmemmap_hpage_addr_end(addr, end);
- __free_huge_page_pte_vmemmap(reuse, ptep, addr, next,
- free_pages);
- } while (pmd++, addr = next, addr != end);
-
- flush_tlb_kernel_range(start, end);
-}
-
static void split_vmemmap_pmd(pmd_t *pmd, pte_t *pte_p, unsigned long addr)
{
int i;
@@ -434,7 +415,8 @@ void free_huge_page_vmemmap(struct hstate *h, struct page *head)
if (vmemmap_pmd_huge(pmd))
split_vmemmap_huge_page(head, pmd);
- __free_huge_page_pmd_vmemmap(h, pmd, (unsigned long)head, &free_pages);
+ remap_huge_page_pmd_vmemmap(h, pmd, (unsigned long)head, &free_pages,
+ __free_huge_page_pte_vmemmap);
freed_vmemmap_hpage_inc(pmd_page(*pmd));
spin_unlock(ptl);
--
2.11.0
Powered by blists - more mailing lists