Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6a7f572 authored by KOSAKI Motohiro's avatar KOSAKI Motohiro Committed by Linus Torvalds
Browse files

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: default avatarKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Reviewed-by: default avatarChristoph Lameter <cl@linux-foundation.org>
Reviewed-by: default avatarMinchan Kim <minchan.kim@gmail.com>
Reviewed-by: default avatarRik van Riel <riel@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 71de1ccb
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -85,6 +85,7 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
		       "Node %d FilePages:      %8lu kB\n"
		       "Node %d FilePages:      %8lu kB\n"
		       "Node %d Mapped:         %8lu kB\n"
		       "Node %d Mapped:         %8lu kB\n"
		       "Node %d AnonPages:      %8lu kB\n"
		       "Node %d AnonPages:      %8lu kB\n"
		       "Node %d KernelStack:    %8lu kB\n"
		       "Node %d PageTables:     %8lu kB\n"
		       "Node %d PageTables:     %8lu kB\n"
		       "Node %d NFS_Unstable:   %8lu kB\n"
		       "Node %d NFS_Unstable:   %8lu kB\n"
		       "Node %d Bounce:         %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_PAGES)),
		       nid, K(node_page_state(nid, NR_FILE_MAPPED)),
		       nid, K(node_page_state(nid, NR_FILE_MAPPED)),
		       nid, K(node_page_state(nid, NR_ANON_PAGES)),
		       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_PAGETABLE)),
		       nid, K(node_page_state(nid, NR_UNSTABLE_NFS)),
		       nid, K(node_page_state(nid, NR_UNSTABLE_NFS)),
		       nid, K(node_page_state(nid, NR_BOUNCE)),
		       nid, K(node_page_state(nid, NR_BOUNCE)),
+2 −0
Original line number Original line Diff line number Diff line
@@ -84,6 +84,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
		"Slab:           %8lu kB\n"
		"Slab:           %8lu kB\n"
		"SReclaimable:   %8lu kB\n"
		"SReclaimable:   %8lu kB\n"
		"SUnreclaim:     %8lu kB\n"
		"SUnreclaim:     %8lu kB\n"
		"KernelStack:    %8lu kB\n"
		"PageTables:     %8lu kB\n"
		"PageTables:     %8lu kB\n"
#ifdef CONFIG_QUICKLIST
#ifdef CONFIG_QUICKLIST
		"Quicklists:     %8lu kB\n"
		"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)),
				global_page_state(NR_SLAB_UNRECLAIMABLE)),
		K(global_page_state(NR_SLAB_RECLAIMABLE)),
		K(global_page_state(NR_SLAB_RECLAIMABLE)),
		K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
		K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
		global_page_state(NR_KERNEL_STACK) * THREAD_SIZE / 1024,
		K(global_page_state(NR_PAGETABLE)),
		K(global_page_state(NR_PAGETABLE)),
#ifdef CONFIG_QUICKLIST
#ifdef CONFIG_QUICKLIST
		K(quicklist_total_size()),
		K(quicklist_total_size()),
+2 −1
Original line number Original line Diff line number Diff line
@@ -94,10 +94,11 @@ enum zone_stat_item {
	NR_SLAB_RECLAIMABLE,
	NR_SLAB_RECLAIMABLE,
	NR_SLAB_UNRECLAIMABLE,
	NR_SLAB_UNRECLAIMABLE,
	NR_PAGETABLE,		/* used for pagetables */
	NR_PAGETABLE,		/* used for pagetables */
	NR_KERNEL_STACK,
	/* Second 128 byte cacheline */
	NR_UNSTABLE_NFS,	/* NFS unstable pages */
	NR_UNSTABLE_NFS,	/* NFS unstable pages */
	NR_BOUNCE,
	NR_BOUNCE,
	NR_VMSCAN_WRITE,
	NR_VMSCAN_WRITE,
	/* Second 128 byte cacheline */
	NR_WRITEBACK_TEMP,	/* Writeback using temporary buffers */
	NR_WRITEBACK_TEMP,	/* Writeback using temporary buffers */
#ifdef CONFIG_NUMA
#ifdef CONFIG_NUMA
	NUMA_HIT,		/* allocated in intended node */
	NUMA_HIT,		/* allocated in intended node */
+11 −0
Original line number Original line Diff line number Diff line
@@ -136,9 +136,17 @@ struct kmem_cache *vm_area_cachep;
/* SLAB cache for mm_struct structures (tsk->mm) */
/* SLAB cache for mm_struct structures (tsk->mm) */
static struct kmem_cache *mm_cachep;
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)
void free_task(struct task_struct *tsk)
{
{
	prop_local_destroy_single(&tsk->dirties);
	prop_local_destroy_single(&tsk->dirties);
	account_kernel_stack(tsk->stack, -1);
	free_thread_info(tsk->stack);
	free_thread_info(tsk->stack);
	rt_mutex_debug_task_free(tsk);
	rt_mutex_debug_task_free(tsk);
	ftrace_graph_exit_task(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;
	tsk->btrace_seq = 0;
#endif
#endif
	tsk->splice_pipe = NULL;
	tsk->splice_pipe = NULL;

	account_kernel_stack(ti, 1);

	return tsk;
	return tsk;


out:
out:
+3 −0
Original line number Original line Diff line number Diff line
@@ -2177,6 +2177,7 @@ void show_free_areas(void)
			" mapped:%lukB"
			" mapped:%lukB"
			" slab_reclaimable:%lukB"
			" slab_reclaimable:%lukB"
			" slab_unreclaimable:%lukB"
			" slab_unreclaimable:%lukB"
			" kernel_stack:%lukB"
			" pagetables:%lukB"
			" pagetables:%lukB"
			" unstable:%lukB"
			" unstable:%lukB"
			" bounce:%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_FILE_MAPPED)),
			K(zone_page_state(zone, NR_SLAB_RECLAIMABLE)),
			K(zone_page_state(zone, NR_SLAB_RECLAIMABLE)),
			K(zone_page_state(zone, NR_SLAB_UNRECLAIMABLE)),
			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_PAGETABLE)),
			K(zone_page_state(zone, NR_UNSTABLE_NFS)),
			K(zone_page_state(zone, NR_UNSTABLE_NFS)),
			K(zone_page_state(zone, NR_BOUNCE)),
			K(zone_page_state(zone, NR_BOUNCE)),
Loading