1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_MM_PAGE_IDLE_H
3 #define _LINUX_MM_PAGE_IDLE_H
4 
5 #include <linux/bitops.h>
6 #include <linux/page-flags.h>
7 #include <linux/page_ext.h>
8 
9 #ifdef CONFIG_PAGE_IDLE_FLAG
10 
11 #ifndef CONFIG_64BIT
12 /*
13  * If there is not enough space to store Idle and Young bits in page flags, use
14  * page ext flags instead.
15  */
folio_test_young(struct folio * folio)16 static inline bool folio_test_young(struct folio *folio)
17 {
18 	struct page_ext *page_ext = page_ext_get(&folio->page);
19 	bool page_young;
20 
21 	if (unlikely(!page_ext))
22 		return false;
23 
24 	page_young = test_bit(PAGE_EXT_YOUNG, &page_ext->flags);
25 	page_ext_put(page_ext);
26 
27 	return page_young;
28 }
29 
folio_set_young(struct folio * folio)30 static inline void folio_set_young(struct folio *folio)
31 {
32 	struct page_ext *page_ext = page_ext_get(&folio->page);
33 
34 	if (unlikely(!page_ext))
35 		return;
36 
37 	set_bit(PAGE_EXT_YOUNG, &page_ext->flags);
38 	page_ext_put(page_ext);
39 }
40 
folio_test_clear_young(struct folio * folio)41 static inline bool folio_test_clear_young(struct folio *folio)
42 {
43 	struct page_ext *page_ext = page_ext_get(&folio->page);
44 	bool page_young;
45 
46 	if (unlikely(!page_ext))
47 		return false;
48 
49 	page_young = test_and_clear_bit(PAGE_EXT_YOUNG, &page_ext->flags);
50 	page_ext_put(page_ext);
51 
52 	return page_young;
53 }
54 
folio_test_idle(struct folio * folio)55 static inline bool folio_test_idle(struct folio *folio)
56 {
57 	struct page_ext *page_ext = page_ext_get(&folio->page);
58 	bool page_idle;
59 
60 	if (unlikely(!page_ext))
61 		return false;
62 
63 	page_idle =  test_bit(PAGE_EXT_IDLE, &page_ext->flags);
64 	page_ext_put(page_ext);
65 
66 	return page_idle;
67 }
68 
folio_set_idle(struct folio * folio)69 static inline void folio_set_idle(struct folio *folio)
70 {
71 	struct page_ext *page_ext = page_ext_get(&folio->page);
72 
73 	if (unlikely(!page_ext))
74 		return;
75 
76 	set_bit(PAGE_EXT_IDLE, &page_ext->flags);
77 	page_ext_put(page_ext);
78 }
79 
folio_clear_idle(struct folio * folio)80 static inline void folio_clear_idle(struct folio *folio)
81 {
82 	struct page_ext *page_ext = page_ext_get(&folio->page);
83 
84 	if (unlikely(!page_ext))
85 		return;
86 
87 	clear_bit(PAGE_EXT_IDLE, &page_ext->flags);
88 	page_ext_put(page_ext);
89 }
90 #endif /* !CONFIG_64BIT */
91 
92 #else /* !CONFIG_PAGE_IDLE_FLAG */
93 
folio_test_young(struct folio * folio)94 static inline bool folio_test_young(struct folio *folio)
95 {
96 	return false;
97 }
98 
folio_set_young(struct folio * folio)99 static inline void folio_set_young(struct folio *folio)
100 {
101 }
102 
folio_test_clear_young(struct folio * folio)103 static inline bool folio_test_clear_young(struct folio *folio)
104 {
105 	return false;
106 }
107 
folio_test_idle(struct folio * folio)108 static inline bool folio_test_idle(struct folio *folio)
109 {
110 	return false;
111 }
112 
folio_set_idle(struct folio * folio)113 static inline void folio_set_idle(struct folio *folio)
114 {
115 }
116 
folio_clear_idle(struct folio * folio)117 static inline void folio_clear_idle(struct folio *folio)
118 {
119 }
120 
121 #endif /* CONFIG_PAGE_IDLE_FLAG */
122 
page_is_young(struct page * page)123 static inline bool page_is_young(struct page *page)
124 {
125 	return folio_test_young(page_folio(page));
126 }
127 
set_page_young(struct page * page)128 static inline void set_page_young(struct page *page)
129 {
130 	folio_set_young(page_folio(page));
131 }
132 
test_and_clear_page_young(struct page * page)133 static inline bool test_and_clear_page_young(struct page *page)
134 {
135 	return folio_test_clear_young(page_folio(page));
136 }
137 
page_is_idle(struct page * page)138 static inline bool page_is_idle(struct page *page)
139 {
140 	return folio_test_idle(page_folio(page));
141 }
142 
set_page_idle(struct page * page)143 static inline void set_page_idle(struct page *page)
144 {
145 	folio_set_idle(page_folio(page));
146 }
147 #endif /* _LINUX_MM_PAGE_IDLE_H */
148