History

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

Linus Torvalds committed 2 years ago

Commit e6ebf012 parents 4630932 52ccdde13 files · +137 −152Browse files

Unified · Split

13 files
  1. fs/proc/page.c +2 −5
  2. include/linux/mm.h +5 −3
  3. include/linux/page-flags.h +82 −62
  4. include/trace/events/mmflags.h +1 −0
  5. kernel/vmcore_info.c +2 −3
  6. lib/stackdepot.c +2 −2
  7. mm/hugetlb.c +15 −25
  8. mm/zswap.c +16 −9
  9. tools/testing/selftests/kselftest_harness.h +8 −4
  10. tools/testing/selftests/mm/mdwe_test.c +1 −0
  11. tools/testing/selftests/mm/protection_keys.c +0 −38
  12. tools/testing/selftests/mm/run_vmtests.sh +2 −0
  13. tools/testing/selftests/mm/split_huge_page_test.c +1 −1
fs/proc/page.c+2−5
@@ -67,7 +67,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, · 66 unmodified lines
67 */67 */
68 ppage = pfn_to_online_page(pfn);68 ppage = pfn_to_online_page(pfn);
69 69
70 if (!ppage || PageSlab(ppage) || page_has_type(ppage))70 if (!ppage)
71 pcount = 0;71 pcount = 0;
72 else72 else
73 pcount = page_mapcount(ppage);73 pcount = page_mapcount(ppage);
@@ -124,11 +124,8 @@ u64 stable_page_flags(struct page *page) · 50 unmodified lines
124 124
125 /*125 /*
126 * pseudo flags for the well known (anonymous) memory mapped pages126 * 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.
130 */127 */
131 if (!PageSlab(page) && page_mapped(page))128 if (page_mapped(page))
132 u |= 1 << KPF_MMAP;129 u |= 1 << KPF_MMAP;
133 if (PageAnon(page))130 if (PageAnon(page))
134 u |= 1 << KPF_ANON;131 u |= 1 << KPF_ANON;
include/linux/mm.h+5−3
@@ -1223,14 +1223,16 @@ static inline void page_mapcount_reset(struct page *page) · 1222 unmodified lines
1223 * a large folio, it includes the number of times this page is mapped1223 * a large folio, it includes the number of times this page is mapped
1224 * as part of that folio.1224 * as part of that folio.
1225 *1225 *
1226 * The result is undefined for pages which cannot be mapped into userspace.1226 * Will report 0 for pages which cannot be mapped into userspace, eg
1227 * For example SLAB or special types of pages. See function page_has_type().1227 * slab, page tables and similar.
1228 * They use this field in struct page differently.
1229 */1228 */
1230static inline int page_mapcount(struct page *page)1229static inline int page_mapcount(struct page *page)
1231{1230{
1232 int mapcount = atomic_read(&page->_mapcount) + 1;1231 int mapcount = atomic_read(&page->_mapcount) + 1;
1233 1232
1233 /* Handle page_has_type() pages */
1234 if (mapcount < 0)
1235 mapcount = 0;
1234 if (unlikely(PageCompound(page)))1236 if (unlikely(PageCompound(page)))
1235 mapcount += folio_entire_mapcount(page_folio(page));1237 mapcount += folio_entire_mapcount(page_folio(page));
1236 1238
include/linux/page-flags.h+82−62
@@ -190,7 +190,6 @@ enum pageflags { · 189 unmodified lines
190 190
191 /* At least one page in this folio has the hwpoison flag set */191 /* At least one page in this folio has the hwpoison flag set */
192 PG_has_hwpoisoned = PG_error,192 PG_has_hwpoisoned = PG_error,
193 PG_hugetlb = PG_active,
194 PG_large_rmappable = PG_workingset, /* anon or file-backed */193 PG_large_rmappable = PG_workingset, /* anon or file-backed */
195};194};
196 195
@@ -458,30 +457,51 @@ static __always_inline int TestClearPage##uname(struct page *page) \ · 261 unmodified lines
458 TESTSETFLAG(uname, lname, policy) \457 TESTSETFLAG(uname, lname, policy) \
459 TESTCLEARFLAG(uname, lname, policy)458 TESTCLEARFLAG(uname, lname, policy)
460 459
460#define FOLIO_TEST_FLAG_FALSE(name) \
461static inline bool folio_test_##name(const struct folio *folio) \
462{ return false; }
463#define FOLIO_SET_FLAG_NOOP(name) \
464static inline void folio_set_##name(struct folio *folio) { }
465#define FOLIO_CLEAR_FLAG_NOOP(name) \
466static inline void folio_clear_##name(struct folio *folio) { }
467#define __FOLIO_SET_FLAG_NOOP(name) \
468static inline void __folio_set_##name(struct folio *folio) { }
469#define __FOLIO_CLEAR_FLAG_NOOP(name) \
470static inline void __folio_clear_##name(struct folio *folio) { }
471#define FOLIO_TEST_SET_FLAG_FALSE(name) \
472static inline bool folio_test_set_##name(struct folio *folio) \
473{ return false; }
474#define FOLIO_TEST_CLEAR_FLAG_FALSE(name) \
475static inline bool folio_test_clear_##name(struct folio *folio) \
476{ return false; }
477
478#define FOLIO_FLAG_FALSE(name) \
479FOLIO_TEST_FLAG_FALSE(name) \
480FOLIO_SET_FLAG_NOOP(name) \
481FOLIO_CLEAR_FLAG_NOOP(name)
482
461#define TESTPAGEFLAG_FALSE(uname, lname) \483#define TESTPAGEFLAG_FALSE(uname, lname) \
462static inline bool folio_test_##lname(const struct folio *folio) { return false; } \484FOLIO_TEST_FLAG_FALSE(lname) \
463static inline int Page##uname(const struct page *page) { return 0; }485static inline int Page##uname(const struct page *page) { return 0; }
464 486
465#define SETPAGEFLAG_NOOP(uname, lname) \487#define SETPAGEFLAG_NOOP(uname, lname) \
466static inline void folio_set_##lname(struct folio *folio) { } \488FOLIO_SET_FLAG_NOOP(lname) \
467static inline void SetPage##uname(struct page *page) { }489static inline void SetPage##uname(struct page *page) { }
468 490
469#define CLEARPAGEFLAG_NOOP(uname, lname) \491#define CLEARPAGEFLAG_NOOP(uname, lname) \
470static inline void folio_clear_##lname(struct folio *folio) { } \492FOLIO_CLEAR_FLAG_NOOP(lname) \
471static inline void ClearPage##uname(struct page *page) { }493static inline void ClearPage##uname(struct page *page) { }
472 494
473#define __CLEARPAGEFLAG_NOOP(uname, lname) \495#define __CLEARPAGEFLAG_NOOP(uname, lname) \
474static inline void __folio_clear_##lname(struct folio *folio) { } \496__FOLIO_CLEAR_FLAG_NOOP(lname) \
475static inline void __ClearPage##uname(struct page *page) { }497static inline void __ClearPage##uname(struct page *page) { }
476 498
477#define TESTSETFLAG_FALSE(uname, lname) \499#define TESTSETFLAG_FALSE(uname, lname) \
478static inline bool folio_test_set_##lname(struct folio *folio) \500FOLIO_TEST_SET_FLAG_FALSE(lname) \
479{ return 0; } \
480static inline int TestSetPage##uname(struct page *page) { return 0; }501static inline int TestSetPage##uname(struct page *page) { return 0; }
481 502
482#define TESTCLEARFLAG_FALSE(uname, lname) \503#define TESTCLEARFLAG_FALSE(uname, lname) \
483static inline bool folio_test_clear_##lname(struct folio *folio) \504FOLIO_TEST_CLEAR_FLAG_FALSE(lname) \
484{ return 0; } \
485static inline int TestClearPage##uname(struct page *page) { return 0; }505static inline int TestClearPage##uname(struct page *page) { return 0; }
486 506
487#define PAGEFLAG_FALSE(uname, lname) TESTPAGEFLAG_FALSE(uname, lname) \507#define PAGEFLAG_FALSE(uname, lname) TESTPAGEFLAG_FALSE(uname, lname) \
@@ -855,29 +875,6 @@ TESTPAGEFLAG_FALSE(LargeRmappable, large_rmappable) · 367 unmodified lines
855 875
856#define PG_head_mask ((1UL << PG_head))876#define PG_head_mask ((1UL << PG_head))
857 877
858#ifdef CONFIG_HUGETLB_PAGE
859int PageHuge(const struct page *page);
860SETPAGEFLAG(HugeTLB, hugetlb, PF_SECOND)
861CLEARPAGEFLAG(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 */
872static 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
878TESTPAGEFLAG_FALSE(Huge, hugetlb)
879#endif
880
881#ifdef CONFIG_TRANSPARENT_HUGEPAGE878#ifdef CONFIG_TRANSPARENT_HUGEPAGE
882/*879/*
883 * PageHuge() only returns true for hugetlbfs pages, but not for880 * PageHuge() only returns true for hugetlbfs pages, but not for
@@ -933,34 +930,23 @@ PAGEFLAG_FALSE(HasHWPoisoned, has_hwpoisoned) · 49 unmodified lines
933 TESTSCFLAG_FALSE(HasHWPoisoned, has_hwpoisoned)930 TESTSCFLAG_FALSE(HasHWPoisoned, has_hwpoisoned)
934#endif931#endif
935 932
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 */
941static 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
948/*933/*
949 * For pages that are never mapped to userspace (and aren't PageSlab),934 * For pages that are never mapped to userspace (and aren't PageSlab),
950 * page_type may be used. Because it is initialised to -1, we invert the935 * page_type may be used. Because it is initialised to -1, we invert the
951 * sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and936 * sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and
952 * __ClearPageFoo *sets* the bit used for PageFoo. We reserve a few high and937 * __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 be938 * low bits so that an underflow or overflow of _mapcount won't be
954 * mistaken for a page type value.939 * mistaken for a page type value.
955 */940 */
956 941
957#define PAGE_TYPE_BASE 0xf0000000942#define PAGE_TYPE_BASE 0xf0000000
958/* Reserve 0x0000007f to catch underflows of page_mapcount */943/* Reserve 0x0000007f to catch underflows of _mapcount */
959#define PAGE_MAPCOUNT_RESERVE -128944#define PAGE_MAPCOUNT_RESERVE -128
960#define PG_buddy 0x00000080945#define PG_buddy 0x00000080
961#define PG_offline 0x00000100946#define PG_offline 0x00000100
962#define PG_table 0x00000200947#define PG_table 0x00000200
963#define PG_guard 0x00000400948#define PG_guard 0x00000400
949#define PG_hugetlb 0x00000800
964 950
965#define PageType(page, flag) \951#define PageType(page, flag) \
966 ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)952 ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
@@ -977,35 +963,38 @@ static inline int page_has_type(const struct page *page) · 10 unmodified lines
977 return page_type_has_type(page->page_type);963 return page_type_has_type(page->page_type);
978}964}
979 965
966#define FOLIO_TYPE_OPS(lname, fname) \
967static __always_inline bool folio_test_##fname(const struct folio *folio)\
968{ \
969 return folio_test_type(folio, PG_##lname); \
970} \
971static __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} \
976static __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
980#define PAGE_TYPE_OPS(uname, lname, fname) \982#define PAGE_TYPE_OPS(uname, lname, fname) \
983FOLIO_TYPE_OPS(lname, fname) \
981static __always_inline int Page##uname(const struct page *page) \984static __always_inline int Page##uname(const struct page *page) \
982{ \985{ \
983 return PageType(page, PG_##lname); \986 return PageType(page, PG_##lname); \
984} \987} \
985static __always_inline int folio_test_##fname(const struct folio *folio)\
986{ \
987 return folio_test_type(folio, PG_##lname); \
988} \
989static __always_inline void __SetPage##uname(struct page *page) \988static __always_inline void __SetPage##uname(struct page *page) \
990{ \989{ \
991 VM_BUG_ON_PAGE(!PageType(page, 0), page); \990 VM_BUG_ON_PAGE(!PageType(page, 0), page); \
992 page->page_type &= ~PG_##lname; \991 page->page_type &= ~PG_##lname; \
993} \992} \
994static __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} \
999static __always_inline void __ClearPage##uname(struct page *page) \993static __always_inline void __ClearPage##uname(struct page *page) \
1000{ \994{ \
1001 VM_BUG_ON_PAGE(!Page##uname(page), page); \995 VM_BUG_ON_PAGE(!Page##uname(page), page); \
1002 page->page_type |= PG_##lname; \996 page->page_type |= PG_##lname; \
1003} \997}
1004static __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} \
1009 998
1010/*999/*
1011 * PageBuddy() indicates that the page is free and in the buddy system1000 * PageBuddy() indicates that the page is free and in the buddy system
@@ -1052,6 +1041,37 @@ PAGE_TYPE_OPS(Table, table, pgtable) · 40 unmodified lines
1052 */1041 */
1053PAGE_TYPE_OPS(Guard, guard, guard)1042PAGE_TYPE_OPS(Guard, guard, guard)
1054 1043
1044#ifdef CONFIG_HUGETLB_PAGE
1045FOLIO_TYPE_OPS(hugetlb, hugetlb)
1046#else
1047FOLIO_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 */
1058static 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 */
1068static 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
1055extern bool is_free_buddy_page(struct page *page);1075extern bool is_free_buddy_page(struct page *page);
1056 1076
1057PAGEFLAG(Isolated, isolated, PF_ANY);1077PAGEFLAG(Isolated, isolated, PF_ANY);
@@ -1118,7 +1138,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page) · 60 unmodified lines
1118 */1138 */
1119#define PAGE_FLAGS_SECOND \1139#define PAGE_FLAGS_SECOND \
1120 (0xffUL /* order */ | 1UL << PG_has_hwpoisoned | \1140 (0xffUL /* order */ | 1UL << PG_has_hwpoisoned | \
1121 1UL << PG_hugetlb | 1UL << PG_large_rmappable)1141 1UL << PG_large_rmappable)
1122 1142
1123#define PAGE_FLAGS_PRIVATE \1143#define PAGE_FLAGS_PRIVATE \
1124 (1UL << PG_private | 1UL << PG_private_2)1144 (1UL << PG_private | 1UL << PG_private_2)
include/trace/events/mmflags.h+1−0
@@ -135,6 +135,7 @@ IF_HAVE_PG_ARCH_X(arch_3) · 134 unmodified lines
135#define DEF_PAGETYPE_NAME(_name) { PG_##_name, __stringify(_name) }135#define DEF_PAGETYPE_NAME(_name) { PG_##_name, __stringify(_name) }
136 136
137#define __def_pagetype_names \137#define __def_pagetype_names \
138 DEF_PAGETYPE_NAME(hugetlb), \
138 DEF_PAGETYPE_NAME(offline), \139 DEF_PAGETYPE_NAME(offline), \
139 DEF_PAGETYPE_NAME(guard), \140 DEF_PAGETYPE_NAME(guard), \
140 DEF_PAGETYPE_NAME(table), \141 DEF_PAGETYPE_NAME(table), \
kernel/vmcore_info.c+2−3
@@ -205,11 +205,10 @@ static int __init crash_save_vmcoreinfo_init(void) · 204 unmodified lines
205 VMCOREINFO_NUMBER(PG_head_mask);205 VMCOREINFO_NUMBER(PG_head_mask);
206#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)206#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
207 VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);207 VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
208#ifdef CONFIG_HUGETLB_PAGE208#define PAGE_HUGETLB_MAPCOUNT_VALUE (~PG_hugetlb)
209 VMCOREINFO_NUMBER(PG_hugetlb);209 VMCOREINFO_NUMBER(PAGE_HUGETLB_MAPCOUNT_VALUE);
210#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)210#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
211 VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);211 VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
212#endif
213 212
214#ifdef CONFIG_KALLSYMS213#ifdef CONFIG_KALLSYMS
215 VMCOREINFO_SYMBOL(kallsyms_names);214 VMCOREINFO_SYMBOL(kallsyms_names);
lib/stackdepot.c+2−2
@@ -627,10 +627,10 @@ depot_stack_handle_t stack_depot_save_flags(unsigned long *entries, · 626 unmodified lines
627 /*627 /*
628 * Zero out zone modifiers, as we don't have specific zone628 * Zero out zone modifiers, as we don't have specific zone
629 * requirements. Keep the flags related to allocation in atomic629 * requirements. Keep the flags related to allocation in atomic
630 * contexts and I/O.630 * contexts, I/O, nolockdep.
631 */631 */
632 alloc_flags &= ~GFP_ZONEMASK;632 alloc_flags &= ~GFP_ZONEMASK;
633 alloc_flags &= (GFP_ATOMIC | GFP_KERNEL);633 alloc_flags &= (GFP_ATOMIC | GFP_KERNEL | __GFP_NOLOCKDEP);
634 alloc_flags |= __GFP_NOWARN;634 alloc_flags |= __GFP_NOWARN;
635 page = alloc_pages(alloc_flags, DEPOT_POOL_ORDER);635 page = alloc_pages(alloc_flags, DEPOT_POOL_ORDER);
636 if (page)636 if (page)
mm/hugetlb.c+15−25
@@ -1624,7 +1624,7 @@ static inline void __clear_hugetlb_destructor(struct hstate *h, · 1623 unmodified lines
1624{1624{
1625 lockdep_assert_held(&hugetlb_lock);1625 lockdep_assert_held(&hugetlb_lock);
1626 1626
1627 folio_clear_hugetlb(folio);1627 __folio_clear_hugetlb(folio);
1628}1628}
1629 1629
1630/*1630/*
@@ -1711,7 +1711,7 @@ static void add_hugetlb_folio(struct hstate *h, struct folio *folio, · 80 unmodified lines
1711 h->surplus_huge_pages_node[nid]++;1711 h->surplus_huge_pages_node[nid]++;
1712 }1712 }
1713 1713
1714 folio_set_hugetlb(folio);1714 __folio_set_hugetlb(folio);
1715 folio_change_private(folio, NULL);1715 folio_change_private(folio, NULL);
1716 /*1716 /*
1717 * We have to set hugetlb_vmemmap_optimized again as above1717 * We have to set hugetlb_vmemmap_optimized again as above
@@ -1781,7 +1781,7 @@ static void __update_and_free_hugetlb_folio(struct hstate *h, · 63 unmodified lines
1781 * If vmemmap pages were allocated above, then we need to clear the1781 * If vmemmap pages were allocated above, then we need to clear the
1782 * hugetlb destructor under the hugetlb lock.1782 * hugetlb destructor under the hugetlb lock.
1783 */1783 */
1784 if (clear_dtor) {1784 if (folio_test_hugetlb(folio)) {
1785 spin_lock_irq(&hugetlb_lock);1785 spin_lock_irq(&hugetlb_lock);
1786 __clear_hugetlb_destructor(h, folio);1786 __clear_hugetlb_destructor(h, folio);
1787 spin_unlock_irq(&hugetlb_lock);1787 spin_unlock_irq(&hugetlb_lock);
@@ -2049,7 +2049,7 @@ static void __prep_account_new_huge_page(struct hstate *h, int nid) · 261 unmodified lines
2049 2049
2050static void init_new_hugetlb_folio(struct hstate *h, struct folio *folio)2050static void init_new_hugetlb_folio(struct hstate *h, struct folio *folio)
2051{2051{
2052 folio_set_hugetlb(folio);2052 __folio_set_hugetlb(folio);
2053 INIT_LIST_HEAD(&folio->lru);2053 INIT_LIST_HEAD(&folio->lru);
2054 hugetlb_set_folio_subpool(folio, NULL);2054 hugetlb_set_folio_subpool(folio, NULL);
2055 set_hugetlb_cgroup(folio, NULL);2055 set_hugetlb_cgroup(folio, NULL);
@@ -2159,22 +2159,6 @@ static bool prep_compound_gigantic_folio_for_demote(struct folio *folio, · 103 unmodified lines
2159 return __prep_compound_gigantic_folio(folio, order, true);2159 return __prep_compound_gigantic_folio(folio, order, true);
2160}2160}
2161 2161
2162/*
2163 * PageHuge() only returns true for hugetlbfs pages, but not for normal or
2164 * transparent huge pages. See the PageTransHuge() documentation for more
2165 * details.
2166 */
2167int PageHuge(const struct page *page)
2168{
2169 const struct folio *folio;
2170
2171 if (!PageCompound(page))
2172 return 0;
2173 folio = page_folio(page);
2174 return folio_test_hugetlb(folio);
2175}
2176EXPORT_SYMBOL_GPL(PageHuge);
2177
2178/*2162/*
2179 * Find and lock address space (mapping) in write mode.2163 * Find and lock address space (mapping) in write mode.
2180 *2164 *
@@ -3268,9 +3252,12 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma, · 1087 unmodified lines
3268 3252
3269 rsv_adjust = hugepage_subpool_put_pages(spool, 1);3253 rsv_adjust = hugepage_subpool_put_pages(spool, 1);
3270 hugetlb_acct_memory(h, -rsv_adjust);3254 hugetlb_acct_memory(h, -rsv_adjust);
3271 if (deferred_reserve)3255 if (deferred_reserve) {
3256 spin_lock_irq(&hugetlb_lock);
3272 hugetlb_cgroup_uncharge_folio_rsvd(hstate_index(h),3257 hugetlb_cgroup_uncharge_folio_rsvd(hstate_index(h),
3273 pages_per_huge_page(h), folio);3258 pages_per_huge_page(h), folio);
3259 spin_unlock_irq(&hugetlb_lock);
3260 }
3274 }3261 }
3275 3262
3276 if (!memcg_charge_ret)3263 if (!memcg_charge_ret)
@@ -6274,6 +6261,12 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm, · 2997 unmodified lines
6274 VM_UFFD_MISSING);6261 VM_UFFD_MISSING);
6275 }6262 }
6276 6263
6264 if (!(vma->vm_flags & VM_MAYSHARE)) {
6265 ret = vmf_anon_prepare(vmf);
6266 if (unlikely(ret))
6267 goto out;
6268 }
6269
6277 folio = alloc_hugetlb_folio(vma, haddr, 0);6270 folio = alloc_hugetlb_folio(vma, haddr, 0);
6278 if (IS_ERR(folio)) {6271 if (IS_ERR(folio)) {
6279 /*6272 /*
@@ -6310,15 +6303,12 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm, · 30 unmodified lines
6310 */6303 */
6311 restore_reserve_on_error(h, vma, haddr, folio);6304 restore_reserve_on_error(h, vma, haddr, folio);
6312 folio_put(folio);6305 folio_put(folio);
6306 ret = VM_FAULT_SIGBUS;
6313 goto out;6307 goto out;
6314 }6308 }
6315 new_pagecache_folio = true;6309 new_pagecache_folio = true;
6316 } else {6310 } else {
6317 folio_lock(folio);6311 folio_lock(folio);
6318
6319 ret = vmf_anon_prepare(vmf);
6320 if (unlikely(ret))
6321 goto backout_unlocked;
6322 anon_rmap = 1;6312 anon_rmap = 1;
6323 }6313 }
6324 } else {6314 } else {
mm/zswap.c+16−9
@@ -1331,15 +1331,22 @@ static unsigned long zswap_shrinker_count(struct shrinker *shrinker, · 1330 unmodified lines
1331 if (!gfp_has_io_fs(sc->gfp_mask))1331 if (!gfp_has_io_fs(sc->gfp_mask))
1332 return 0;1332 return 0;
1333 1333
1334#ifdef CONFIG_MEMCG_KMEM1334 /*
1335 mem_cgroup_flush_stats(memcg);1335 * For memcg, use the cgroup-wide ZSWAP stats since we don't
1336 nr_backing = memcg_page_state(memcg, MEMCG_ZSWAP_B) >> PAGE_SHIFT;1336 * have them per-node and thus per-lruvec. Careful if memcg is
1337 nr_stored = memcg_page_state(memcg, MEMCG_ZSWAPPED);1337 * runtime-disabled: we can get sc->memcg == NULL, which is ok
1338#else1338 * for the lruvec, but not for memcg_page_state().
1339 /* use pool stats instead of memcg stats */1339 *
1340 nr_backing = zswap_pool_total_size >> PAGE_SHIFT;1340 * Without memcg, use the zswap pool-wide metrics.
1341 nr_stored = atomic_read(&zswap_nr_stored);1341 */
1342#endif1342 if (!mem_cgroup_disabled()) {
1343 mem_cgroup_flush_stats(memcg);
1344 nr_backing = memcg_page_state(memcg, MEMCG_ZSWAP_B) >> PAGE_SHIFT;
1345 nr_stored = memcg_page_state(memcg, MEMCG_ZSWAPPED);
1346 } else {
1347 nr_backing = zswap_pool_total_size >> PAGE_SHIFT;
1348 nr_stored = atomic_read(&zswap_nr_stored);
1349 }
1343 1350
1344 if (!nr_stored)1351 if (!nr_stored)
1345 return 0;1352 return 0;
tools/testing/selftests/kselftest_harness.h+8−4
@@ -56,7 +56,6 @@ · 55 unmodified lines
56#include <asm/types.h>56#include <asm/types.h>
57#include <ctype.h>57#include <ctype.h>
58#include <errno.h>58#include <errno.h>
59#include <limits.h>
60#include <stdbool.h>59#include <stdbool.h>
61#include <stdint.h>60#include <stdint.h>
62#include <stdio.h>61#include <stdio.h>
@@ -1159,7 +1158,7 @@ void __run_test(struct __fixture_metadata *f, · 1096 unmodified lines
1159 struct __test_metadata *t)1158 struct __test_metadata *t)
1160{1159{
1161 struct __test_xfail *xfail;1160 struct __test_xfail *xfail;
1162 char test_name[LINE_MAX];1161 char *test_name;
1163 const char *diagnostic;1162 const char *diagnostic;
1164 1163
1165 /* reset test struct */1164 /* reset test struct */
@@ -1167,8 +1166,12 @@ void __run_test(struct __fixture_metadata *f, · 1 unmodified line
1167 t->trigger = 0;1166 t->trigger = 0;
1168 memset(t->results->reason, 0, sizeof(t->results->reason));1167 memset(t->results->reason, 0, sizeof(t->results->reason));
1169 1168
1170 snprintf(test_name, sizeof(test_name), "%s%s%s.%s",1169 if (asprintf(&test_name, "%s%s%s.%s", f->name,
1171 f->name, variant->name[0] ? "." : "", variant->name, t->name);1170 variant->name[0] ? "." : "", variant->name, t->name) == -1) {
1171 ksft_print_msg("ERROR ALLOCATING MEMORY\n");
1172 t->exit_code = KSFT_FAIL;
1173 _exit(t->exit_code);
1174 }
1172 1175
1173 ksft_print_msg(" RUN %s ...\n", test_name);1176 ksft_print_msg(" RUN %s ...\n", test_name);
1174 1177
@@ -1206,6 +1209,7 @@ void __run_test(struct __fixture_metadata *f, · 31 unmodified lines
1206 1209
1207 ksft_test_result_code(t->exit_code, test_name,1210 ksft_test_result_code(t->exit_code, test_name,
1208 diagnostic ? "%s" : NULL, diagnostic);1211 diagnostic ? "%s" : NULL, diagnostic);
1212 free(test_name);
1209}1213}
1210 1214
1211static int test_harness_run(int argc, char **argv)1215static int test_harness_run(int argc, char **argv)
tools/testing/selftests/mm/mdwe_test.c+1−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
7#include <linux/mman.h>7#include <linux/mman.h>
8#include <linux/prctl.h>8#include <linux/prctl.h>
9 9
10#define _GNU_SOURCE
10#include <stdio.h>11#include <stdio.h>
11#include <stdlib.h>12#include <stdlib.h>
12#include <sys/auxv.h>13#include <sys/auxv.h>
tools/testing/selftests/mm/protection_keys.c+0−38
@@ -54,7 +54,6 @@ int test_nr; · 53 unmodified lines
54u64 shadow_pkey_reg;54u64 shadow_pkey_reg;
55int dprint_in_signal;55int dprint_in_signal;
56char dprint_in_signal_buffer[DPRINT_IN_SIGNAL_BUF_SIZE];56char dprint_in_signal_buffer[DPRINT_IN_SIGNAL_BUF_SIZE];
57char buf[256];
58 57
59void cat_into_file(char *str, char *file)58void cat_into_file(char *str, char *file)
60{59{
@@ -1745,42 +1744,6 @@ void pkey_setup_shadow(void) · 1684 unmodified lines
1745 shadow_pkey_reg = __read_pkey_reg();1744 shadow_pkey_reg = __read_pkey_reg();
1746}1745}
1747 1746
1748pid_t parent_pid;
1749
1750void restore_settings_atexit(void)
1751{
1752 if (parent_pid == getpid())
1753 cat_into_file(buf, "/proc/sys/vm/nr_hugepages");
1754}
1755
1756void save_settings(void)
1757{
1758 int fd;
1759 int err;
1760
1761 if (geteuid())
1762 return;
1763
1764 fd = open("/proc/sys/vm/nr_hugepages", O_RDONLY);
1765 if (fd < 0) {
1766 fprintf(stderr, "error opening\n");
1767 perror("error: ");
1768 exit(__LINE__);
1769 }
1770
1771 /* -1 to guarantee leaving the trailing \0 */
1772 err = read(fd, buf, sizeof(buf)-1);
1773 if (err < 0) {
1774 fprintf(stderr, "error reading\n");
1775 perror("error: ");
1776 exit(__LINE__);
1777 }
1778
1779 parent_pid = getpid();
1780 atexit(restore_settings_atexit);
1781 close(fd);
1782}
1783
1784int main(void)1747int main(void)
1785{1748{
1786 int nr_iterations = 22;1749 int nr_iterations = 22;
@@ -1788,7 +1751,6 @@ int main(void) · 1 unmodified line
1788 1751
1789 srand((unsigned int)time(NULL));1752 srand((unsigned int)time(NULL));
1790 1753
1791 save_settings();
1792 setup_handlers();1754 setup_handlers();
1793 1755
1794 printf("has pkeys: %d\n", pkeys_supported);1756 printf("has pkeys: %d\n", pkeys_supported);
tools/testing/selftests/mm/run_vmtests.sh+2−0
@@ -385,6 +385,7 @@ CATEGORY="ksm_numa" run_test ./ksm_tests -N -m 0 · 384 unmodified lines
385CATEGORY="ksm" run_test ./ksm_functional_tests385CATEGORY="ksm" run_test ./ksm_functional_tests
386 386
387# protection_keys tests387# protection_keys tests
388nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
388if [ -x ./protection_keys_32 ]389if [ -x ./protection_keys_32 ]
389then390then
390 CATEGORY="pkey" run_test ./protection_keys_32391 CATEGORY="pkey" run_test ./protection_keys_32
@@ -394,6 +395,7 @@ if [ -x ./protection_keys_64 ] · 3 unmodified lines
394then395then
395 CATEGORY="pkey" run_test ./protection_keys_64396 CATEGORY="pkey" run_test ./protection_keys_64
396fi397fi
398echo "$nr_hugepgs" > /proc/sys/vm/nr_hugepages
397 399
398if [ -x ./soft-dirty ]400if [ -x ./soft-dirty ]
399then401then
tools/testing/selftests/mm/split_huge_page_test.c+1−1
@@ -300,7 +300,7 @@ int create_pagecache_thp_and_fd(const char *testfile, size_t fd_size, int *fd, · 299 unmodified lines
300 char **addr)300 char **addr)
301{301{
302 size_t i;302 size_t i;
303 int dummy;303 int __attribute__((unused)) dummy = 0;
304 304
305 srand(time(NULL));305 srand(time(NULL));
306 306