debug.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/mm/debug.c
  3.  *
  4.  *  Copyright (C) 2001 Russell King.
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License version 2 as
  8.  * published by the Free Software Foundation.
  9.  *
  10.  *  Dump out page information on SysRQ-G, and provide show_page_info()
  11.  *
  12.  *  You are advised to use a serial console with this patch - it
  13.  *  saturates a 38400baud link for 1 minute on a 32MB machine.
  14.  */
  15. #include <linux/kernel.h>
  16. #include <linux/mm.h>
  17. #include <linux/pagemap.h>
  18. #include <linux/sysrq.h>
  19. #include <linux/init.h>
  20. /*
  21.  * We print out the following information for each page in the system:
  22.  * address: use count, age, mapping, [RSsr] rD [acd]
  23.  *
  24.  * The flags are:
  25.  * R - reserved
  26.  * S - in swapcache
  27.  * s - slab page
  28.  *
  29.  * r - referenced
  30.  * D - dirty
  31.  *
  32.  * a - active page
  33.  */
  34. static void page_detail(struct page *page)
  35. {
  36. if (!page)
  37. return;
  38. printk("%p: %2d %p [%c%c%c] %c%c [%c]n",
  39. page_address(page),
  40. page_count(page),
  41. page->mapping,
  42. PageReserved(page) ? 'R' : '-',
  43. PageSwapCache(page) ? 'S' : '-',
  44. PageSlab(page) ? 's' : '-',
  45. PageReferenced(page) ? 'r' : '-',
  46. PageDirty(page) ? 'D' : '-',
  47. PageActive(page) ? 'a' : '-');
  48. }
  49. /*
  50.  * This version collects statistics
  51.  */
  52. static int anon_pages, slab_pages, resvd_pages, unused_pages;
  53. static void page_statistics(struct page *page)
  54. {
  55. if (page) {
  56. if (PageReserved(page))
  57. resvd_pages++;
  58. else if (PageSlab(page))
  59. slab_pages++;
  60. else if (!page_count(page))
  61. unused_pages ++;
  62. else if (!page->mapping)
  63. anon_pages ++;
  64. return;
  65. }
  66. printk("  anon: %d, slab: %d, reserved: %d, free: %dn",
  67. anon_pages, slab_pages, resvd_pages, unused_pages);
  68. }
  69. static void show_zone_info(zone_t *zone, void (*fn)(struct page *))
  70. {
  71. int i;
  72. printk("  total %ld, free %ld min %ld, low %ld, high %ldn",
  73. zone->size, zone->free_pages, zone->pages_min,
  74. zone->pages_low, zone->pages_high);
  75. anon_pages    = 0;
  76. slab_pages    = 0;
  77. resvd_pages   = 0;
  78. unused_pages  = 0;
  79. for (i = 0; i < zone->size; i++) {
  80. struct page *page = zone->zone_mem_map + i;
  81. fn(page);
  82. }
  83. fn(NULL);
  84. }
  85. static void show_node_info(pg_data_t *pg, void (*fn)(struct page *))
  86. {
  87. int type;
  88. for (type = 0; type < MAX_NR_ZONES; type++) {
  89. zone_t *zone = pg->node_zones + type;
  90. if (zone->size == 0)
  91. continue;
  92. printk("----- Zone %d ------n", type);
  93. show_zone_info(zone, fn);
  94. }
  95. }
  96. static void __show_page_info(void (*fn)(struct page *))
  97. {
  98. pg_data_t *pg;
  99. int pgdat = 0;
  100. for (pg = pgdat_list; pg; pg = pg->node_next) {
  101. printk("===== Node %d =====n", pgdat++);
  102. show_node_info(pg, fn);
  103. }
  104. }
  105. void show_page_info(void)
  106. {
  107. __show_page_info(page_detail);
  108. }
  109. static void
  110. show_pg_info(int key, struct pt_regs *regs, struct kbd_struct *kd,
  111.      struct tty_struct *tty)
  112. {
  113. void (*fn)(struct page *);
  114. show_mem();
  115. if (key == 'g')
  116. fn = page_detail;
  117. else
  118. fn = page_statistics;
  119. __show_page_info(fn);
  120. }
  121. static struct sysrq_key_op page_info_op = {
  122. handler: show_pg_info,
  123. help_msg: "paGeinfo",
  124. action_msg: "Page Info",
  125. };
  126. static int __init debug_mm_init(void)
  127. {
  128. register_sysrq_key('g', &page_info_op);
  129. register_sysrq_key('h', &page_info_op);
  130. return 0;
  131. }
  132. __initcall(debug_mm_init);