1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef LINUX_MM_DEBUG_H |
3 | #define LINUX_MM_DEBUG_H 1 |
4 | |
5 | #include <linux/bug.h> |
6 | #include <linux/stringify.h> |
7 | |
8 | struct page; |
9 | struct vm_area_struct; |
10 | struct mm_struct; |
11 | struct vma_iterator; |
12 | |
13 | void dump_page(const struct page *page, const char *reason); |
14 | void dump_vma(const struct vm_area_struct *vma); |
15 | void dump_mm(const struct mm_struct *mm); |
16 | void vma_iter_dump_tree(const struct vma_iterator *vmi); |
17 | |
18 | #ifdef CONFIG_DEBUG_VM |
19 | #define VM_BUG_ON(cond) BUG_ON(cond) |
20 | #define VM_BUG_ON_PAGE(cond, page) \ |
21 | do { \ |
22 | if (unlikely(cond)) { \ |
23 | dump_page(page, "VM_BUG_ON_PAGE(" __stringify(cond)")");\ |
24 | BUG(); \ |
25 | } \ |
26 | } while (0) |
27 | #define VM_BUG_ON_FOLIO(cond, folio) \ |
28 | do { \ |
29 | if (unlikely(cond)) { \ |
30 | dump_page(&folio->page, "VM_BUG_ON_FOLIO(" __stringify(cond)")");\ |
31 | BUG(); \ |
32 | } \ |
33 | } while (0) |
34 | #define VM_BUG_ON_VMA(cond, vma) \ |
35 | do { \ |
36 | if (unlikely(cond)) { \ |
37 | dump_vma(vma); \ |
38 | BUG(); \ |
39 | } \ |
40 | } while (0) |
41 | #define VM_BUG_ON_MM(cond, mm) \ |
42 | do { \ |
43 | if (unlikely(cond)) { \ |
44 | dump_mm(mm); \ |
45 | BUG(); \ |
46 | } \ |
47 | } while (0) |
48 | #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ |
49 | static bool __section(".data.once") __warned; \ |
50 | int __ret_warn_once = !!(cond); \ |
51 | \ |
52 | if (unlikely(__ret_warn_once && !__warned)) { \ |
53 | dump_page(page, "VM_WARN_ON_ONCE_PAGE(" __stringify(cond)")");\ |
54 | __warned = true; \ |
55 | WARN_ON(1); \ |
56 | } \ |
57 | unlikely(__ret_warn_once); \ |
58 | }) |
59 | #define VM_WARN_ON_FOLIO(cond, folio) ({ \ |
60 | int __ret_warn = !!(cond); \ |
61 | \ |
62 | if (unlikely(__ret_warn)) { \ |
63 | dump_page(&folio->page, "VM_WARN_ON_FOLIO(" __stringify(cond)")");\ |
64 | WARN_ON(1); \ |
65 | } \ |
66 | unlikely(__ret_warn); \ |
67 | }) |
68 | #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \ |
69 | static bool __section(".data.once") __warned; \ |
70 | int __ret_warn_once = !!(cond); \ |
71 | \ |
72 | if (unlikely(__ret_warn_once && !__warned)) { \ |
73 | dump_page(&folio->page, "VM_WARN_ON_ONCE_FOLIO(" __stringify(cond)")");\ |
74 | __warned = true; \ |
75 | WARN_ON(1); \ |
76 | } \ |
77 | unlikely(__ret_warn_once); \ |
78 | }) |
79 | #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ |
80 | static bool __section(".data.once") __warned; \ |
81 | int __ret_warn_once = !!(cond); \ |
82 | \ |
83 | if (unlikely(__ret_warn_once && !__warned)) { \ |
84 | dump_mm(mm); \ |
85 | __warned = true; \ |
86 | WARN_ON(1); \ |
87 | } \ |
88 | unlikely(__ret_warn_once); \ |
89 | }) |
90 | |
91 | #define VM_WARN_ON(cond) (void)WARN_ON(cond) |
92 | #define VM_WARN_ON_ONCE(cond) (void)WARN_ON_ONCE(cond) |
93 | #define VM_WARN_ONCE(cond, format...) (void)WARN_ONCE(cond, format) |
94 | #define VM_WARN(cond, format...) (void)WARN(cond, format) |
95 | #else |
96 | #define VM_BUG_ON(cond) BUILD_BUG_ON_INVALID(cond) |
97 | #define VM_BUG_ON_PAGE(cond, page) VM_BUG_ON(cond) |
98 | #define VM_BUG_ON_FOLIO(cond, folio) VM_BUG_ON(cond) |
99 | #define VM_BUG_ON_VMA(cond, vma) VM_BUG_ON(cond) |
100 | #define VM_BUG_ON_MM(cond, mm) VM_BUG_ON(cond) |
101 | #define VM_WARN_ON(cond) BUILD_BUG_ON_INVALID(cond) |
102 | #define VM_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond) |
103 | #define VM_WARN_ON_ONCE_PAGE(cond, page) BUILD_BUG_ON_INVALID(cond) |
104 | #define VM_WARN_ON_FOLIO(cond, folio) BUILD_BUG_ON_INVALID(cond) |
105 | #define VM_WARN_ON_ONCE_FOLIO(cond, folio) BUILD_BUG_ON_INVALID(cond) |
106 | #define VM_WARN_ON_ONCE_MM(cond, mm) BUILD_BUG_ON_INVALID(cond) |
107 | #define VM_WARN_ONCE(cond, format...) BUILD_BUG_ON_INVALID(cond) |
108 | #define VM_WARN(cond, format...) BUILD_BUG_ON_INVALID(cond) |
109 | #endif |
110 | |
111 | #ifdef CONFIG_DEBUG_VM_IRQSOFF |
112 | #define VM_WARN_ON_IRQS_ENABLED() WARN_ON_ONCE(!irqs_disabled()) |
113 | #else |
114 | #define VM_WARN_ON_IRQS_ENABLED() do { } while (0) |
115 | #endif |
116 | |
117 | #ifdef CONFIG_DEBUG_VIRTUAL |
118 | #define VIRTUAL_BUG_ON(cond) BUG_ON(cond) |
119 | #else |
120 | #define VIRTUAL_BUG_ON(cond) do { } while (0) |
121 | #endif |
122 | |
123 | #ifdef CONFIG_DEBUG_VM_PGFLAGS |
124 | #define VM_BUG_ON_PGFLAGS(cond, page) VM_BUG_ON_PAGE(cond, page) |
125 | #else |
126 | #define VM_BUG_ON_PGFLAGS(cond, page) BUILD_BUG_ON_INVALID(cond) |
127 | #endif |
128 | |
129 | #endif |
130 | |