![David Rientjes](/assets/img/avatar_default.png)
The oom killer is extremely verbose for machines with a large number of cpus and/or nodes. This verbosity can often be harmful if it causes other important messages to be scrolled from the kernel log and incurs a signicant time delay, specifically for kernels with CONFIG_NODES_SHIFT > 8. This patch causes only memory information to be displayed for nodes that are allowed by current's cpuset when dumping the VM state. Information for all other nodes is irrelevant to the oom condition; we don't care if there's an abundance of memory elsewhere if we can't access it. This only affects the behavior of dumping memory information when an oom is triggered. Other dumps, such as for sysrq+m, still display the unfiltered form when using the existing show_mem() interface. Additionally, the per-cpu pageset statistics are extremely verbose in oom killer output, so it is now suppressed. This removes nodes_weight(current->mems_allowed) * (1 + nr_cpus) lines from the oom killer output. Callers may use __show_mem(SHOW_MEM_FILTER_NODES) to filter disallowed nodes. Signed-off-by: David Rientjes <rientjes@google.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
69 lines
1.4 KiB
C
69 lines
1.4 KiB
C
/*
|
|
* Generic show_mem() implementation
|
|
*
|
|
* Copyright (C) 2008 Johannes Weiner <hannes@saeurebad.de>
|
|
* All code subject to the GPL version 2.
|
|
*/
|
|
|
|
#include <linux/mm.h>
|
|
#include <linux/nmi.h>
|
|
#include <linux/quicklist.h>
|
|
|
|
void __show_mem(unsigned int filter)
|
|
{
|
|
pg_data_t *pgdat;
|
|
unsigned long total = 0, reserved = 0, shared = 0,
|
|
nonshared = 0, highmem = 0;
|
|
|
|
printk("Mem-Info:\n");
|
|
__show_free_areas(filter);
|
|
|
|
for_each_online_pgdat(pgdat) {
|
|
unsigned long i, flags;
|
|
|
|
pgdat_resize_lock(pgdat, &flags);
|
|
for (i = 0; i < pgdat->node_spanned_pages; i++) {
|
|
struct page *page;
|
|
unsigned long pfn = pgdat->node_start_pfn + i;
|
|
|
|
if (unlikely(!(i % MAX_ORDER_NR_PAGES)))
|
|
touch_nmi_watchdog();
|
|
|
|
if (!pfn_valid(pfn))
|
|
continue;
|
|
|
|
page = pfn_to_page(pfn);
|
|
|
|
if (PageHighMem(page))
|
|
highmem++;
|
|
|
|
if (PageReserved(page))
|
|
reserved++;
|
|
else if (page_count(page) == 1)
|
|
nonshared++;
|
|
else if (page_count(page) > 1)
|
|
shared += page_count(page) - 1;
|
|
|
|
total++;
|
|
}
|
|
pgdat_resize_unlock(pgdat, &flags);
|
|
}
|
|
|
|
printk("%lu pages RAM\n", total);
|
|
#ifdef CONFIG_HIGHMEM
|
|
printk("%lu pages HighMem\n", highmem);
|
|
#endif
|
|
printk("%lu pages reserved\n", reserved);
|
|
printk("%lu pages shared\n", shared);
|
|
printk("%lu pages non-shared\n", nonshared);
|
|
#ifdef CONFIG_QUICKLIST
|
|
printk("%lu pages in pagetable cache\n",
|
|
quicklist_total_size());
|
|
#endif
|
|
}
|
|
|
|
void show_mem(void)
|
|
{
|
|
__show_mem(0);
|
|
}
|