aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>2009-09-21 20:01:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-22 10:17:27 -0400
commitc6a7f5728a1db45d30df55a01adc130b4ab0327c (patch)
tree36649bc6ebb959841a5097c699968722cfd99c4d
parent71de1ccbe1fb40203edd3beb473f8580d917d2ca (diff)
mm: oom analysis: Show kernel stack usage in /proc/meminfo and OOM log output
The amount of memory allocated to kernel stacks can become significant and cause OOM conditions. However, we do not display the amount of memory consumed by stacks. Add code to display the amount of memory used for stacks in /proc/meminfo. Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Reviewed-by: Christoph Lameter <cl@linux-foundation.org> Reviewed-by: Minchan Kim <minchan.kim@gmail.com> Reviewed-by: Rik van Riel <riel@redhat.com> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/base/node.c3
-rw-r--r--fs/proc/meminfo.c2
-rw-r--r--include/linux/mmzone.h3
-rw-r--r--kernel/fork.c11
-rw-r--r--mm/page_alloc.c3
-rw-r--r--mm/vmstat.c1
6 files changed, 22 insertions, 1 deletions
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 91d4087b4039..b560c17f6d4e 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -85,6 +85,7 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
85 "Node %d FilePages: %8lu kB\n" 85 "Node %d FilePages: %8lu kB\n"
86 "Node %d Mapped: %8lu kB\n" 86 "Node %d Mapped: %8lu kB\n"
87 "Node %d AnonPages: %8lu kB\n" 87 "Node %d AnonPages: %8lu kB\n"
88 "Node %d KernelStack: %8lu kB\n"
88 "Node %d PageTables: %8lu kB\n" 89 "Node %d PageTables: %8lu kB\n"
89 "Node %d NFS_Unstable: %8lu kB\n" 90 "Node %d NFS_Unstable: %8lu kB\n"
90 "Node %d Bounce: %8lu kB\n" 91 "Node %d Bounce: %8lu kB\n"
@@ -116,6 +117,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
116 nid, K(node_page_state(nid, NR_FILE_PAGES)), 117 nid, K(node_page_state(nid, NR_FILE_PAGES)),
117 nid, K(node_page_state(nid, NR_FILE_MAPPED)), 118 nid, K(node_page_state(nid, NR_FILE_MAPPED)),
118 nid, K(node_page_state(nid, NR_ANON_PAGES)), 119 nid, K(node_page_state(nid, NR_ANON_PAGES)),
120 nid, node_page_state(nid, NR_KERNEL_STACK) *
121 THREAD_SIZE / 1024,
119 nid, K(node_page_state(nid, NR_PAGETABLE)), 122 nid, K(node_page_state(nid, NR_PAGETABLE)),
120 nid, K(node_page_state(nid, NR_UNSTABLE_NFS)), 123 nid, K(node_page_state(nid, NR_UNSTABLE_NFS)),
121 nid, K(node_page_state(nid, NR_BOUNCE)), 124 nid, K(node_page_state(nid, NR_BOUNCE)),
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index d5c410d47fae..1fc588f430e4 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -84,6 +84,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
84 "Slab: %8lu kB\n" 84 "Slab: %8lu kB\n"
85 "SReclaimable: %8lu kB\n" 85 "SReclaimable: %8lu kB\n"
86 "SUnreclaim: %8lu kB\n" 86 "SUnreclaim: %8lu kB\n"
87 "KernelStack: %8lu kB\n"
87 "PageTables: %8lu kB\n" 88 "PageTables: %8lu kB\n"
88#ifdef CONFIG_QUICKLIST 89#ifdef CONFIG_QUICKLIST
89 "Quicklists: %8lu kB\n" 90 "Quicklists: %8lu kB\n"
@@ -128,6 +129,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
128 global_page_state(NR_SLAB_UNRECLAIMABLE)), 129 global_page_state(NR_SLAB_UNRECLAIMABLE)),
129 K(global_page_state(NR_SLAB_RECLAIMABLE)), 130 K(global_page_state(NR_SLAB_RECLAIMABLE)),
130 K(global_page_state(NR_SLAB_UNRECLAIMABLE)), 131 K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
132 global_page_state(NR_KERNEL_STACK) * THREAD_SIZE / 1024,
131 K(global_page_state(NR_PAGETABLE)), 133 K(global_page_state(NR_PAGETABLE)),
132#ifdef CONFIG_QUICKLIST 134#ifdef CONFIG_QUICKLIST
133 K(quicklist_total_size()), 135 K(quicklist_total_size()),
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 889598537370..d9335b8de84a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -94,10 +94,11 @@ enum zone_stat_item {
94 NR_SLAB_RECLAIMABLE, 94 NR_SLAB_RECLAIMABLE,
95 NR_SLAB_UNRECLAIMABLE, 95 NR_SLAB_UNRECLAIMABLE,
96 NR_PAGETABLE, /* used for pagetables */ 96 NR_PAGETABLE, /* used for pagetables */
97 NR_KERNEL_STACK,
98 /* Second 128 byte cacheline */
97 NR_UNSTABLE_NFS, /* NFS unstable pages */ 99 NR_UNSTABLE_NFS, /* NFS unstable pages */
98 NR_BOUNCE, 100 NR_BOUNCE,
99 NR_VMSCAN_WRITE, 101 NR_VMSCAN_WRITE,
100 /* Second 128 byte cacheline */
101 NR_WRITEBACK_TEMP, /* Writeback using temporary buffers */ 102 NR_WRITEBACK_TEMP, /* Writeback using temporary buffers */
102#ifdef CONFIG_NUMA 103#ifdef CONFIG_NUMA
103 NUMA_HIT, /* allocated in intended node */ 104 NUMA_HIT, /* allocated in intended node */
diff --git a/kernel/fork.c b/kernel/fork.c
index 2cebfb23b0b8..d4638c8cc19e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -136,9 +136,17 @@ struct kmem_cache *vm_area_cachep;
136/* SLAB cache for mm_struct structures (tsk->mm) */ 136/* SLAB cache for mm_struct structures (tsk->mm) */
137static struct kmem_cache *mm_cachep; 137static struct kmem_cache *mm_cachep;
138 138
139static void account_kernel_stack(struct thread_info *ti, int account)
140{
141 struct zone *zone = page_zone(virt_to_page(ti));
142
143 mod_zone_page_state(zone, NR_KERNEL_STACK, account);
144}
145
139void free_task(struct task_struct *tsk) 146void free_task(struct task_struct *tsk)
140{ 147{
141 prop_local_destroy_single(&tsk->dirties); 148 prop_local_destroy_single(&tsk->dirties);
149 account_kernel_stack(tsk->stack, -1);
142 free_thread_info(tsk->stack); 150 free_thread_info(tsk->stack);
143 rt_mutex_debug_task_free(tsk); 151 rt_mutex_debug_task_free(tsk);
144 ftrace_graph_exit_task(tsk); 152 ftrace_graph_exit_task(tsk);
@@ -253,6 +261,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
253 tsk->btrace_seq = 0; 261 tsk->btrace_seq = 0;
254#endif 262#endif
255 tsk->splice_pipe = NULL; 263 tsk->splice_pipe = NULL;
264
265 account_kernel_stack(ti, 1);
266
256 return tsk; 267 return tsk;
257 268
258out: 269out:
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 494c09196c30..4e050f325ebd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2177,6 +2177,7 @@ void show_free_areas(void)
2177 " mapped:%lukB" 2177 " mapped:%lukB"
2178 " slab_reclaimable:%lukB" 2178 " slab_reclaimable:%lukB"
2179 " slab_unreclaimable:%lukB" 2179 " slab_unreclaimable:%lukB"
2180 " kernel_stack:%lukB"
2180 " pagetables:%lukB" 2181 " pagetables:%lukB"
2181 " unstable:%lukB" 2182 " unstable:%lukB"
2182 " bounce:%lukB" 2183 " bounce:%lukB"
@@ -2201,6 +2202,8 @@ void show_free_areas(void)
2201 K(zone_page_state(zone, NR_FILE_MAPPED)), 2202 K(zone_page_state(zone, NR_FILE_MAPPED)),
2202 K(zone_page_state(zone, NR_SLAB_RECLAIMABLE)), 2203 K(zone_page_state(zone, NR_SLAB_RECLAIMABLE)),
2203 K(zone_page_state(zone, NR_SLAB_UNRECLAIMABLE)), 2204 K(zone_page_state(zone, NR_SLAB_UNRECLAIMABLE)),
2205 zone_page_state(zone, NR_KERNEL_STACK) *
2206 THREAD_SIZE / 1024,
2204 K(zone_page_state(zone, NR_PAGETABLE)), 2207 K(zone_page_state(zone, NR_PAGETABLE)),
2205 K(zone_page_state(zone, NR_UNSTABLE_NFS)), 2208 K(zone_page_state(zone, NR_UNSTABLE_NFS)),
2206 K(zone_page_state(zone, NR_BOUNCE)), 2209 K(zone_page_state(zone, NR_BOUNCE)),
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 138bed53706e..ceda39b63d7e 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -639,6 +639,7 @@ static const char * const vmstat_text[] = {
639 "nr_slab_reclaimable", 639 "nr_slab_reclaimable",
640 "nr_slab_unreclaimable", 640 "nr_slab_unreclaimable",
641 "nr_page_table_pages", 641 "nr_page_table_pages",
642 "nr_kernel_stack",
642 "nr_unstable", 643 "nr_unstable",
643 "nr_bounce", 644 "nr_bounce",
644 "nr_vmscan_write", 645 "nr_vmscan_write",