debug.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * mm/debug.c
  3. *
  4. * mm/ specific debug routines.
  5. *
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/mm.h>
  9. #include <linux/trace_events.h>
  10. #include <linux/memcontrol.h>
  11. static const struct trace_print_flags pageflag_names[] = {
  12. {1UL << PG_locked, "locked" },
  13. {1UL << PG_error, "error" },
  14. {1UL << PG_referenced, "referenced" },
  15. {1UL << PG_uptodate, "uptodate" },
  16. {1UL << PG_dirty, "dirty" },
  17. {1UL << PG_lru, "lru" },
  18. {1UL << PG_active, "active" },
  19. {1UL << PG_slab, "slab" },
  20. {1UL << PG_owner_priv_1, "owner_priv_1" },
  21. {1UL << PG_arch_1, "arch_1" },
  22. {1UL << PG_reserved, "reserved" },
  23. {1UL << PG_private, "private" },
  24. {1UL << PG_private_2, "private_2" },
  25. {1UL << PG_writeback, "writeback" },
  26. #ifdef CONFIG_PAGEFLAGS_EXTENDED
  27. {1UL << PG_head, "head" },
  28. {1UL << PG_tail, "tail" },
  29. #else
  30. {1UL << PG_compound, "compound" },
  31. #endif
  32. {1UL << PG_swapcache, "swapcache" },
  33. {1UL << PG_mappedtodisk, "mappedtodisk" },
  34. {1UL << PG_reclaim, "reclaim" },
  35. {1UL << PG_swapbacked, "swapbacked" },
  36. {1UL << PG_unevictable, "unevictable" },
  37. #ifdef CONFIG_MMU
  38. {1UL << PG_mlocked, "mlocked" },
  39. #endif
  40. #ifdef CONFIG_ARCH_USES_PG_UNCACHED
  41. {1UL << PG_uncached, "uncached" },
  42. #endif
  43. #ifdef CONFIG_MEMORY_FAILURE
  44. {1UL << PG_hwpoison, "hwpoison" },
  45. #endif
  46. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  47. {1UL << PG_compound_lock, "compound_lock" },
  48. #endif
  49. };
  50. static void dump_flags(unsigned long flags,
  51. const struct trace_print_flags *names, int count)
  52. {
  53. const char *delim = "";
  54. unsigned long mask;
  55. int i;
  56. pr_emerg("flags: %#lx(", flags);
  57. /* remove zone id */
  58. flags &= (1UL << NR_PAGEFLAGS) - 1;
  59. for (i = 0; i < count && flags; i++) {
  60. mask = names[i].mask;
  61. if ((flags & mask) != mask)
  62. continue;
  63. flags &= ~mask;
  64. pr_cont("%s%s", delim, names[i].name);
  65. delim = "|";
  66. }
  67. /* check for left over flags */
  68. if (flags)
  69. pr_cont("%s%#lx", delim, flags);
  70. pr_cont(")\n");
  71. }
  72. void dump_page_badflags(struct page *page, const char *reason,
  73. unsigned long badflags)
  74. {
  75. pr_emerg("page:%p count:%d mapcount:%d mapping:%p index:%#lx\n",
  76. page, atomic_read(&page->_count), page_mapcount(page),
  77. page->mapping, page->index);
  78. BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS);
  79. dump_flags(page->flags, pageflag_names, ARRAY_SIZE(pageflag_names));
  80. if (reason)
  81. pr_alert("page dumped because: %s\n", reason);
  82. if (page->flags & badflags) {
  83. pr_alert("bad because of flags:\n");
  84. dump_flags(page->flags & badflags,
  85. pageflag_names, ARRAY_SIZE(pageflag_names));
  86. }
  87. #ifdef CONFIG_MEMCG
  88. if (page->mem_cgroup)
  89. pr_alert("page->mem_cgroup:%p\n", page->mem_cgroup);
  90. #endif
  91. }
  92. void dump_page(struct page *page, const char *reason)
  93. {
  94. dump_page_badflags(page, reason, 0);
  95. }
  96. EXPORT_SYMBOL(dump_page);
  97. #ifdef CONFIG_DEBUG_VM
  98. static const struct trace_print_flags vmaflags_names[] = {
  99. {VM_READ, "read" },
  100. {VM_WRITE, "write" },
  101. {VM_EXEC, "exec" },
  102. {VM_SHARED, "shared" },
  103. {VM_MAYREAD, "mayread" },
  104. {VM_MAYWRITE, "maywrite" },
  105. {VM_MAYEXEC, "mayexec" },
  106. {VM_MAYSHARE, "mayshare" },
  107. {VM_GROWSDOWN, "growsdown" },
  108. {VM_PFNMAP, "pfnmap" },
  109. {VM_DENYWRITE, "denywrite" },
  110. {VM_LOCKED, "locked" },
  111. {VM_IO, "io" },
  112. {VM_SEQ_READ, "seqread" },
  113. {VM_RAND_READ, "randread" },
  114. {VM_DONTCOPY, "dontcopy" },
  115. {VM_DONTEXPAND, "dontexpand" },
  116. {VM_ACCOUNT, "account" },
  117. {VM_NORESERVE, "noreserve" },
  118. {VM_HUGETLB, "hugetlb" },
  119. #if defined(CONFIG_X86)
  120. {VM_PAT, "pat" },
  121. #elif defined(CONFIG_PPC)
  122. {VM_SAO, "sao" },
  123. #elif defined(CONFIG_PARISC) || defined(CONFIG_METAG) || defined(CONFIG_IA64)
  124. {VM_GROWSUP, "growsup" },
  125. #elif !defined(CONFIG_MMU)
  126. {VM_MAPPED_COPY, "mappedcopy" },
  127. #else
  128. {VM_ARCH_1, "arch_1" },
  129. #endif
  130. {VM_DONTDUMP, "dontdump" },
  131. #ifdef CONFIG_MEM_SOFT_DIRTY
  132. {VM_SOFTDIRTY, "softdirty" },
  133. #endif
  134. {VM_MIXEDMAP, "mixedmap" },
  135. {VM_HUGEPAGE, "hugepage" },
  136. {VM_NOHUGEPAGE, "nohugepage" },
  137. {VM_MERGEABLE, "mergeable" },
  138. };
  139. void dump_vma(const struct vm_area_struct *vma)
  140. {
  141. pr_emerg("vma %p start %p end %p\n"
  142. "next %p prev %p mm %p\n"
  143. "prot %lx anon_vma %p vm_ops %p\n"
  144. "pgoff %lx file %p private_data %p\n",
  145. vma, (void *)vma->vm_start, (void *)vma->vm_end, vma->vm_next,
  146. vma->vm_prev, vma->vm_mm,
  147. (unsigned long)pgprot_val(vma->vm_page_prot),
  148. vma->anon_vma, vma->vm_ops, vma->vm_pgoff,
  149. vma->vm_file, vma->vm_private_data);
  150. dump_flags(vma->vm_flags, vmaflags_names, ARRAY_SIZE(vmaflags_names));
  151. }
  152. EXPORT_SYMBOL(dump_vma);
  153. void dump_mm(const struct mm_struct *mm)
  154. {
  155. pr_emerg("mm %p mmap %p seqnum %d task_size %lu\n"
  156. #ifdef CONFIG_MMU
  157. "get_unmapped_area %p\n"
  158. #endif
  159. "mmap_base %lu mmap_legacy_base %lu highest_vm_end %lu\n"
  160. "pgd %p mm_users %d mm_count %d nr_ptes %lu nr_pmds %lu map_count %d\n"
  161. "hiwater_rss %lx hiwater_vm %lx total_vm %lx locked_vm %lx\n"
  162. "pinned_vm %lx shared_vm %lx exec_vm %lx stack_vm %lx\n"
  163. "start_code %lx end_code %lx start_data %lx end_data %lx\n"
  164. "start_brk %lx brk %lx start_stack %lx\n"
  165. "arg_start %lx arg_end %lx env_start %lx env_end %lx\n"
  166. "binfmt %p flags %lx core_state %p\n"
  167. #ifdef CONFIG_AIO
  168. "ioctx_table %p\n"
  169. #endif
  170. #ifdef CONFIG_MEMCG
  171. "owner %p "
  172. #endif
  173. "exe_file %p\n"
  174. #ifdef CONFIG_MMU_NOTIFIER
  175. "mmu_notifier_mm %p\n"
  176. #endif
  177. #ifdef CONFIG_NUMA_BALANCING
  178. "numa_next_scan %lu numa_scan_offset %lu numa_scan_seq %d\n"
  179. #endif
  180. #if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
  181. "tlb_flush_pending %d\n"
  182. #endif
  183. "%s", /* This is here to hold the comma */
  184. mm, mm->mmap, mm->vmacache_seqnum, mm->task_size,
  185. #ifdef CONFIG_MMU
  186. mm->get_unmapped_area,
  187. #endif
  188. mm->mmap_base, mm->mmap_legacy_base, mm->highest_vm_end,
  189. mm->pgd, atomic_read(&mm->mm_users),
  190. atomic_read(&mm->mm_count),
  191. atomic_long_read((atomic_long_t *)&mm->nr_ptes),
  192. mm_nr_pmds((struct mm_struct *)mm),
  193. mm->map_count,
  194. mm->hiwater_rss, mm->hiwater_vm, mm->total_vm, mm->locked_vm,
  195. mm->pinned_vm, mm->shared_vm, mm->exec_vm, mm->stack_vm,
  196. mm->start_code, mm->end_code, mm->start_data, mm->end_data,
  197. mm->start_brk, mm->brk, mm->start_stack,
  198. mm->arg_start, mm->arg_end, mm->env_start, mm->env_end,
  199. mm->binfmt, mm->flags, mm->core_state,
  200. #ifdef CONFIG_AIO
  201. mm->ioctx_table,
  202. #endif
  203. #ifdef CONFIG_MEMCG
  204. mm->owner,
  205. #endif
  206. mm->exe_file,
  207. #ifdef CONFIG_MMU_NOTIFIER
  208. mm->mmu_notifier_mm,
  209. #endif
  210. #ifdef CONFIG_NUMA_BALANCING
  211. mm->numa_next_scan, mm->numa_scan_offset, mm->numa_scan_seq,
  212. #endif
  213. #if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
  214. mm->tlb_flush_pending,
  215. #endif
  216. "" /* This is here to not have a comma! */
  217. );
  218. dump_flags(mm->def_flags, vmaflags_names,
  219. ARRAY_SIZE(vmaflags_names));
  220. }
  221. #endif /* CONFIG_DEBUG_VM */