lkml.org 
[lkml]   [2020]   [Nov]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v6 11/16] mm/hugetlb: Introduce remap_huge_page_pmd_vmemmap helper
Date
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@bytedance.com>
---
mm/hugetlb_vmemmap.c | 87 +++++++++++++++++++++-------------------------------
1 file changed, 35 insertions(+), 52 deletions(-)

diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index d6a1b06c1322..509ca451e232 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -127,6 +127,10 @@
(__boundary - 1 < (end) - 1) ? __boundary : (end); \
})

+typedef void (*vmemmap_pte_remap_func_t)(struct page *reuse, pte_t *ptep,
+ unsigned long start, unsigned long end,
+ void *priv);
+
static inline unsigned int vmemmap_pages_per_hpage(struct hstate *h)
{
return free_vmemmap_pages_per_hpage(h) + RESERVE_VMEMMAP_NR;
@@ -162,21 +166,42 @@ static pmd_t *vmemmap_to_pmd(unsigned long page)
return pmd_offset(pud, page);
}

+static void remap_huge_page_pmd_vmemmap(pmd_t *pmd, unsigned long start,
+ unsigned long end,
+ vmemmap_pte_remap_func_t fn, void *priv)
+{
+ unsigned long next, addr = start;
+ struct page *reuse = NULL;
+
+ 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);
+ fn(reuse, ptep, addr, next, priv);
+ } 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,
- struct list_head *remap_pages)
+ unsigned long end, void *priv)
{
pgprot_t pgprot = PAGE_KERNEL;
void *from = page_to_virt(reuse);
unsigned long addr;
+ struct list_head *pages = priv;

for (addr = start; addr < end; addr += PAGE_SIZE) {
void *to;
struct page *page;
pte_t entry, old = *ptep;

- page = list_first_entry(remap_pages, struct page, lru);
+ page = list_first_entry(pages, struct page, lru);
list_del(&page->lru);
to = page_to_virt(page);
copy_page(to, from);
@@ -196,28 +221,6 @@ static void __remap_huge_page_pte_vmemmap(struct page *reuse, pte_t *ptep,
}
}

-static void __remap_huge_page_pmd_vmemmap(pmd_t *pmd, unsigned long start,
- unsigned long end,
- struct list_head *vmemmap_pages)
-{
- unsigned long next, addr = start;
- struct page *reuse = NULL;
-
- 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,
- vmemmap_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)
{
unsigned int nr = free_vmemmap_pages_per_hpage(h);
@@ -258,7 +261,8 @@ void alloc_huge_page_vmemmap(struct hstate *h, struct page *head)

start = vmemmap_addr + RESERVE_VMEMMAP_SIZE;
end = vmemmap_addr + vmemmap_pages_size_per_hpage(h);
- __remap_huge_page_pmd_vmemmap(pmd, start, end, &map_pages);
+ remap_huge_page_pmd_vmemmap(pmd, start, end,
+ __remap_huge_page_pte_vmemmap, &map_pages);
}

static inline void free_vmemmap_page_list(struct list_head *list)
@@ -273,13 +277,13 @@ static inline void free_vmemmap_page_list(struct list_head *list)

static void __free_huge_page_pte_vmemmap(struct page *reuse, pte_t *ptep,
unsigned long start,
- unsigned long end,
- struct list_head *free_pages)
+ unsigned long end, void *priv)
{
/* Make the tail pages are mapped read-only. */
pgprot_t pgprot = PAGE_KERNEL_RO;
pte_t entry = mk_pte(reuse, pgprot);
unsigned long addr;
+ struct list_head *pages = priv;

for (addr = start; addr < end; addr += PAGE_SIZE, ptep++) {
struct page *page;
@@ -287,34 +291,12 @@ static void __free_huge_page_pte_vmemmap(struct page *reuse, pte_t *ptep,

VM_WARN_ON(!pte_present(old));
page = pte_page(old);
- list_add(&page->lru, free_pages);
+ list_add(&page->lru, pages);

set_pte_at(&init_mm, addr, ptep, entry);
}
}

-static void __free_huge_page_pmd_vmemmap(pmd_t *pmd, unsigned long start,
- unsigned long end,
- struct list_head *vmemmap_pages)
-{
- unsigned long next, addr = start;
- struct page *reuse = NULL;
-
- 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,
- vmemmap_pages);
- } while (pmd++, addr = next, addr != end);
-
- flush_tlb_kernel_range(start, end);
-}
-
void free_huge_page_vmemmap(struct hstate *h, struct page *head)
{
pmd_t *pmd;
@@ -330,7 +312,8 @@ void free_huge_page_vmemmap(struct hstate *h, struct page *head)

start = vmemmap_addr + RESERVE_VMEMMAP_SIZE;
end = vmemmap_addr + vmemmap_pages_size_per_hpage(h);
- __free_huge_page_pmd_vmemmap(pmd, start, end, &free_pages);
+ remap_huge_page_pmd_vmemmap(pmd, start, end,
+ __free_huge_page_pte_vmemmap, &free_pages);
free_vmemmap_page_list(&free_pages);
}

--
2.11.0
\
 
 \ /
  Last update: 2020-11-24 11:10    [W:0.683 / U:0.300 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site