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(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