1/* SPDX-License-Identifier: GPL-2.0 */
2#include <linux/node.h>
3#include <linux/mmzone.h>
4#include <linux/compaction.h>
5/*
6 * The order of these masks is important. Matching masks will be seen
7 * first and the left over flags will end up showing by themselves.
8 *
9 * For example, if we have GFP_KERNEL before GFP_USER we wil get:
10 *
11 * GFP_KERNEL|GFP_HARDWALL
12 *
13 * Thus most bits set go first.
14 */
15
16/* These define the values that are enums (the bits) */
17#define TRACE_GFP_FLAGS_GENERAL \
18 TRACE_GFP_EM(DMA) \
19 TRACE_GFP_EM(HIGHMEM) \
20 TRACE_GFP_EM(DMA32) \
21 TRACE_GFP_EM(MOVABLE) \
22 TRACE_GFP_EM(RECLAIMABLE) \
23 TRACE_GFP_EM(HIGH) \
24 TRACE_GFP_EM(IO) \
25 TRACE_GFP_EM(FS) \
26 TRACE_GFP_EM(ZERO) \
27 TRACE_GFP_EM(DIRECT_RECLAIM) \
28 TRACE_GFP_EM(KSWAPD_RECLAIM) \
29 TRACE_GFP_EM(WRITE) \
30 TRACE_GFP_EM(NOWARN) \
31 TRACE_GFP_EM(RETRY_MAYFAIL) \
32 TRACE_GFP_EM(NOFAIL) \
33 TRACE_GFP_EM(NORETRY) \
34 TRACE_GFP_EM(MEMALLOC) \
35 TRACE_GFP_EM(COMP) \
36 TRACE_GFP_EM(NOMEMALLOC) \
37 TRACE_GFP_EM(HARDWALL) \
38 TRACE_GFP_EM(THISNODE) \
39 TRACE_GFP_EM(ACCOUNT) \
40 TRACE_GFP_EM(ZEROTAGS)
41
42#ifdef CONFIG_KASAN_HW_TAGS
43# define TRACE_GFP_FLAGS_KASAN \
44 TRACE_GFP_EM(SKIP_ZERO) \
45 TRACE_GFP_EM(SKIP_KASAN)
46#else
47# define TRACE_GFP_FLAGS_KASAN
48#endif
49
50#ifdef CONFIG_LOCKDEP
51# define TRACE_GFP_FLAGS_LOCKDEP \
52 TRACE_GFP_EM(NOLOCKDEP)
53#else
54# define TRACE_GFP_FLAGS_LOCKDEP
55#endif
56
57#ifdef CONFIG_SLAB_OBJ_EXT
58# define TRACE_GFP_FLAGS_SLAB \
59 TRACE_GFP_EM(NO_OBJ_EXT)
60#else
61# define TRACE_GFP_FLAGS_SLAB
62#endif
63
64#define TRACE_GFP_FLAGS \
65 TRACE_GFP_FLAGS_GENERAL \
66 TRACE_GFP_FLAGS_KASAN \
67 TRACE_GFP_FLAGS_LOCKDEP \
68 TRACE_GFP_FLAGS_SLAB
69
70#undef TRACE_GFP_EM
71#define TRACE_GFP_EM(a) TRACE_DEFINE_ENUM(___GFP_##a##_BIT);
72
73TRACE_GFP_FLAGS
74
75/* Just in case these are ever used */
76TRACE_DEFINE_ENUM(___GFP_UNUSED_BIT);
77TRACE_DEFINE_ENUM(___GFP_LAST_BIT);
78
79#define gfpflag_string(flag) {(__force unsigned long)flag, #flag}
80
81/*
82 * For the values that match the bits, use the TRACE_GFP_FLAGS
83 * which will allow any updates to be included automatically.
84 */
85#undef TRACE_GFP_EM
86#define TRACE_GFP_EM(a) gfpflag_string(__GFP_##a),
87
88#define __def_gfpflag_names \
89 gfpflag_string(GFP_TRANSHUGE), \
90 gfpflag_string(GFP_TRANSHUGE_LIGHT), \
91 gfpflag_string(GFP_HIGHUSER_MOVABLE), \
92 gfpflag_string(GFP_HIGHUSER), \
93 gfpflag_string(GFP_USER), \
94 gfpflag_string(GFP_KERNEL_ACCOUNT), \
95 gfpflag_string(GFP_KERNEL), \
96 gfpflag_string(GFP_NOFS), \
97 gfpflag_string(GFP_ATOMIC), \
98 gfpflag_string(GFP_NOIO), \
99 gfpflag_string(GFP_NOWAIT), \
100 gfpflag_string(GFP_DMA), \
101 gfpflag_string(GFP_DMA32), \
102 gfpflag_string(__GFP_RECLAIM), \
103 TRACE_GFP_FLAGS \
104 { 0, NULL }
105
106#define show_gfp_flags(flags) \
107 (flags) ? __print_flags(flags, "|", __def_gfpflag_names \
108 ) : "none"
109
110#ifdef CONFIG_MMU
111#define IF_HAVE_PG_MLOCK(_name) ,{1UL << PG_##_name, __stringify(_name)}
112#else
113#define IF_HAVE_PG_MLOCK(_name)
114#endif
115
116#ifdef CONFIG_MEMORY_FAILURE
117#define IF_HAVE_PG_HWPOISON(_name) ,{1UL << PG_##_name, __stringify(_name)}
118#else
119#define IF_HAVE_PG_HWPOISON(_name)
120#endif
121
122#if defined(CONFIG_PAGE_IDLE_FLAG) && defined(CONFIG_64BIT)
123#define IF_HAVE_PG_IDLE(_name) ,{1UL << PG_##_name, __stringify(_name)}
124#else
125#define IF_HAVE_PG_IDLE(_name)
126#endif
127
128#ifdef CONFIG_ARCH_USES_PG_ARCH_2
129#define IF_HAVE_PG_ARCH_2(_name) ,{1UL << PG_##_name, __stringify(_name)}
130#else
131#define IF_HAVE_PG_ARCH_2(_name)
132#endif
133
134#ifdef CONFIG_ARCH_USES_PG_ARCH_3
135#define IF_HAVE_PG_ARCH_3(_name) ,{1UL << PG_##_name, __stringify(_name)}
136#else
137#define IF_HAVE_PG_ARCH_3(_name)
138#endif
139
140#define DEF_PAGEFLAG_NAME(_name) { 1UL << PG_##_name, __stringify(_name) }
141
142#define __def_pageflag_names \
143 DEF_PAGEFLAG_NAME(locked), \
144 DEF_PAGEFLAG_NAME(waiters), \
145 DEF_PAGEFLAG_NAME(referenced), \
146 DEF_PAGEFLAG_NAME(uptodate), \
147 DEF_PAGEFLAG_NAME(dirty), \
148 DEF_PAGEFLAG_NAME(lru), \
149 DEF_PAGEFLAG_NAME(active), \
150 DEF_PAGEFLAG_NAME(workingset), \
151 DEF_PAGEFLAG_NAME(owner_priv_1), \
152 DEF_PAGEFLAG_NAME(owner_2), \
153 DEF_PAGEFLAG_NAME(arch_1), \
154 DEF_PAGEFLAG_NAME(reserved), \
155 DEF_PAGEFLAG_NAME(private), \
156 DEF_PAGEFLAG_NAME(private_2), \
157 DEF_PAGEFLAG_NAME(writeback), \
158 DEF_PAGEFLAG_NAME(head), \
159 DEF_PAGEFLAG_NAME(reclaim), \
160 DEF_PAGEFLAG_NAME(swapbacked), \
161 DEF_PAGEFLAG_NAME(unevictable), \
162 DEF_PAGEFLAG_NAME(dropbehind) \
163IF_HAVE_PG_MLOCK(mlocked) \
164IF_HAVE_PG_HWPOISON(hwpoison) \
165IF_HAVE_PG_IDLE(idle) \
166IF_HAVE_PG_IDLE(young) \
167IF_HAVE_PG_ARCH_2(arch_2) \
168IF_HAVE_PG_ARCH_3(arch_3)
169
170#define show_page_flags(flags) \
171 (flags) ? __print_flags(flags, "|", \
172 __def_pageflag_names \
173 ) : "none"
174
175#if defined(CONFIG_PPC64)
176#define __VM_ARCH_SPECIFIC_1 {VM_SAO, "sao" }
177#elif defined(CONFIG_PARISC)
178#define __VM_ARCH_SPECIFIC_1 {VM_GROWSUP, "growsup" }
179#elif !defined(CONFIG_MMU)
180#define __VM_ARCH_SPECIFIC_1 {VM_MAPPED_COPY,"mappedcopy" }
181#else
182#define __VM_ARCH_SPECIFIC_1 {VM_ARCH_1, "arch_1" }
183#endif
184
185#ifdef CONFIG_MEM_SOFT_DIRTY
186#define IF_HAVE_VM_SOFTDIRTY(flag,name) {flag, name },
187#else
188#define IF_HAVE_VM_SOFTDIRTY(flag,name)
189#endif
190
191#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR
192# define IF_HAVE_UFFD_MINOR(flag, name) {flag, name},
193#else
194# define IF_HAVE_UFFD_MINOR(flag, name)
195#endif
196
197#if defined(CONFIG_64BIT) || defined(CONFIG_PPC32)
198# define IF_HAVE_VM_DROPPABLE(flag, name) {flag, name},
199#else
200# define IF_HAVE_VM_DROPPABLE(flag, name)
201#endif
202
203#define __def_vmaflag_names \
204 {VM_READ, "read" }, \
205 {VM_WRITE, "write" }, \
206 {VM_EXEC, "exec" }, \
207 {VM_SHARED, "shared" }, \
208 {VM_MAYREAD, "mayread" }, \
209 {VM_MAYWRITE, "maywrite" }, \
210 {VM_MAYEXEC, "mayexec" }, \
211 {VM_MAYSHARE, "mayshare" }, \
212 {VM_GROWSDOWN, "growsdown" }, \
213 {VM_UFFD_MISSING, "uffd_missing" }, \
214IF_HAVE_UFFD_MINOR(VM_UFFD_MINOR, "uffd_minor" ) \
215 {VM_PFNMAP, "pfnmap" }, \
216 {VM_UFFD_WP, "uffd_wp" }, \
217 {VM_LOCKED, "locked" }, \
218 {VM_IO, "io" }, \
219 {VM_SEQ_READ, "seqread" }, \
220 {VM_RAND_READ, "randread" }, \
221 {VM_DONTCOPY, "dontcopy" }, \
222 {VM_DONTEXPAND, "dontexpand" }, \
223 {VM_LOCKONFAULT, "lockonfault" }, \
224 {VM_ACCOUNT, "account" }, \
225 {VM_NORESERVE, "noreserve" }, \
226 {VM_HUGETLB, "hugetlb" }, \
227 {VM_SYNC, "sync" }, \
228 __VM_ARCH_SPECIFIC_1 , \
229 {VM_WIPEONFORK, "wipeonfork" }, \
230 {VM_DONTDUMP, "dontdump" }, \
231IF_HAVE_VM_SOFTDIRTY(VM_SOFTDIRTY, "softdirty" ) \
232 {VM_MIXEDMAP, "mixedmap" }, \
233 {VM_HUGEPAGE, "hugepage" }, \
234 {VM_NOHUGEPAGE, "nohugepage" }, \
235IF_HAVE_VM_DROPPABLE(VM_DROPPABLE, "droppable" ) \
236 {VM_MERGEABLE, "mergeable" } \
237
238#define show_vma_flags(flags) \
239 (flags) ? __print_flags(flags, "|", \
240 __def_vmaflag_names \
241 ) : "none"
242
243#ifdef CONFIG_COMPACTION
244#define COMPACTION_STATUS \
245 EM( COMPACT_SKIPPED, "skipped") \
246 EM( COMPACT_DEFERRED, "deferred") \
247 EM( COMPACT_CONTINUE, "continue") \
248 EM( COMPACT_SUCCESS, "success") \
249 EM( COMPACT_PARTIAL_SKIPPED, "partial_skipped") \
250 EM( COMPACT_COMPLETE, "complete") \
251 EM( COMPACT_NO_SUITABLE_PAGE, "no_suitable_page") \
252 EM( COMPACT_NOT_SUITABLE_ZONE, "not_suitable_zone") \
253 EMe(COMPACT_CONTENDED, "contended")
254
255/* High-level compaction status feedback */
256#define COMPACTION_FAILED 1
257#define COMPACTION_WITHDRAWN 2
258#define COMPACTION_PROGRESS 3
259
260#define compact_result_to_feedback(result) \
261({ \
262 enum compact_result __result = result; \
263 (__result == COMPACT_COMPLETE) ? COMPACTION_FAILED : \
264 (__result == COMPACT_SUCCESS) ? COMPACTION_PROGRESS : COMPACTION_WITHDRAWN; \
265})
266
267#define COMPACTION_FEEDBACK \
268 EM(COMPACTION_FAILED, "failed") \
269 EM(COMPACTION_WITHDRAWN, "withdrawn") \
270 EMe(COMPACTION_PROGRESS, "progress")
271
272#define COMPACTION_PRIORITY \
273 EM(COMPACT_PRIO_SYNC_FULL, "COMPACT_PRIO_SYNC_FULL") \
274 EM(COMPACT_PRIO_SYNC_LIGHT, "COMPACT_PRIO_SYNC_LIGHT") \
275 EMe(COMPACT_PRIO_ASYNC, "COMPACT_PRIO_ASYNC")
276#else
277#define COMPACTION_STATUS
278#define COMPACTION_PRIORITY
279#define COMPACTION_FEEDBACK
280#endif
281
282#ifdef CONFIG_ZONE_DMA
283#define IFDEF_ZONE_DMA(X) X
284#else
285#define IFDEF_ZONE_DMA(X)
286#endif
287
288#ifdef CONFIG_ZONE_DMA32
289#define IFDEF_ZONE_DMA32(X) X
290#else
291#define IFDEF_ZONE_DMA32(X)
292#endif
293
294#ifdef CONFIG_HIGHMEM
295#define IFDEF_ZONE_HIGHMEM(X) X
296#else
297#define IFDEF_ZONE_HIGHMEM(X)
298#endif
299
300#define ZONE_TYPE \
301 IFDEF_ZONE_DMA( EM (ZONE_DMA, "DMA")) \
302 IFDEF_ZONE_DMA32( EM (ZONE_DMA32, "DMA32")) \
303 EM (ZONE_NORMAL, "Normal") \
304 IFDEF_ZONE_HIGHMEM( EM (ZONE_HIGHMEM,"HighMem")) \
305 EMe(ZONE_MOVABLE,"Movable")
306
307#define LRU_NAMES \
308 EM (LRU_INACTIVE_ANON, "inactive_anon") \
309 EM (LRU_ACTIVE_ANON, "active_anon") \
310 EM (LRU_INACTIVE_FILE, "inactive_file") \
311 EM (LRU_ACTIVE_FILE, "active_file") \
312 EMe(LRU_UNEVICTABLE, "unevictable")
313
314/*
315 * First define the enums in the above macros to be exported to userspace
316 * via TRACE_DEFINE_ENUM().
317 */
318#undef EM
319#undef EMe
320#define EM(a, b) TRACE_DEFINE_ENUM(a);
321#define EMe(a, b) TRACE_DEFINE_ENUM(a);
322
323COMPACTION_STATUS
324COMPACTION_PRIORITY
325/* COMPACTION_FEEDBACK are defines not enums. Not needed here. */
326ZONE_TYPE
327LRU_NAMES
328
329/*
330 * Now redefine the EM() and EMe() macros to map the enums to the strings
331 * that will be printed in the output.
332 */
333#undef EM
334#undef EMe
335#define EM(a, b) {a, b},
336#define EMe(a, b) {a, b}
337