@@ -190,7 +190,6 @@ enum pageflags {
190
190
191
191
/* At least one page in this folio has the hwpoison flag set */
192
192
PG_has_hwpoisoned = PG_error ,
193
- PG_hugetlb = PG_active ,
194
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) \
458
457
TESTSETFLAG(uname, lname, policy) \
459
458
TESTCLEARFLAG(uname, lname, policy)
460
459
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
+
461
483
#define TESTPAGEFLAG_FALSE (uname , lname ) \
462
- static inline bool folio_test_##lname(const struct folio *folio) { return false; } \
484
+ FOLIO_TEST_FLAG_FALSE(lname) \
463
485
static inline int Page##uname(const struct page *page) { return 0; }
464
486
465
487
#define SETPAGEFLAG_NOOP (uname , lname ) \
466
- static inline void folio_set_##lname(struct folio *folio) { } \
488
+ FOLIO_SET_FLAG_NOOP(lname) \
467
489
static inline void SetPage##uname(struct page *page) { }
468
490
469
491
#define CLEARPAGEFLAG_NOOP (uname , lname ) \
470
- static inline void folio_clear_##lname(struct folio *folio) { } \
492
+ FOLIO_CLEAR_FLAG_NOOP(lname) \
471
493
static inline void ClearPage##uname(struct page *page) { }
472
494
473
495
#define __CLEARPAGEFLAG_NOOP (uname , lname ) \
474
- static inline void __folio_clear_##lname(struct folio *folio) { } \
496
+ __FOLIO_CLEAR_FLAG_NOOP(lname) \
475
497
static inline void __ClearPage##uname(struct page *page) { }
476
498
477
499
#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) \
480
501
static inline int TestSetPage##uname(struct page *page) { return 0; }
481
502
482
503
#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) \
485
505
static inline int TestClearPage##uname(struct page *page) { return 0; }
486
506
487
507
#define PAGEFLAG_FALSE (uname , lname ) TESTPAGEFLAG_FALSE(uname, lname) \
@@ -855,29 +875,6 @@ TESTPAGEFLAG_FALSE(LargeRmappable, large_rmappable)
855
875
856
876
#define PG_head_mask ((1UL << PG_head))
857
877
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
-
881
878
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
882
879
/*
883
880
* PageHuge() only returns true for hugetlbfs pages, but not for
@@ -933,34 +930,23 @@ PAGEFLAG_FALSE(HasHWPoisoned, has_hwpoisoned)
933
930
TESTSCFLAG_FALSE (HasHWPoisoned , has_hwpoisoned )
934
931
#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
- */
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
-
948
933
/*
949
934
* For pages that are never mapped to userspace (and aren't PageSlab),
950
935
* page_type may be used. Because it is initialised to -1, we invert the
951
936
* sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and
952
937
* __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
954
939
* mistaken for a page type value.
955
940
*/
956
941
957
942
#define PAGE_TYPE_BASE 0xf0000000
958
- /* Reserve 0x0000007f to catch underflows of page_mapcount */
943
+ /* Reserve 0x0000007f to catch underflows of _mapcount */
959
944
#define PAGE_MAPCOUNT_RESERVE -128
960
945
#define PG_buddy 0x00000080
961
946
#define PG_offline 0x00000100
962
947
#define PG_table 0x00000200
963
948
#define PG_guard 0x00000400
949
+ #define PG_hugetlb 0x00000800
964
950
965
951
#define PageType (page , flag ) \
966
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)
977
963
return page_type_has_type (page -> page_type );
978
964
}
979
965
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
+
980
982
#define PAGE_TYPE_OPS (uname , lname , fname ) \
983
+ FOLIO_TYPE_OPS(lname, fname) \
981
984
static __always_inline int Page##uname(const struct page *page) \
982
985
{ \
983
986
return PageType(page, PG_##lname); \
984
987
} \
985
- static __always_inline int folio_test_##fname(const struct folio *folio)\
986
- { \
987
- return folio_test_type(folio, PG_##lname); \
988
- } \
989
988
static __always_inline void __SetPage##uname(struct page *page) \
990
989
{ \
991
990
VM_BUG_ON_PAGE(!PageType(page, 0), page); \
992
991
page->page_type &= ~PG_##lname; \
993
992
} \
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
- } \
999
993
static __always_inline void __ClearPage##uname(struct page *page) \
1000
994
{ \
1001
995
VM_BUG_ON_PAGE(!Page##uname(page), page); \
1002
996
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
+ }
1009
998
1010
999
/*
1011
1000
* PageBuddy() indicates that the page is free and in the buddy system
@@ -1052,6 +1041,37 @@ PAGE_TYPE_OPS(Table, table, pgtable)
1052
1041
*/
1053
1042
PAGE_TYPE_OPS (Guard , guard , guard )
1054
1043
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
+
1055
1075
extern bool is_free_buddy_page (struct page * page );
1056
1076
1057
1077
PAGEFLAG (Isolated , isolated , PF_ANY );
@@ -1118,7 +1138,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
1118
1138
*/
1119
1139
#define PAGE_FLAGS_SECOND \
1120
1140
(0xffUL /* order */ | 1UL << PG_has_hwpoisoned | \
1121
- 1UL << PG_hugetlb | 1UL << PG_large_rmappable)
1141
+ 1UL << PG_large_rmappable)
1122
1142
1123
1143
#define PAGE_FLAGS_PRIVATE \
1124
1144
(1UL << PG_private | 1UL << PG_private_2)
0 commit comments