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
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+82−62
@@ -190,7 +190,6 @@ enum pageflags { · 189 unmodified lines
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) \ · 261 unmodified lines
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) · 367 unmodified lines
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) · 49 unmodified lines
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) · 10 unmodified lines
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) · 40 unmodified lines
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) · 60 unmodified lines
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)