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
Unified · Split
| @@ -90,7 +90,7 @@ suffix-$(CONFIG_KERNEL_LZO) := lzo · 89 unmodified lines | ||
| 90 | 90 | suffix-$(CONFIG_KERNEL_LZ4) := lz4 |
| 91 | 91 | |
| 92 | 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 | 94 | quiet_cmd_mkpiggy = MKPIGGY $@ |
| 95 | 95 | cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false ) |
| 96 | 96 | |
| @@ -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); | |
| @@ -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 | |
| @@ -832,6 +832,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); · 831 unmodified lines | ||
| 832 | 832 | static const struct platform_device_id s5m_rtc_id[] = { |
| 833 | 833 | { "s5m-rtc", S5M8767X }, |
| 834 | 834 | { "s2mps14-rtc", S2MPS14X }, |
| 835 | + { }, | |
| 835 | 836 | }; |
| 836 | 837 | |
| 837 | 838 | static struct platform_driver s5m_rtc_driver = { |
| @@ -85,11 +85,6 @@ static inline void oom_killer_enable(void) · 84 unmodified lines | ||
| 85 | 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 | 88 | extern struct task_struct *find_lock_task_mm(struct task_struct *p); |
| 94 | 89 | |
| 95 | 90 | static inline bool task_will_free_mem(struct task_struct *task) |
| @@ -10,9 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | extern const char linux_banner[]; |
| 11 | 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 | 13 | static inline int printk_get_level(const char *buffer) |
| 17 | 14 | { |
| 18 | 15 | if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { |
| @@ -163,6 +160,8 @@ extern int kptr_restrict; · 144 unmodified lines | ||
| 163 | 160 | |
| 164 | 161 | extern void wake_up_klogd(void); |
| 165 | 162 | |
| 163 | +char *log_buf_addr_get(void); | |
| 164 | +u32 log_buf_len_get(void); | |
| 166 | 165 | void log_buf_kexec_setup(void); |
| 167 | 166 | void __init setup_log_buf(int early); |
| 168 | 167 | void dump_stack_set_arch_desc(const char *fmt, ...); |
| @@ -198,6 +197,16 @@ static inline void wake_up_klogd(void) · 29 unmodified lines | ||
| 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 | 210 | static inline void log_buf_kexec_setup(void) |
| 202 | 211 | { |
| 203 | 212 | } |
| @@ -1477,9 +1477,9 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p) · 1476 unmodified lines | ||
| 1477 | 1477 | |
| 1478 | 1478 | pr_info("Task in "); |
| 1479 | 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 | 1481 | pr_cont_cgroup_path(memcg->css.cgroup); |
| 1482 | − pr_info("\n"); | |
| 1482 | + pr_cont("\n"); | |
| 1483 | 1483 | |
| 1484 | 1484 | rcu_read_unlock(); |
| 1485 | 1485 | |
| @@ -2332,12 +2332,21 @@ static inline struct page * · 2331 unmodified lines | ||
| 2332 | 2332 | __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, |
| 2333 | 2333 | struct zonelist *zonelist, enum zone_type high_zoneidx, |
| 2334 | 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 | 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 | 2348 | if (!oom_zonelist_trylock(zonelist, gfp_mask)) { |
| 2349 | + *did_some_progress = 1; | |
| 2341 | 2350 | schedule_timeout_uninterruptible(1); |
| 2342 | 2351 | return NULL; |
| 2343 | 2352 | } |
| @@ -2363,12 +2372,18 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order, · 19 unmodified lines | ||
| 2363 | 2372 | goto out; |
| 2364 | 2373 | |
| 2365 | 2374 | if (!(gfp_mask & __GFP_NOFAIL)) { |
| 2375 | + /* Coredumps can quickly deplete all memory reserves */ | |
| 2376 | + if (current->flags & PF_DUMPCORE) | |
| 2377 | + goto out; | |
| 2366 | 2378 | /* The OOM killer will not help higher order allocs */ |
| 2367 | 2379 | if (order > PAGE_ALLOC_COSTLY_ORDER) |
| 2368 | 2380 | goto out; |
| 2369 | 2381 | /* The OOM killer does not needlessly kill tasks for lowmem */ |
| 2370 | 2382 | if (high_zoneidx < ZONE_NORMAL) |
| 2371 | 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 | 2388 | * GFP_THISNODE contains __GFP_NORETRY and we never hit this. |
| 2374 | 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, · 6 unmodified lines | ||
| 2381 | 2396 | } |
| 2382 | 2397 | /* Exhausted what can be done so it's blamo time */ |
| 2383 | 2398 | out_of_memory(zonelist, gfp_mask, order, nodemask, false); |
| 2384 | − | |
| 2399 | + *did_some_progress = 1; | |
| 2385 | 2400 | out: |
| 2386 | 2401 | oom_zonelist_unlock(zonelist, gfp_mask); |
| 2387 | 2402 | return page; |
| @@ -2658,7 +2673,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, · 270 unmodified lines | ||
| 2658 | 2673 | (gfp_mask & GFP_THISNODE) == GFP_THISNODE) |
| 2659 | 2674 | goto nopage; |
| 2660 | 2675 | |
| 2661 | −restart: | |
| 2676 | +retry: | |
| 2662 | 2677 | if (!(gfp_mask & __GFP_NO_KSWAPD)) |
| 2663 | 2678 | wake_all_kswapds(order, zonelist, high_zoneidx, |
| 2664 | 2679 | preferred_zone, nodemask); |
| @@ -2681,7 +2696,6 @@ restart: · 16 unmodified lines | ||
| 2681 | 2696 | classzone_idx = zonelist_zone_idx(preferred_zoneref); |
| 2682 | 2697 | } |
| 2683 | 2698 | |
| 2684 | −rebalance: | |
| 2685 | 2699 | /* This is the last chance, in general, before the goto nopage. */ |
| 2686 | 2700 | page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist, |
| 2687 | 2701 | high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS, |
| @@ -2788,54 +2802,28 @@ rebalance: · 100 unmodified lines | ||
| 2788 | 2802 | if (page) |
| 2789 | 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 | 2805 | /* Check if we should retry the allocation */ |
| 2833 | 2806 | pages_reclaimed += did_some_progress; |
| 2834 | 2807 | if (should_alloc_retry(gfp_mask, order, did_some_progress, |
| 2835 | 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 | 2824 | /* Wait for some write requests to complete then retry */ |
| 2837 | 2825 | wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50); |
| 2838 | − goto rebalance; | |
| 2826 | + goto retry; | |
| 2839 | 2827 | } else { |
| 2840 | 2828 | /* |
| 2841 | 2829 | * High-order allocations do not necessarily loop after |
| @@ -2656,7 +2656,7 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist, · 2655 unmodified lines | ||
| 2656 | 2656 | * should make reasonable progress. |
| 2657 | 2657 | */ |
| 2658 | 2658 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
| 2659 | − gfp_mask, nodemask) { | |
| 2659 | + gfp_zone(gfp_mask), nodemask) { | |
| 2660 | 2660 | if (zone_idx(zone) > ZONE_NORMAL) |
| 2661 | 2661 | continue; |
| 2662 | 2662 | |