anolis: mm, kidled: set age value in the flags of head pages

ANBZ: #6572

Patch series "Free some vmemmap pages of HugeTLB page" make
the vmemmap pages of tail pages readonly, which will result
in kernel panic when kidled store the age value into the flags
of tail pages.

In the patch, we only store the age value in the head pages.

Signed-off-by: Ning Zhang <ningzhang@linux.alibaba.com>
Reviewed-by: Xu Yu <xuyu@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/2181
This commit is contained in:
Ning Zhang 2023-09-14 11:10:28 +08:00 committed by 小龙
parent f8986d6ea7
commit 3f29353eb6
4 changed files with 6 additions and 4 deletions

View File

@ -1534,6 +1534,7 @@ static inline int kidled_get_page_age(pg_data_t *pgdat, unsigned long pfn)
{
struct page *page = pfn_to_page(pfn);
page = compound_head(page);
return (page->flags >> KIDLED_AGE_PGSHIFT) & KIDLED_AGE_MASK;
}

View File

@ -109,6 +109,7 @@
#define KIDLED_AGE_WIDTH 0
#endif
#define KIDLED_AGE_OFFSET_MASK ((BIT(KIDLED_AGE_WIDTH) - 1) << KIDLED_AGE_PGOFF)
/*
* We are going to use the flags for the page to node mapping if its in
* there. This includes the case where there is no node, so it is implicit.

View File

@ -2741,7 +2741,8 @@ static void __split_huge_page_tail(struct page *head, int tail,
(1L << PG_arch_2) |
#endif
(1L << PG_dirty) |
LRU_GEN_MASK | LRU_REFS_MASK));
LRU_GEN_MASK | LRU_REFS_MASK |
KIDLED_AGE_OFFSET_MASK));
/* ->mapping in first tail page is compound_mapcount */
VM_BUG_ON_PAGE(tail > 3 && page_tail->mapping != TAIL_MAPPING,

View File

@ -131,6 +131,7 @@ int kidled_inc_page_age(pg_data_t *pgdat, unsigned long pfn)
unsigned long old, new;
int age;
page = compound_head(page);
do {
age = ((page->flags >> KIDLED_AGE_PGSHIFT) & KIDLED_AGE_MASK);
if (age >= KIDLED_AGE_MASK)
@ -151,6 +152,7 @@ void kidled_set_page_age(pg_data_t *pgdat, unsigned long pfn, int val)
struct page *page = pfn_to_page(pfn);
unsigned long old, new;
page = compound_head(page);
do {
new = old = page->flags;
new &= ~(KIDLED_AGE_MASK << KIDLED_AGE_PGSHIFT);
@ -497,9 +499,6 @@ static inline int kidled_scan_page(pg_data_t *pgdat, unsigned long pfn)
}
}
for (idx = 1; idx < nr_pages; idx++)
kidled_set_page_age(pgdat, pfn + idx, age);
out:
return nr_pages;
}