aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita Danilov <nikita@clusterfs.com>2005-06-21 20:14:38 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 21:46:14 -0400
commit295ab93497ec703f7d6eaf0787dd9768b83035fe (patch)
treee3dce05d4cab0d7d3907a7357d37932c99ffd76d
parent05b7438475ddbac47e75506913d44550f0e75938 (diff)
[PATCH] mm: add /proc/zoneinfo
Add /proc/zoneinfo file to display information about memory zones. Useful to analyze VM behaviour. Signed-off-by: Nikita Danilov <nikita@clusterfs.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/proc/proc_misc.c14
-rw-r--r--mm/page_alloc.c113
2 files changed, 125 insertions, 2 deletions
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index a60a3b3d8a7b..63a9fbf1ac51 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -219,6 +219,19 @@ static struct file_operations fragmentation_file_operations = {
219 .release = seq_release, 219 .release = seq_release,
220}; 220};
221 221
222extern struct seq_operations zoneinfo_op;
223static int zoneinfo_open(struct inode *inode, struct file *file)
224{
225 return seq_open(file, &zoneinfo_op);
226}
227
228static struct file_operations proc_zoneinfo_file_operations = {
229 .open = zoneinfo_open,
230 .read = seq_read,
231 .llseek = seq_lseek,
232 .release = seq_release,
233};
234
222static int version_read_proc(char *page, char **start, off_t off, 235static int version_read_proc(char *page, char **start, off_t off,
223 int count, int *eof, void *data) 236 int count, int *eof, void *data)
224{ 237{
@@ -589,6 +602,7 @@ void __init proc_misc_init(void)
589 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); 602 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
590 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); 603 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
591 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); 604 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
605 create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
592 create_seq_entry("diskstats", 0, &proc_diskstats_operations); 606 create_seq_entry("diskstats", 0, &proc_diskstats_operations);
593#ifdef CONFIG_MODULES 607#ifdef CONFIG_MODULES
594 create_seq_entry("modules", 0, &proc_modules_operations); 608 create_seq_entry("modules", 0, &proc_modules_operations);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index b1061b1962f8..40169f0b7e9e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1853,6 +1853,115 @@ struct seq_operations fragmentation_op = {
1853 .show = frag_show, 1853 .show = frag_show,
1854}; 1854};
1855 1855
1856/*
1857 * Output information about zones in @pgdat.
1858 */
1859static int zoneinfo_show(struct seq_file *m, void *arg)
1860{
1861 pg_data_t *pgdat = arg;
1862 struct zone *zone;
1863 struct zone *node_zones = pgdat->node_zones;
1864 unsigned long flags;
1865
1866 for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; zone++) {
1867 int i;
1868
1869 if (!zone->present_pages)
1870 continue;
1871
1872 spin_lock_irqsave(&zone->lock, flags);
1873 seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name);
1874 seq_printf(m,
1875 "\n pages free %lu"
1876 "\n min %lu"
1877 "\n low %lu"
1878 "\n high %lu"
1879 "\n active %lu"
1880 "\n inactive %lu"
1881 "\n scanned %lu (a: %lu i: %lu)"
1882 "\n spanned %lu"
1883 "\n present %lu",
1884 zone->free_pages,
1885 zone->pages_min,
1886 zone->pages_low,
1887 zone->pages_high,
1888 zone->nr_active,
1889 zone->nr_inactive,
1890 zone->pages_scanned,
1891 zone->nr_scan_active, zone->nr_scan_inactive,
1892 zone->spanned_pages,
1893 zone->present_pages);
1894 seq_printf(m,
1895 "\n protection: (%lu",
1896 zone->lowmem_reserve[0]);
1897 for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
1898 seq_printf(m, ", %lu", zone->lowmem_reserve[i]);
1899 seq_printf(m,
1900 ")"
1901 "\n pagesets");
1902 for (i = 0; i < ARRAY_SIZE(zone->pageset); i++) {
1903 struct per_cpu_pageset *pageset;
1904 int j;
1905
1906 pageset = &zone->pageset[i];
1907 for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
1908 if (pageset->pcp[j].count)
1909 break;
1910 }
1911 if (j == ARRAY_SIZE(pageset->pcp))
1912 continue;
1913 for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
1914 seq_printf(m,
1915 "\n cpu: %i pcp: %i"
1916 "\n count: %i"
1917 "\n low: %i"
1918 "\n high: %i"
1919 "\n batch: %i",
1920 i, j,
1921 pageset->pcp[j].count,
1922 pageset->pcp[j].low,
1923 pageset->pcp[j].high,
1924 pageset->pcp[j].batch);
1925 }
1926#ifdef CONFIG_NUMA
1927 seq_printf(m,
1928 "\n numa_hit: %lu"
1929 "\n numa_miss: %lu"
1930 "\n numa_foreign: %lu"
1931 "\n interleave_hit: %lu"
1932 "\n local_node: %lu"
1933 "\n other_node: %lu",
1934 pageset->numa_hit,
1935 pageset->numa_miss,
1936 pageset->numa_foreign,
1937 pageset->interleave_hit,
1938 pageset->local_node,
1939 pageset->other_node);
1940#endif
1941 }
1942 seq_printf(m,
1943 "\n all_unreclaimable: %u"
1944 "\n prev_priority: %i"
1945 "\n temp_priority: %i"
1946 "\n start_pfn: %lu",
1947 zone->all_unreclaimable,
1948 zone->prev_priority,
1949 zone->temp_priority,
1950 zone->zone_start_pfn);
1951 spin_unlock_irqrestore(&zone->lock, flags);
1952 seq_putc(m, '\n');
1953 }
1954 return 0;
1955}
1956
1957struct seq_operations zoneinfo_op = {
1958 .start = frag_start, /* iterate over all zones. The same as in
1959 * fragmentation. */
1960 .next = frag_next,
1961 .stop = frag_stop,
1962 .show = zoneinfo_show,
1963};
1964
1856static char *vmstat_text[] = { 1965static char *vmstat_text[] = {
1857 "nr_dirty", 1966 "nr_dirty",
1858 "nr_writeback", 1967 "nr_writeback",
@@ -2058,10 +2167,10 @@ static void setup_per_zone_pages_min(void)
2058 min_pages = 128; 2167 min_pages = 128;
2059 zone->pages_min = min_pages; 2168 zone->pages_min = min_pages;
2060 } else { 2169 } else {
2061 /* if it's a lowmem zone, reserve a number of pages 2170 /* if it's a lowmem zone, reserve a number of pages
2062 * proportionate to the zone's size. 2171 * proportionate to the zone's size.
2063 */ 2172 */
2064 zone->pages_min = (pages_min * zone->present_pages) / 2173 zone->pages_min = (pages_min * zone->present_pages) /
2065 lowmem_pages; 2174 lowmem_pages;
2066 } 2175 }
2067 2176