Skip to content

Commit e6ebf01

Browse files
committed
Merge tag 'mm-hotfixes-stable-2024-04-26-13-30' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "11 hotfixes. 8 are cc:stable and the remaining 3 (nice ratio!) address post-6.8 issues or aren't considered suitable for backporting. All except one of these are for MM. I see no particular theme - it's singletons all over" * tag 'mm-hotfixes-stable-2024-04-26-13-30' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mm/hugetlb: fix DEBUG_LOCKS_WARN_ON(1) when dissolve_free_hugetlb_folio() selftests: mm: protection_keys: save/restore nr_hugepages value from launch script stackdepot: respect __GFP_NOLOCKDEP allocation flag hugetlb: check for anon_vma prior to folio allocation mm: zswap: fix shrinker NULL crash with cgroup_disable=memory mm: turn folio_test_hugetlb into a PageType mm: support page_mapcount() on page_has_type() pages mm: create FOLIO_FLAG_FALSE and FOLIO_TYPE_OPS macros mm/hugetlb: fix missing hugetlb_lock for resv uncharge selftests: mm: fix unused and uninitialized variable warning selftests/harness: remove use of LINE_MAX
2 parents 4630932 + 52ccdde commit e6ebf01

File tree

13 files changed

+137
-152
lines changed

13 files changed

+137
-152
lines changed

fs/proc/page.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
6767
*/
6868
ppage = pfn_to_online_page(pfn);
6969

70-
if (!ppage || PageSlab(ppage) || page_has_type(ppage))
70+
if (!ppage)
7171
pcount = 0;
7272
else
7373
pcount = page_mapcount(ppage);
@@ -124,11 +124,8 @@ u64 stable_page_flags(struct page *page)
124124

125125
/*
126126
* pseudo flags for the well known (anonymous) memory mapped pages
127-
*
128-
* Note that page->_mapcount is overloaded in SLAB, so the
129-
* simple test in page_mapped() is not enough.
130127
*/
131-
if (!PageSlab(page) && page_mapped(page))
128+
if (page_mapped(page))
132129
u |= 1 << KPF_MMAP;
133130
if (PageAnon(page))
134131
u |= 1 << KPF_ANON;

include/linux/mm.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,14 +1223,16 @@ static inline void page_mapcount_reset(struct page *page)
12231223
* a large folio, it includes the number of times this page is mapped
12241224
* as part of that folio.
12251225
*
1226-
* The result is undefined for pages which cannot be mapped into userspace.
1227-
* For example SLAB or special types of pages. See function page_has_type().
1228-
* They use this field in struct page differently.
1226+
* Will report 0 for pages which cannot be mapped into userspace, eg
1227+
* slab, page tables and similar.
12291228
*/
12301229
static inline int page_mapcount(struct page *page)
12311230
{
12321231
int mapcount = atomic_read(&page->_mapcount) + 1;
12331232

1233+
/* Handle page_has_type() pages */
1234+
if (mapcount < 0)
1235+
mapcount = 0;
12341236
if (unlikely(PageCompound(page)))
12351237
mapcount += folio_entire_mapcount(page_folio(page));
12361238

include/linux/page-flags.h

Lines changed: 82 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ enum pageflags {
190190

191191
/* At least one page in this folio has the hwpoison flag set */
192192
PG_has_hwpoisoned = PG_error,
193-
PG_hugetlb = PG_active,
194193
PG_large_rmappable = PG_workingset, /* anon or file-backed */
195194
};
196195

@@ -458,30 +457,51 @@ static __always_inline int TestClearPage##uname(struct page *page) \
458457
TESTSETFLAG(uname, lname, policy) \
459458
TESTCLEARFLAG(uname, lname, policy)
460459

460+
#define FOLIO_TEST_FLAG_FALSE(name) \
461+
static inline bool folio_test_##name(const struct folio *folio) \
462+
{ return false; }
463+
#define FOLIO_SET_FLAG_NOOP(name) \
464+
static inline void folio_set_##name(struct folio *folio) { }
465+
#define FOLIO_CLEAR_FLAG_NOOP(name) \
466+
static inline void folio_clear_##name(struct folio *folio) { }
467+
#define __FOLIO_SET_FLAG_NOOP(name) \
468+
static inline void __folio_set_##name(struct folio *folio) { }
469+
#define __FOLIO_CLEAR_FLAG_NOOP(name) \
470+
static inline void __folio_clear_##name(struct folio *folio) { }
471+
#define FOLIO_TEST_SET_FLAG_FALSE(name) \
472+
static inline bool folio_test_set_##name(struct folio *folio) \
473+
{ return false; }
474+
#define FOLIO_TEST_CLEAR_FLAG_FALSE(name) \
475+
static inline bool folio_test_clear_##name(struct folio *folio) \
476+
{ return false; }
477+
478+
#define FOLIO_FLAG_FALSE(name) \
479+
FOLIO_TEST_FLAG_FALSE(name) \
480+
FOLIO_SET_FLAG_NOOP(name) \
481+
FOLIO_CLEAR_FLAG_NOOP(name)
482+
461483
#define TESTPAGEFLAG_FALSE(uname, lname) \
462-
static inline bool folio_test_##lname(const struct folio *folio) { return false; } \
484+
FOLIO_TEST_FLAG_FALSE(lname) \
463485
static inline int Page##uname(const struct page *page) { return 0; }
464486

465487
#define SETPAGEFLAG_NOOP(uname, lname) \
466-
static inline void folio_set_##lname(struct folio *folio) { } \
488+
FOLIO_SET_FLAG_NOOP(lname) \
467489
static inline void SetPage##uname(struct page *page) { }
468490

469491
#define CLEARPAGEFLAG_NOOP(uname, lname) \
470-
static inline void folio_clear_##lname(struct folio *folio) { } \
492+
FOLIO_CLEAR_FLAG_NOOP(lname) \
471493
static inline void ClearPage##uname(struct page *page) { }
472494

473495
#define __CLEARPAGEFLAG_NOOP(uname, lname) \
474-
static inline void __folio_clear_##lname(struct folio *folio) { } \
496+
__FOLIO_CLEAR_FLAG_NOOP(lname) \
475497
static inline void __ClearPage##uname(struct page *page) { }
476498

477499
#define TESTSETFLAG_FALSE(uname, lname) \
478-
static inline bool folio_test_set_##lname(struct folio *folio) \
479-
{ return 0; } \
500+
FOLIO_TEST_SET_FLAG_FALSE(lname) \
480501
static inline int TestSetPage##uname(struct page *page) { return 0; }
481502

482503
#define TESTCLEARFLAG_FALSE(uname, lname) \
483-
static inline bool folio_test_clear_##lname(struct folio *folio) \
484-
{ return 0; } \
504+
FOLIO_TEST_CLEAR_FLAG_FALSE(lname) \
485505
static inline int TestClearPage##uname(struct page *page) { return 0; }
486506

487507
#define PAGEFLAG_FALSE(uname, lname) TESTPAGEFLAG_FALSE(uname, lname) \
@@ -855,29 +875,6 @@ TESTPAGEFLAG_FALSE(LargeRmappable, large_rmappable)
855875

856876
#define PG_head_mask ((1UL << PG_head))
857877

858-
#ifdef CONFIG_HUGETLB_PAGE
859-
int PageHuge(const struct page *page);
860-
SETPAGEFLAG(HugeTLB, hugetlb, PF_SECOND)
861-
CLEARPAGEFLAG(HugeTLB, hugetlb, PF_SECOND)
862-
863-
/**
864-
* folio_test_hugetlb - Determine if the folio belongs to hugetlbfs
865-
* @folio: The folio to test.
866-
*
867-
* Context: Any context. Caller should have a reference on the folio to
868-
* prevent it from being turned into a tail page.
869-
* Return: True for hugetlbfs folios, false for anon folios or folios
870-
* belonging to other filesystems.
871-
*/
872-
static inline bool folio_test_hugetlb(const struct folio *folio)
873-
{
874-
return folio_test_large(folio) &&
875-
test_bit(PG_hugetlb, const_folio_flags(folio, 1));
876-
}
877-
#else
878-
TESTPAGEFLAG_FALSE(Huge, hugetlb)
879-
#endif
880-
881878
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
882879
/*
883880
* PageHuge() only returns true for hugetlbfs pages, but not for
@@ -933,34 +930,23 @@ PAGEFLAG_FALSE(HasHWPoisoned, has_hwpoisoned)
933930
TESTSCFLAG_FALSE(HasHWPoisoned, has_hwpoisoned)
934931
#endif
935932

936-
/*
937-
* Check if a page is currently marked HWPoisoned. Note that this check is
938-
* best effort only and inherently racy: there is no way to synchronize with
939-
* failing hardware.
940-
*/
941-
static inline bool is_page_hwpoison(struct page *page)
942-
{
943-
if (PageHWPoison(page))
944-
return true;
945-
return PageHuge(page) && PageHWPoison(compound_head(page));
946-
}
947-
948933
/*
949934
* For pages that are never mapped to userspace (and aren't PageSlab),
950935
* page_type may be used. Because it is initialised to -1, we invert the
951936
* sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and
952937
* __ClearPageFoo *sets* the bit used for PageFoo. We reserve a few high and
953-
* low bits so that an underflow or overflow of page_mapcount() won't be
938+
* low bits so that an underflow or overflow of _mapcount won't be
954939
* mistaken for a page type value.
955940
*/
956941

957942
#define PAGE_TYPE_BASE 0xf0000000
958-
/* Reserve 0x0000007f to catch underflows of page_mapcount */
943+
/* Reserve 0x0000007f to catch underflows of _mapcount */
959944
#define PAGE_MAPCOUNT_RESERVE -128
960945
#define PG_buddy 0x00000080
961946
#define PG_offline 0x00000100
962947
#define PG_table 0x00000200
963948
#define PG_guard 0x00000400
949+
#define PG_hugetlb 0x00000800
964950

965951
#define PageType(page, flag) \
966952
((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
@@ -977,35 +963,38 @@ static inline int page_has_type(const struct page *page)
977963
return page_type_has_type(page->page_type);
978964
}
979965

966+
#define FOLIO_TYPE_OPS(lname, fname) \
967+
static __always_inline bool folio_test_##fname(const struct folio *folio)\
968+
{ \
969+
return folio_test_type(folio, PG_##lname); \
970+
} \
971+
static __always_inline void __folio_set_##fname(struct folio *folio) \
972+
{ \
973+
VM_BUG_ON_FOLIO(!folio_test_type(folio, 0), folio); \
974+
folio->page.page_type &= ~PG_##lname; \
975+
} \
976+
static __always_inline void __folio_clear_##fname(struct folio *folio) \
977+
{ \
978+
VM_BUG_ON_FOLIO(!folio_test_##fname(folio), folio); \
979+
folio->page.page_type |= PG_##lname; \
980+
}
981+
980982
#define PAGE_TYPE_OPS(uname, lname, fname) \
983+
FOLIO_TYPE_OPS(lname, fname) \
981984
static __always_inline int Page##uname(const struct page *page) \
982985
{ \
983986
return PageType(page, PG_##lname); \
984987
} \
985-
static __always_inline int folio_test_##fname(const struct folio *folio)\
986-
{ \
987-
return folio_test_type(folio, PG_##lname); \
988-
} \
989988
static __always_inline void __SetPage##uname(struct page *page) \
990989
{ \
991990
VM_BUG_ON_PAGE(!PageType(page, 0), page); \
992991
page->page_type &= ~PG_##lname; \
993992
} \
994-
static __always_inline void __folio_set_##fname(struct folio *folio) \
995-
{ \
996-
VM_BUG_ON_FOLIO(!folio_test_type(folio, 0), folio); \
997-
folio->page.page_type &= ~PG_##lname; \
998-
} \
999993
static __always_inline void __ClearPage##uname(struct page *page) \
1000994
{ \
1001995
VM_BUG_ON_PAGE(!Page##uname(page), page); \
1002996
page->page_type |= PG_##lname; \
1003-
} \
1004-
static __always_inline void __folio_clear_##fname(struct folio *folio) \
1005-
{ \
1006-
VM_BUG_ON_FOLIO(!folio_test_##fname(folio), folio); \
1007-
folio->page.page_type |= PG_##lname; \
1008-
} \
997+
}
1009998

1010999
/*
10111000
* PageBuddy() indicates that the page is free and in the buddy system
@@ -1052,6 +1041,37 @@ PAGE_TYPE_OPS(Table, table, pgtable)
10521041
*/
10531042
PAGE_TYPE_OPS(Guard, guard, guard)
10541043

1044+
#ifdef CONFIG_HUGETLB_PAGE
1045+
FOLIO_TYPE_OPS(hugetlb, hugetlb)
1046+
#else
1047+
FOLIO_TEST_FLAG_FALSE(hugetlb)
1048+
#endif
1049+
1050+
/**
1051+
* PageHuge - Determine if the page belongs to hugetlbfs
1052+
* @page: The page to test.
1053+
*
1054+
* Context: Any context.
1055+
* Return: True for hugetlbfs pages, false for anon pages or pages
1056+
* belonging to other filesystems.
1057+
*/
1058+
static inline bool PageHuge(const struct page *page)
1059+
{
1060+
return folio_test_hugetlb(page_folio(page));
1061+
}
1062+
1063+
/*
1064+
* Check if a page is currently marked HWPoisoned. Note that this check is
1065+
* best effort only and inherently racy: there is no way to synchronize with
1066+
* failing hardware.
1067+
*/
1068+
static inline bool is_page_hwpoison(struct page *page)
1069+
{
1070+
if (PageHWPoison(page))
1071+
return true;
1072+
return PageHuge(page) && PageHWPoison(compound_head(page));
1073+
}
1074+
10551075
extern bool is_free_buddy_page(struct page *page);
10561076

10571077
PAGEFLAG(Isolated, isolated, PF_ANY);
@@ -1118,7 +1138,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
11181138
*/
11191139
#define PAGE_FLAGS_SECOND \
11201140
(0xffUL /* order */ | 1UL << PG_has_hwpoisoned | \
1121-
1UL << PG_hugetlb | 1UL << PG_large_rmappable)
1141+
1UL << PG_large_rmappable)
11221142

11231143
#define PAGE_FLAGS_PRIVATE \
11241144
(1UL << PG_private | 1UL << PG_private_2)

include/trace/events/mmflags.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ IF_HAVE_PG_ARCH_X(arch_3)
135135
#define DEF_PAGETYPE_NAME(_name) { PG_##_name, __stringify(_name) }
136136

137137
#define __def_pagetype_names \
138+
DEF_PAGETYPE_NAME(hugetlb), \
138139
DEF_PAGETYPE_NAME(offline), \
139140
DEF_PAGETYPE_NAME(guard), \
140141
DEF_PAGETYPE_NAME(table), \

kernel/vmcore_info.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,10 @@ static int __init crash_save_vmcoreinfo_init(void)
205205
VMCOREINFO_NUMBER(PG_head_mask);
206206
#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
207207
VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
208-
#ifdef CONFIG_HUGETLB_PAGE
209-
VMCOREINFO_NUMBER(PG_hugetlb);
208+
#define PAGE_HUGETLB_MAPCOUNT_VALUE (~PG_hugetlb)
209+
VMCOREINFO_NUMBER(PAGE_HUGETLB_MAPCOUNT_VALUE);
210210
#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
211211
VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
212-
#endif
213212

214213
#ifdef CONFIG_KALLSYMS
215214
VMCOREINFO_SYMBOL(kallsyms_names);

lib/stackdepot.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,10 +627,10 @@ depot_stack_handle_t stack_depot_save_flags(unsigned long *entries,
627627
/*
628628
* Zero out zone modifiers, as we don't have specific zone
629629
* requirements. Keep the flags related to allocation in atomic
630-
* contexts and I/O.
630+
* contexts, I/O, nolockdep.
631631
*/
632632
alloc_flags &= ~GFP_ZONEMASK;
633-
alloc_flags &= (GFP_ATOMIC | GFP_KERNEL);
633+
alloc_flags &= (GFP_ATOMIC | GFP_KERNEL | __GFP_NOLOCKDEP);
634634
alloc_flags |= __GFP_NOWARN;
635635
page = alloc_pages(alloc_flags, DEPOT_POOL_ORDER);
636636
if (page)

0 commit comments

Comments
 (0)