diff options
author | Nikita Danilov <nikita@clusterfs.com> | 2005-06-21 20:14:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 21:46:14 -0400 |
commit | 295ab93497ec703f7d6eaf0787dd9768b83035fe (patch) | |
tree | e3dce05d4cab0d7d3907a7357d37932c99ffd76d /mm | |
parent | 05b7438475ddbac47e75506913d44550f0e75938 (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>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 113 |
1 files changed, 111 insertions, 2 deletions
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 | */ | ||
1859 | static 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 | |||
1957 | struct 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 | |||
1856 | static char *vmstat_text[] = { | 1965 | static 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 | ||