aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Rientjes <rientjes@google.com>2011-03-22 19:30:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-22 20:44:01 -0400
commitddd588b5dd55f14320379961e47683db4e4c1d90 (patch)
tree09de73c51c8c5e701e644236890a5d205ec3cdc9
parent94dcf29a11b3d20a28790598d701f98484a969da (diff)
oom: suppress nodes that are not allowed from meminfo on oom kill
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>
-rw-r--r--include/linux/mm.h8
-rw-r--r--lib/show_mem.c9
-rw-r--r--mm/oom_kill.c2
-rw-r--r--mm/page_alloc.c34
4 files changed, 49 insertions, 4 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 581703d86fbd..1f82adc85352 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -859,7 +859,14 @@ extern void pagefault_out_of_memory(void);
859 859
860#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) 860#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
861 861
862/*
863 * Flags passed to __show_mem() and __show_free_areas() to suppress output in
864 * various contexts.
865 */
866#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */
867
862extern void show_free_areas(void); 868extern void show_free_areas(void);
869extern void __show_free_areas(unsigned int flags);
863 870
864int shmem_lock(struct file *file, int lock, struct user_struct *user); 871int shmem_lock(struct file *file, int lock, struct user_struct *user);
865struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags); 872struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags);
@@ -1348,6 +1355,7 @@ extern void calculate_zone_inactive_ratio(struct zone *zone);
1348extern void mem_init(void); 1355extern void mem_init(void);
1349extern void __init mmap_init(void); 1356extern void __init mmap_init(void);
1350extern void show_mem(void); 1357extern void show_mem(void);
1358extern void __show_mem(unsigned int flags);
1351extern void si_meminfo(struct sysinfo * val); 1359extern void si_meminfo(struct sysinfo * val);
1352extern void si_meminfo_node(struct sysinfo *val, int nid); 1360extern void si_meminfo_node(struct sysinfo *val, int nid);
1353extern int after_bootmem; 1361extern int after_bootmem;
diff --git a/lib/show_mem.c b/lib/show_mem.c
index fdc77c82f922..d8d602b58c31 100644
--- a/lib/show_mem.c
+++ b/lib/show_mem.c
@@ -9,14 +9,14 @@
9#include <linux/nmi.h> 9#include <linux/nmi.h>
10#include <linux/quicklist.h> 10#include <linux/quicklist.h>
11 11
12void show_mem(void) 12void __show_mem(unsigned int filter)
13{ 13{
14 pg_data_t *pgdat; 14 pg_data_t *pgdat;
15 unsigned long total = 0, reserved = 0, shared = 0, 15 unsigned long total = 0, reserved = 0, shared = 0,
16 nonshared = 0, highmem = 0; 16 nonshared = 0, highmem = 0;
17 17
18 printk("Mem-Info:\n"); 18 printk("Mem-Info:\n");
19 show_free_areas(); 19 __show_free_areas(filter);
20 20
21 for_each_online_pgdat(pgdat) { 21 for_each_online_pgdat(pgdat) {
22 unsigned long i, flags; 22 unsigned long i, flags;
@@ -61,3 +61,8 @@ void show_mem(void)
61 quicklist_total_size()); 61 quicklist_total_size());
62#endif 62#endif
63} 63}
64
65void show_mem(void)
66{
67 __show_mem(0);
68}
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 33b58615072c..3100bc57036b 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -406,7 +406,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
406 task_unlock(current); 406 task_unlock(current);
407 dump_stack(); 407 dump_stack();
408 mem_cgroup_print_oom_info(mem, p); 408 mem_cgroup_print_oom_info(mem, p);
409 show_mem(); 409 __show_mem(SHOW_MEM_FILTER_NODES);
410 if (sysctl_oom_dump_tasks) 410 if (sysctl_oom_dump_tasks)
411 dump_tasks(mem, nodemask); 411 dump_tasks(mem, nodemask);
412} 412}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 7945247b1e53..36be3ba4bbed 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2411,19 +2411,42 @@ void si_meminfo_node(struct sysinfo *val, int nid)
2411} 2411}
2412#endif 2412#endif
2413 2413
2414/*
2415 * Determine whether the zone's node should be displayed or not, depending on
2416 * whether SHOW_MEM_FILTER_NODES was passed to __show_free_areas().
2417 */
2418static bool skip_free_areas_zone(unsigned int flags, const struct zone *zone)
2419{
2420 bool ret = false;
2421
2422 if (!(flags & SHOW_MEM_FILTER_NODES))
2423 goto out;
2424
2425 get_mems_allowed();
2426 ret = !node_isset(zone->zone_pgdat->node_id,
2427 cpuset_current_mems_allowed);
2428 put_mems_allowed();
2429out:
2430 return ret;
2431}
2432
2414#define K(x) ((x) << (PAGE_SHIFT-10)) 2433#define K(x) ((x) << (PAGE_SHIFT-10))
2415 2434
2416/* 2435/*
2417 * Show free area list (used inside shift_scroll-lock stuff) 2436 * Show free area list (used inside shift_scroll-lock stuff)
2418 * We also calculate the percentage fragmentation. We do this by counting the 2437 * We also calculate the percentage fragmentation. We do this by counting the
2419 * memory on each free list with the exception of the first item on the list. 2438 * memory on each free list with the exception of the first item on the list.
2439 * Suppresses nodes that are not allowed by current's cpuset if
2440 * SHOW_MEM_FILTER_NODES is passed.
2420 */ 2441 */
2421void show_free_areas(void) 2442void __show_free_areas(unsigned int filter)
2422{ 2443{
2423 int cpu; 2444 int cpu;
2424 struct zone *zone; 2445 struct zone *zone;
2425 2446
2426 for_each_populated_zone(zone) { 2447 for_each_populated_zone(zone) {
2448 if (skip_free_areas_zone(filter, zone))
2449 continue;
2427 show_node(zone); 2450 show_node(zone);
2428 printk("%s per-cpu:\n", zone->name); 2451 printk("%s per-cpu:\n", zone->name);
2429 2452
@@ -2465,6 +2488,8 @@ void show_free_areas(void)
2465 for_each_populated_zone(zone) { 2488 for_each_populated_zone(zone) {
2466 int i; 2489 int i;
2467 2490
2491 if (skip_free_areas_zone(filter, zone))
2492 continue;
2468 show_node(zone); 2493 show_node(zone);
2469 printk("%s" 2494 printk("%s"
2470 " free:%lukB" 2495 " free:%lukB"
@@ -2532,6 +2557,8 @@ void show_free_areas(void)
2532 for_each_populated_zone(zone) { 2557 for_each_populated_zone(zone) {
2533 unsigned long nr[MAX_ORDER], flags, order, total = 0; 2558 unsigned long nr[MAX_ORDER], flags, order, total = 0;
2534 2559
2560 if (skip_free_areas_zone(filter, zone))
2561 continue;
2535 show_node(zone); 2562 show_node(zone);
2536 printk("%s: ", zone->name); 2563 printk("%s: ", zone->name);
2537 2564
@@ -2551,6 +2578,11 @@ void show_free_areas(void)
2551 show_swap_cache_info(); 2578 show_swap_cache_info();
2552} 2579}
2553 2580
2581void show_free_areas(void)
2582{
2583 __show_free_areas(0);
2584}
2585
2554static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref) 2586static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref)
2555{ 2587{
2556 zoneref->zone = zone; 2588 zoneref->zone = zone;