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 struct vma_merge_struct; 13 14 void dump_page(const struct page *page, const char *reason); 15 void dump_vma(const struct vm_area_struct *vma); 16 void dump_mm(const struct mm_struct *mm); 17 void dump_vmg(const struct vma_merge_struct *vmg, const char *reason); 18 void vma_iter_dump_tree(const struct vma_iterator *vmi); 19 20 #ifdef CONFIG_DEBUG_VM 21 #define VM_BUG_ON(cond) BUG_ON(cond) 22 #define VM_BUG_ON_PAGE(cond, page) \ 23 do { \ 24 if (unlikely(cond)) { \ 25 dump_page(page, "VM_BUG_ON_PAGE(" __stringify(cond)")");\ 26 BUG(); \ 27 } \ 28 } while (0) 29 #define VM_BUG_ON_FOLIO(cond, folio) \ 30 do { \ 31 if (unlikely(cond)) { \ 32 dump_page(&folio->page, "VM_BUG_ON_FOLIO(" __stringify(cond)")");\ 33 BUG(); \ 34 } \ 35 } while (0) 36 #define VM_BUG_ON_VMA(cond, vma) \ 37 do { \ 38 if (unlikely(cond)) { \ 39 dump_vma(vma); \ 40 BUG(); \ 41 } \ 42 } while (0) 43 #define VM_BUG_ON_MM(cond, mm) \ 44 do { \ 45 if (unlikely(cond)) { \ 46 dump_mm(mm); \ 47 BUG(); \ 48 } \ 49 } while (0) 50 #define VM_WARN_ON_PAGE(cond, page) ({ \ 51 int __ret_warn = !!(cond); \ 52 \ 53 if (unlikely(__ret_warn)) { \ 54 dump_page(page, "VM_WARN_ON_PAGE(" __stringify(cond)")");\ 55 WARN_ON(1); \ 56 } \ 57 unlikely(__ret_warn); \ 58 }) 59 #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ 60 static bool __section(".data..once") __warned; \ 61 int __ret_warn_once = !!(cond); \ 62 \ 63 if (unlikely(__ret_warn_once && !__warned)) { \ 64 dump_page(page, "VM_WARN_ON_ONCE_PAGE(" __stringify(cond)")");\ 65 __warned = true; \ 66 WARN_ON(1); \ 67 } \ 68 unlikely(__ret_warn_once); \ 69 }) 70 #define VM_WARN_ON_FOLIO(cond, folio) ({ \ 71 int __ret_warn = !!(cond); \ 72 \ 73 if (unlikely(__ret_warn)) { \ 74 dump_page(&folio->page, "VM_WARN_ON_FOLIO(" __stringify(cond)")");\ 75 WARN_ON(1); \ 76 } \ 77 unlikely(__ret_warn); \ 78 }) 79 #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \ 80 static bool __section(".data..once") __warned; \ 81 int __ret_warn_once = !!(cond); \ 82 \ 83 if (unlikely(__ret_warn_once && !__warned)) { \ 84 dump_page(&folio->page, "VM_WARN_ON_ONCE_FOLIO(" __stringify(cond)")");\ 85 __warned = true; \ 86 WARN_ON(1); \ 87 } \ 88 unlikely(__ret_warn_once); \ 89 }) 90 #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ 91 static bool __section(".data..once") __warned; \ 92 int __ret_warn_once = !!(cond); \ 93 \ 94 if (unlikely(__ret_warn_once && !__warned)) { \ 95 dump_mm(mm); \ 96 __warned = true; \ 97 WARN_ON(1); \ 98 } \ 99 unlikely(__ret_warn_once); \ 100 }) 101 #define VM_WARN_ON_ONCE_VMA(cond, vma) ({ \ 102 static bool __section(".data..once") __warned; \ 103 int __ret_warn_once = !!(cond); \ 104 \ 105 if (unlikely(__ret_warn_once && !__warned)) { \ 106 dump_vma(vma); \ 107 __warned = true; \ 108 WARN_ON(1); \ 109 } \ 110 unlikely(__ret_warn_once); \ 111 }) 112 #define VM_WARN_ON_VMG(cond, vmg) ({ \ 113 int __ret_warn = !!(cond); \ 114 \ 115 if (unlikely(__ret_warn)) { \ 116 dump_vmg(vmg, "VM_WARN_ON_VMG(" __stringify(cond)")"); \ 117 WARN_ON(1); \ 118 } \ 119 unlikely(__ret_warn); \ 120 }) 121 122 #define VM_WARN_ON(cond) (void)WARN_ON(cond) 123 #define VM_WARN_ON_ONCE(cond) (void)WARN_ON_ONCE(cond) 124 #define VM_WARN_ONCE(cond, format...) (void)WARN_ONCE(cond, format) 125 #define VM_WARN(cond, format...) (void)WARN(cond, format) 126 #else 127 #define VM_BUG_ON(cond) BUILD_BUG_ON_INVALID(cond) 128 #define VM_BUG_ON_PAGE(cond, page) VM_BUG_ON(cond) 129 #define VM_BUG_ON_FOLIO(cond, folio) VM_BUG_ON(cond) 130 #define VM_BUG_ON_VMA(cond, vma) VM_BUG_ON(cond) 131 #define VM_BUG_ON_MM(cond, mm) VM_BUG_ON(cond) 132 #define VM_WARN_ON(cond) BUILD_BUG_ON_INVALID(cond) 133 #define VM_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond) 134 #define VM_WARN_ON_PAGE(cond, page) BUILD_BUG_ON_INVALID(cond) 135 #define VM_WARN_ON_ONCE_PAGE(cond, page) BUILD_BUG_ON_INVALID(cond) 136 #define VM_WARN_ON_FOLIO(cond, folio) BUILD_BUG_ON_INVALID(cond) 137 #define VM_WARN_ON_ONCE_FOLIO(cond, folio) BUILD_BUG_ON_INVALID(cond) 138 #define VM_WARN_ON_ONCE_MM(cond, mm) BUILD_BUG_ON_INVALID(cond) 139 #define VM_WARN_ON_ONCE_VMA(cond, vma) BUILD_BUG_ON_INVALID(cond) 140 #define VM_WARN_ON_VMG(cond, vmg) BUILD_BUG_ON_INVALID(cond) 141 #define VM_WARN_ONCE(cond, format...) BUILD_BUG_ON_INVALID(cond) 142 #define VM_WARN(cond, format...) BUILD_BUG_ON_INVALID(cond) 143 #endif /* CONFIG_DEBUG_VM */ 144 145 #ifdef CONFIG_DEBUG_VM_IRQSOFF 146 #define VM_WARN_ON_IRQS_ENABLED() WARN_ON_ONCE(!irqs_disabled()) 147 #else 148 #define VM_WARN_ON_IRQS_ENABLED() do { } while (0) 149 #endif 150 151 #ifdef CONFIG_DEBUG_VIRTUAL 152 #define VIRTUAL_BUG_ON(cond) BUG_ON(cond) 153 #else 154 #define VIRTUAL_BUG_ON(cond) do { } while (0) 155 #endif 156 157 #ifdef CONFIG_DEBUG_VM_PGFLAGS 158 #define VM_BUG_ON_PGFLAGS(cond, page) VM_BUG_ON_PAGE(cond, page) 159 #else 160 #define VM_BUG_ON_PGFLAGS(cond, page) BUILD_BUG_ON_INVALID(cond) 161 #endif 162 163 #endif 164