diff options
-rw-r--r-- | include/linux/mm.h | 8 | ||||
-rw-r--r-- | lib/show_mem.c | 9 | ||||
-rw-r--r-- | mm/oom_kill.c | 2 | ||||
-rw-r--r-- | mm/page_alloc.c | 34 |
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 | |||
862 | extern void show_free_areas(void); | 868 | extern void show_free_areas(void); |
869 | extern void __show_free_areas(unsigned int flags); | ||
863 | 870 | ||
864 | int shmem_lock(struct file *file, int lock, struct user_struct *user); | 871 | int shmem_lock(struct file *file, int lock, struct user_struct *user); |
865 | struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags); | 872 | struct 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); | |||
1348 | extern void mem_init(void); | 1355 | extern void mem_init(void); |
1349 | extern void __init mmap_init(void); | 1356 | extern void __init mmap_init(void); |
1350 | extern void show_mem(void); | 1357 | extern void show_mem(void); |
1358 | extern void __show_mem(unsigned int flags); | ||
1351 | extern void si_meminfo(struct sysinfo * val); | 1359 | extern void si_meminfo(struct sysinfo * val); |
1352 | extern void si_meminfo_node(struct sysinfo *val, int nid); | 1360 | extern void si_meminfo_node(struct sysinfo *val, int nid); |
1353 | extern int after_bootmem; | 1361 | extern 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 | ||
12 | void show_mem(void) | 12 | void __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 | |||
65 | void 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 | */ | ||
2418 | static 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(); | ||
2429 | out: | ||
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 | */ |
2421 | void show_free_areas(void) | 2442 | void __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 | ||
2581 | void show_free_areas(void) | ||
2582 | { | ||
2583 | __show_free_areas(0); | ||
2584 | } | ||
2585 | |||
2554 | static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref) | 2586 | static void zoneref_set_zone(struct zone *zone, struct zoneref *zoneref) |
2555 | { | 2587 | { |
2556 | zoneref->zone = zone; | 2588 | zoneref->zone = zone; |