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

Showing the changes to include/linux (2 of 13 files). Show all

Unified · Split

2 files
  1. include/linux/mm.h +5 −3
  2. include/linux/page-flags.h +82 −62
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)