mm: oom analysis: Show kernel stack usage in /proc/meminfo and OOM log output
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Tue, 22 Sep 2009 00:01:32 +0000 (17:01 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 Sep 2009 14:17:27 +0000 (07:17 -0700)
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>
drivers/base/node.c
fs/proc/meminfo.c
include/linux/mmzone.h
kernel/fork.c
mm/page_alloc.c
mm/vmstat.c

index 91d4087b4039490a844d23e909ffe34eaa0ff0f9..b560c17f6d4e2a79b080fafaac75b61558e29b4a 100644 (file)
@@ -85,6 +85,7 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
                       "Node %d FilePages:      %8lu kB\n"
                       "Node %d Mapped:         %8lu kB\n"
                       "Node %d AnonPages:      %8lu kB\n"
+                      "Node %d KernelStack:    %8lu kB\n"
                       "Node %d PageTables:     %8lu kB\n"
                       "Node %d NFS_Unstable:   %8lu kB\n"
                       "Node %d Bounce:         %8lu kB\n"
@@ -116,6 +117,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
                       nid, K(node_page_state(nid, NR_FILE_PAGES)),
                       nid, K(node_page_state(nid, NR_FILE_MAPPED)),
                       nid, K(node_page_state(nid, NR_ANON_PAGES)),
+                      nid, node_page_state(nid, NR_KERNEL_STACK) *
+                               THREAD_SIZE / 1024,
                       nid, K(node_page_state(nid, NR_PAGETABLE)),
                       nid, K(node_page_state(nid, NR_UNSTABLE_NFS)),
                       nid, K(node_page_state(nid, NR_BOUNCE)),
index d5c410d47faef162d3edf1876f8582baec0936e9..1fc588f430e4b94c0f40a210fb05bc3bdf186650 100644 (file)
@@ -84,6 +84,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
                "Slab:           %8lu kB\n"
                "SReclaimable:   %8lu kB\n"
                "SUnreclaim:     %8lu kB\n"
+               "KernelStack:    %8lu kB\n"
                "PageTables:     %8lu kB\n"
 #ifdef CONFIG_QUICKLIST
                "Quicklists:     %8lu kB\n"
@@ -128,6 +129,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
                                global_page_state(NR_SLAB_UNRECLAIMABLE)),
                K(global_page_state(NR_SLAB_RECLAIMABLE)),
                K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
+               global_page_state(NR_KERNEL_STACK) * THREAD_SIZE / 1024,
                K(global_page_state(NR_PAGETABLE)),
 #ifdef CONFIG_QUICKLIST
                K(quicklist_total_size()),
index 889598537370b6f1de72e672efd55b6f3db1b377..d9335b8de84af682850910fa399acfeb3159e89b 100644 (file)
@@ -94,10 +94,11 @@ enum zone_stat_item {
        NR_SLAB_RECLAIMABLE,
        NR_SLAB_UNRECLAIMABLE,
        NR_PAGETABLE,           /* used for pagetables */
+       NR_KERNEL_STACK,
+       /* Second 128 byte cacheline */
        NR_UNSTABLE_NFS,        /* NFS unstable pages */
        NR_BOUNCE,
        NR_VMSCAN_WRITE,
-       /* Second 128 byte cacheline */
        NR_WRITEBACK_TEMP,      /* Writeback using temporary buffers */
 #ifdef CONFIG_NUMA
        NUMA_HIT,               /* allocated in intended node */
index 2cebfb23b0b886afc46f5ad255d77735ca674383..d4638c8cc19ecf7e4d5b440dd83bb261ce3e8518 100644 (file)
@@ -136,9 +136,17 @@ struct kmem_cache *vm_area_cachep;
 /* SLAB cache for mm_struct structures (tsk->mm) */
 static struct kmem_cache *mm_cachep;
 
+static void account_kernel_stack(struct thread_info *ti, int account)
+{
+       struct zone *zone = page_zone(virt_to_page(ti));
+
+       mod_zone_page_state(zone, NR_KERNEL_STACK, account);
+}
+
 void free_task(struct task_struct *tsk)
 {
        prop_local_destroy_single(&tsk->dirties);
+       account_kernel_stack(tsk->stack, -1);
        free_thread_info(tsk->stack);
        rt_mutex_debug_task_free(tsk);
        ftrace_graph_exit_task(tsk);
@@ -253,6 +261,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
        tsk->btrace_seq = 0;
 #endif
        tsk->splice_pipe = NULL;
+
+       account_kernel_stack(ti, 1);
+
        return tsk;
 
 out:
index 494c09196c30a07ca6b690844933a3d7a5b1a41c..4e050f325ebd8ca1ed49362d390e747ea02bd6f0 100644 (file)
@@ -2177,6 +2177,7 @@ void show_free_areas(void)
                        " mapped:%lukB"
                        " slab_reclaimable:%lukB"
                        " slab_unreclaimable:%lukB"
+                       " kernel_stack:%lukB"
                        " pagetables:%lukB"
                        " unstable:%lukB"
                        " bounce:%lukB"
@@ -2201,6 +2202,8 @@ void show_free_areas(void)
                        K(zone_page_state(zone, NR_FILE_MAPPED)),
                        K(zone_page_state(zone, NR_SLAB_RECLAIMABLE)),
                        K(zone_page_state(zone, NR_SLAB_UNRECLAIMABLE)),
+                       zone_page_state(zone, NR_KERNEL_STACK) *
+                               THREAD_SIZE / 1024,
                        K(zone_page_state(zone, NR_PAGETABLE)),
                        K(zone_page_state(zone, NR_UNSTABLE_NFS)),
                        K(zone_page_state(zone, NR_BOUNCE)),
index 138bed53706ed325e2d4aac3ae0065cffccdda47..ceda39b63d7ea37c6e0e3fa3bf7fef3457627684 100644 (file)
@@ -639,6 +639,7 @@ static const char * const vmstat_text[] = {
        "nr_slab_reclaimable",
        "nr_slab_unreclaimable",
        "nr_page_table_pages",
+       "nr_kernel_stack",
        "nr_unstable",
        "nr_bounce",
        "nr_vmscan_write",