diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-26 19:25:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-26 19:25:42 -0500 |
commit | 4adca1cbc4cedb31aba03497b3de238ea13b566a (patch) | |
tree | 7f5e26da972eb9a5653f9c87cb9db471200702bf | |
parent | c976a67b02821d324f5e9fffe87e807364fe1a0e (diff) | |
parent | 45cd15e600ec8006305ce83f62c7208c2cb7a052 (diff) |
Merge branch 'akpm' (patches from Andrew Morton)
Merge misc fixes from Andrew Morton:
"Six fixes"
* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
drivers/rtc/rtc-s5m.c: terminate s5m_rtc_id array with empty element
printk: add dummy routine for when CONFIG_PRINTK=n
mm/vmscan: fix highidx argument type
memcg: remove extra newlines from memcg oom kill log
x86, build: replace Perl script with Shell script
mm: page_alloc: embed OOM killing naturally into allocation slowpath
-rw-r--r-- | arch/x86/boot/compressed/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/tools/calc_run_size.pl | 39 | ||||
-rw-r--r-- | arch/x86/tools/calc_run_size.sh | 42 | ||||
-rw-r--r-- | drivers/rtc/rtc-s5m.c | 1 | ||||
-rw-r--r-- | include/linux/oom.h | 5 | ||||
-rw-r--r-- | include/linux/printk.h | 15 | ||||
-rw-r--r-- | mm/memcontrol.c | 4 | ||||
-rw-r--r-- | mm/page_alloc.c | 82 | ||||
-rw-r--r-- | mm/vmscan.c | 2 |
9 files changed, 94 insertions, 98 deletions
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index d999398928bc..ad754b4411f7 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
@@ -90,7 +90,7 @@ suffix-$(CONFIG_KERNEL_LZO) := lzo | |||
90 | suffix-$(CONFIG_KERNEL_LZ4) := lz4 | 90 | suffix-$(CONFIG_KERNEL_LZ4) := lz4 |
91 | 91 | ||
92 | RUN_SIZE = $(shell $(OBJDUMP) -h vmlinux | \ | 92 | RUN_SIZE = $(shell $(OBJDUMP) -h vmlinux | \ |
93 | perl $(srctree)/arch/x86/tools/calc_run_size.pl) | 93 | $(CONFIG_SHELL) $(srctree)/arch/x86/tools/calc_run_size.sh) |
94 | quiet_cmd_mkpiggy = MKPIGGY $@ | 94 | quiet_cmd_mkpiggy = MKPIGGY $@ |
95 | cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) | 95 | cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) |
96 | 96 | ||
diff --git a/arch/x86/tools/calc_run_size.pl b/arch/x86/tools/calc_run_size.pl deleted file mode 100644 index 23210baade2d..000000000000 --- a/arch/x86/tools/calc_run_size.pl +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | #!/usr/bin/perl | ||
2 | # | ||
3 | # Calculate the amount of space needed to run the kernel, including room for | ||
4 | # the .bss and .brk sections. | ||
5 | # | ||
6 | # Usage: | ||
7 | # objdump -h a.out | perl calc_run_size.pl | ||
8 | use strict; | ||
9 | |||
10 | my $mem_size = 0; | ||
11 | my $file_offset = 0; | ||
12 | |||
13 | my $sections=" *[0-9]+ \.(?:bss|brk) +"; | ||
14 | while (<>) { | ||
15 | if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) { | ||
16 | my $size = hex($1); | ||
17 | my $offset = hex($2); | ||
18 | $mem_size += $size; | ||
19 | if ($file_offset == 0) { | ||
20 | $file_offset = $offset; | ||
21 | } elsif ($file_offset != $offset) { | ||
22 | # BFD linker shows the same file offset in ELF. | ||
23 | # Gold linker shows them as consecutive. | ||
24 | next if ($file_offset + $mem_size == $offset + $size); | ||
25 | |||
26 | printf STDERR "file_offset: 0x%lx\n", $file_offset; | ||
27 | printf STDERR "mem_size: 0x%lx\n", $mem_size; | ||
28 | printf STDERR "offset: 0x%lx\n", $offset; | ||
29 | printf STDERR "size: 0x%lx\n", $size; | ||
30 | |||
31 | die ".bss and .brk are non-contiguous\n"; | ||
32 | } | ||
33 | } | ||
34 | } | ||
35 | |||
36 | if ($file_offset == 0) { | ||
37 | die "Never found .bss or .brk file offset\n"; | ||
38 | } | ||
39 | printf("%d\n", $mem_size + $file_offset); | ||
diff --git a/arch/x86/tools/calc_run_size.sh b/arch/x86/tools/calc_run_size.sh new file mode 100644 index 000000000000..1a4c17bb3910 --- /dev/null +++ b/arch/x86/tools/calc_run_size.sh | |||
@@ -0,0 +1,42 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # Calculate the amount of space needed to run the kernel, including room for | ||
4 | # the .bss and .brk sections. | ||
5 | # | ||
6 | # Usage: | ||
7 | # objdump -h a.out | sh calc_run_size.sh | ||
8 | |||
9 | NUM='\([0-9a-fA-F]*[ \t]*\)' | ||
10 | OUT=$(sed -n 's/^[ \t0-9]*.b[sr][sk][ \t]*'"$NUM$NUM$NUM$NUM"'.*/\1\4/p') | ||
11 | if [ -z "$OUT" ] ; then | ||
12 | echo "Never found .bss or .brk file offset" >&2 | ||
13 | exit 1 | ||
14 | fi | ||
15 | |||
16 | OUT=$(echo ${OUT# }) | ||
17 | sizeA=$(printf "%d" 0x${OUT%% *}) | ||
18 | OUT=${OUT#* } | ||
19 | offsetA=$(printf "%d" 0x${OUT%% *}) | ||
20 | OUT=${OUT#* } | ||
21 | sizeB=$(printf "%d" 0x${OUT%% *}) | ||
22 | OUT=${OUT#* } | ||
23 | offsetB=$(printf "%d" 0x${OUT%% *}) | ||
24 | |||
25 | run_size=$(( $offsetA + $sizeA + $sizeB )) | ||
26 | |||
27 | # BFD linker shows the same file offset in ELF. | ||
28 | if [ "$offsetA" -ne "$offsetB" ] ; then | ||
29 | # Gold linker shows them as consecutive. | ||
30 | endB=$(( $offsetB + $sizeB )) | ||
31 | if [ "$endB" != "$run_size" ] ; then | ||
32 | printf "sizeA: 0x%x\n" $sizeA >&2 | ||
33 | printf "offsetA: 0x%x\n" $offsetA >&2 | ||
34 | printf "sizeB: 0x%x\n" $sizeB >&2 | ||
35 | printf "offsetB: 0x%x\n" $offsetB >&2 | ||
36 | echo ".bss and .brk are non-contiguous" >&2 | ||
37 | exit 1 | ||
38 | fi | ||
39 | fi | ||
40 | |||
41 | printf "%d\n" $run_size | ||
42 | exit 0 | ||
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index b5e7c4670205..89ac1d5083c6 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c | |||
@@ -832,6 +832,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); | |||
832 | static const struct platform_device_id s5m_rtc_id[] = { | 832 | static const struct platform_device_id s5m_rtc_id[] = { |
833 | { "s5m-rtc", S5M8767X }, | 833 | { "s5m-rtc", S5M8767X }, |
834 | { "s2mps14-rtc", S2MPS14X }, | 834 | { "s2mps14-rtc", S2MPS14X }, |
835 | { }, | ||
835 | }; | 836 | }; |
836 | 837 | ||
837 | static struct platform_driver s5m_rtc_driver = { | 838 | static struct platform_driver s5m_rtc_driver = { |
diff --git a/include/linux/oom.h b/include/linux/oom.h index 853698c721f7..76200984d1e2 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h | |||
@@ -85,11 +85,6 @@ static inline void oom_killer_enable(void) | |||
85 | oom_killer_disabled = false; | 85 | oom_killer_disabled = false; |
86 | } | 86 | } |
87 | 87 | ||
88 | static inline bool oom_gfp_allowed(gfp_t gfp_mask) | ||
89 | { | ||
90 | return (gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY); | ||
91 | } | ||
92 | |||
93 | extern struct task_struct *find_lock_task_mm(struct task_struct *p); | 88 | extern struct task_struct *find_lock_task_mm(struct task_struct *p); |
94 | 89 | ||
95 | static inline bool task_will_free_mem(struct task_struct *task) | 90 | static inline bool task_will_free_mem(struct task_struct *task) |
diff --git a/include/linux/printk.h b/include/linux/printk.h index c8f170324e64..4d5bf5726578 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h | |||
@@ -10,9 +10,6 @@ | |||
10 | extern const char linux_banner[]; | 10 | extern const char linux_banner[]; |
11 | extern const char linux_proc_banner[]; | 11 | extern const char linux_proc_banner[]; |
12 | 12 | ||
13 | extern char *log_buf_addr_get(void); | ||
14 | extern u32 log_buf_len_get(void); | ||
15 | |||
16 | static inline int printk_get_level(const char *buffer) | 13 | static inline int printk_get_level(const char *buffer) |
17 | { | 14 | { |
18 | if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { | 15 | if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { |
@@ -163,6 +160,8 @@ extern int kptr_restrict; | |||
163 | 160 | ||
164 | extern void wake_up_klogd(void); | 161 | extern void wake_up_klogd(void); |
165 | 162 | ||
163 | char *log_buf_addr_get(void); | ||
164 | u32 log_buf_len_get(void); | ||
166 | void log_buf_kexec_setup(void); | 165 | void log_buf_kexec_setup(void); |
167 | void __init setup_log_buf(int early); | 166 | void __init setup_log_buf(int early); |
168 | void dump_stack_set_arch_desc(const char *fmt, ...); | 167 | void dump_stack_set_arch_desc(const char *fmt, ...); |
@@ -198,6 +197,16 @@ static inline void wake_up_klogd(void) | |||
198 | { | 197 | { |
199 | } | 198 | } |
200 | 199 | ||
200 | static inline char *log_buf_addr_get(void) | ||
201 | { | ||
202 | return NULL; | ||
203 | } | ||
204 | |||
205 | static inline u32 log_buf_len_get(void) | ||
206 | { | ||
207 | return 0; | ||
208 | } | ||
209 | |||
201 | static inline void log_buf_kexec_setup(void) | 210 | static inline void log_buf_kexec_setup(void) |
202 | { | 211 | { |
203 | } | 212 | } |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 851924fa5170..683b4782019b 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1477,9 +1477,9 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) | |||
1477 | 1477 | ||
1478 | pr_info("Task in "); | 1478 | pr_info("Task in "); |
1479 | pr_cont_cgroup_path(task_cgroup(p, memory_cgrp_id)); | 1479 | pr_cont_cgroup_path(task_cgroup(p, memory_cgrp_id)); |
1480 | pr_info(" killed as a result of limit of "); | 1480 | pr_cont(" killed as a result of limit of "); |
1481 | pr_cont_cgroup_path(memcg->css.cgroup); | 1481 | pr_cont_cgroup_path(memcg->css.cgroup); |
1482 | pr_info("\n"); | 1482 | pr_cont("\n"); |
1483 | 1483 | ||
1484 | rcu_read_unlock(); | 1484 | rcu_read_unlock(); |
1485 | 1485 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7633c503a116..8e20f9c2fa5a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2332,12 +2332,21 @@ static inline struct page * | |||
2332 | __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, | 2332 | __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, |
2333 | struct zonelist *zonelist, enum zone_type high_zoneidx, | 2333 | struct zonelist *zonelist, enum zone_type high_zoneidx, |
2334 | nodemask_t *nodemask, struct zone *preferred_zone, | 2334 | nodemask_t *nodemask, struct zone *preferred_zone, |
2335 | int classzone_idx, int migratetype) | 2335 | int classzone_idx, int migratetype, unsigned long *did_some_progress) |
2336 | { | 2336 | { |
2337 | struct page *page; | 2337 | struct page *page; |
2338 | 2338 | ||
2339 | /* Acquire the per-zone oom lock for each zone */ | 2339 | *did_some_progress = 0; |
2340 | |||
2341 | if (oom_killer_disabled) | ||
2342 | return NULL; | ||
2343 | |||
2344 | /* | ||
2345 | * Acquire the per-zone oom lock for each zone. If that | ||
2346 | * fails, somebody else is making progress for us. | ||
2347 | */ | ||
2340 | if (!oom_zonelist_trylock(zonelist, gfp_mask)) { | 2348 | if (!oom_zonelist_trylock(zonelist, gfp_mask)) { |
2349 | *did_some_progress = 1; | ||
2341 | schedule_timeout_uninterruptible(1); | 2350 | schedule_timeout_uninterruptible(1); |
2342 | return NULL; | 2351 | return NULL; |
2343 | } | 2352 | } |
@@ -2363,12 +2372,18 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, | |||
2363 | goto out; | 2372 | goto out; |
2364 | 2373 | ||
2365 | if (!(gfp_mask & __GFP_NOFAIL)) { | 2374 | if (!(gfp_mask & __GFP_NOFAIL)) { |
2375 | /* Coredumps can quickly deplete all memory reserves */ | ||
2376 | if (current->flags & PF_DUMPCORE) | ||
2377 | goto out; | ||
2366 | /* The OOM killer will not help higher order allocs */ | 2378 | /* The OOM killer will not help higher order allocs */ |
2367 | if (order > PAGE_ALLOC_COSTLY_ORDER) | 2379 | if (order > PAGE_ALLOC_COSTLY_ORDER) |
2368 | goto out; | 2380 | goto out; |
2369 | /* The OOM killer does not needlessly kill tasks for lowmem */ | 2381 | /* The OOM killer does not needlessly kill tasks for lowmem */ |
2370 | if (high_zoneidx < ZONE_NORMAL) | 2382 | if (high_zoneidx < ZONE_NORMAL) |
2371 | goto out; | 2383 | goto out; |
2384 | /* The OOM killer does not compensate for light reclaim */ | ||
2385 | if (!(gfp_mask & __GFP_FS)) | ||
2386 | goto out; | ||
2372 | /* | 2387 | /* |
2373 | * GFP_THISNODE contains __GFP_NORETRY and we never hit this. | 2388 | * GFP_THISNODE contains __GFP_NORETRY and we never hit this. |
2374 | * Sanity check for bare calls of __GFP_THISNODE, not real OOM. | 2389 | * Sanity check for bare calls of __GFP_THISNODE, not real OOM. |
@@ -2381,7 +2396,7 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, | |||
2381 | } | 2396 | } |
2382 | /* Exhausted what can be done so it's blamo time */ | 2397 | /* Exhausted what can be done so it's blamo time */ |
2383 | out_of_memory(zonelist, gfp_mask, order, nodemask, false); | 2398 | out_of_memory(zonelist, gfp_mask, order, nodemask, false); |
2384 | 2399 | *did_some_progress = 1; | |
2385 | out: | 2400 | out: |
2386 | oom_zonelist_unlock(zonelist, gfp_mask); | 2401 | oom_zonelist_unlock(zonelist, gfp_mask); |
2387 | return page; | 2402 | return page; |
@@ -2658,7 +2673,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, | |||
2658 | (gfp_mask & GFP_THISNODE) == GFP_THISNODE) | 2673 | (gfp_mask & GFP_THISNODE) == GFP_THISNODE) |
2659 | goto nopage; | 2674 | goto nopage; |
2660 | 2675 | ||
2661 | restart: | 2676 | retry: |
2662 | if (!(gfp_mask & __GFP_NO_KSWAPD)) | 2677 | if (!(gfp_mask & __GFP_NO_KSWAPD)) |
2663 | wake_all_kswapds(order, zonelist, high_zoneidx, | 2678 | wake_all_kswapds(order, zonelist, high_zoneidx, |
2664 | preferred_zone, nodemask); | 2679 | preferred_zone, nodemask); |
@@ -2681,7 +2696,6 @@ restart: | |||
2681 | classzone_idx = zonelist_zone_idx(preferred_zoneref); | 2696 | classzone_idx = zonelist_zone_idx(preferred_zoneref); |
2682 | } | 2697 | } |
2683 | 2698 | ||
2684 | rebalance: | ||
2685 | /* This is the last chance, in general, before the goto nopage. */ | 2699 | /* This is the last chance, in general, before the goto nopage. */ |
2686 | page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, | 2700 | page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, |
2687 | high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, | 2701 | high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, |
@@ -2788,54 +2802,28 @@ rebalance: | |||
2788 | if (page) | 2802 | if (page) |
2789 | goto got_pg; | 2803 | goto got_pg; |
2790 | 2804 | ||
2791 | /* | ||
2792 | * If we failed to make any progress reclaiming, then we are | ||
2793 | * running out of options and have to consider going OOM | ||
2794 | */ | ||
2795 | if (!did_some_progress) { | ||
2796 | if (oom_gfp_allowed(gfp_mask)) { | ||
2797 | if (oom_killer_disabled) | ||
2798 | goto nopage; | ||
2799 | /* Coredumps can quickly deplete all memory reserves */ | ||
2800 | if ((current->flags & PF_DUMPCORE) && | ||
2801 | !(gfp_mask & __GFP_NOFAIL)) | ||
2802 | goto nopage; | ||
2803 | page = __alloc_pages_may_oom(gfp_mask, order, | ||
2804 | zonelist, high_zoneidx, | ||
2805 | nodemask, preferred_zone, | ||
2806 | classzone_idx, migratetype); | ||
2807 | if (page) | ||
2808 | goto got_pg; | ||
2809 | |||
2810 | if (!(gfp_mask & __GFP_NOFAIL)) { | ||
2811 | /* | ||
2812 | * The oom killer is not called for high-order | ||
2813 | * allocations that may fail, so if no progress | ||
2814 | * is being made, there are no other options and | ||
2815 | * retrying is unlikely to help. | ||
2816 | */ | ||
2817 | if (order > PAGE_ALLOC_COSTLY_ORDER) | ||
2818 | goto nopage; | ||
2819 | /* | ||
2820 | * The oom killer is not called for lowmem | ||
2821 | * allocations to prevent needlessly killing | ||
2822 | * innocent tasks. | ||
2823 | */ | ||
2824 | if (high_zoneidx < ZONE_NORMAL) | ||
2825 | goto nopage; | ||
2826 | } | ||
2827 | |||
2828 | goto restart; | ||
2829 | } | ||
2830 | } | ||
2831 | |||
2832 | /* Check if we should retry the allocation */ | 2805 | /* Check if we should retry the allocation */ |
2833 | pages_reclaimed += did_some_progress; | 2806 | pages_reclaimed += did_some_progress; |
2834 | if (should_alloc_retry(gfp_mask, order, did_some_progress, | 2807 | if (should_alloc_retry(gfp_mask, order, did_some_progress, |
2835 | pages_reclaimed)) { | 2808 | pages_reclaimed)) { |
2809 | /* | ||
2810 | * If we fail to make progress by freeing individual | ||
2811 | * pages, but the allocation wants us to keep going, | ||
2812 | * start OOM killing tasks. | ||
2813 | */ | ||
2814 | if (!did_some_progress) { | ||
2815 | page = __alloc_pages_may_oom(gfp_mask, order, zonelist, | ||
2816 | high_zoneidx, nodemask, | ||
2817 | preferred_zone, classzone_idx, | ||
2818 | migratetype,&did_some_progress); | ||
2819 | if (page) | ||
2820 | goto got_pg; | ||
2821 | if (!did_some_progress) | ||
2822 | goto nopage; | ||
2823 | } | ||
2836 | /* Wait for some write requests to complete then retry */ | 2824 | /* Wait for some write requests to complete then retry */ |
2837 | wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50); | 2825 | wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50); |
2838 | goto rebalance; | 2826 | goto retry; |
2839 | } else { | 2827 | } else { |
2840 | /* | 2828 | /* |
2841 | * High-order allocations do not necessarily loop after | 2829 | * High-order allocations do not necessarily loop after |
diff --git a/mm/vmscan.c b/mm/vmscan.c index ab2505c3ef54..dcd90c891d8e 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -2656,7 +2656,7 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, | |||
2656 | * should make reasonable progress. | 2656 | * should make reasonable progress. |
2657 | */ | 2657 | */ |
2658 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 2658 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
2659 | gfp_mask, nodemask) { | 2659 | gfp_zone(gfp_mask), nodemask) { |
2660 | if (zone_idx(zone) > ZONE_NORMAL) | 2660 | if (zone_idx(zone) > ZONE_NORMAL) |
2661 | continue; | 2661 | continue; |
2662 | 2662 | ||