diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2015-06-24 19:58:51 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-07-21 13:10:03 -0400 |
commit | 03445a4c2324f4adddd6b6c9b92879c1c754238a (patch) | |
tree | 691e794f2d8b6dd859b5c061735f13d5c12cde4e /mm/kmemleak.c | |
parent | 3baf726f001b69454f3eb18a589c508992622be9 (diff) |
mm: kmemleak_alloc_percpu() should follow the gfp from per_alloc()
commit 8a8c35fadfaf55629a37ef1a8ead1b8fb32581d2 upstream.
Beginning at commit d52d3997f843 ("ipv6: Create percpu rt6_info"), the
following INFO splat is logged:
===============================
[ INFO: suspicious RCU usage. ]
4.1.0-rc7-next-20150612 #1 Not tainted
-------------------------------
kernel/sched/core.c:7318 Illegal context switch in RCU-bh read-side critical section!
other info that might help us debug this:
rcu_scheduler_active = 1, debug_locks = 0
3 locks held by systemd/1:
#0: (rtnl_mutex){+.+.+.}, at: [<ffffffff815f0c8f>] rtnetlink_rcv+0x1f/0x40
#1: (rcu_read_lock_bh){......}, at: [<ffffffff816a34e2>] ipv6_add_addr+0x62/0x540
#2: (addrconf_hash_lock){+...+.}, at: [<ffffffff816a3604>] ipv6_add_addr+0x184/0x540
stack backtrace:
CPU: 0 PID: 1 Comm: systemd Not tainted 4.1.0-rc7-next-20150612 #1
Hardware name: TOSHIBA TECRA A50-A/TECRA A50-A, BIOS Version 4.20 04/17/2014
Call Trace:
dump_stack+0x4c/0x6e
lockdep_rcu_suspicious+0xe7/0x120
___might_sleep+0x1d5/0x1f0
__might_sleep+0x4d/0x90
kmem_cache_alloc+0x47/0x250
create_object+0x39/0x2e0
kmemleak_alloc_percpu+0x61/0xe0
pcpu_alloc+0x370/0x630
Additional backtrace lines are truncated. In addition, the above splat
is followed by several "BUG: sleeping function called from invalid
context at mm/slub.c:1268" outputs. As suggested by Martin KaFai Lau,
these are the clue to the fix. Routine kmemleak_alloc_percpu() always
uses GFP_KERNEL for its allocations, whereas it should follow the gfp
from its callers.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux-foundation.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'mm/kmemleak.c')
-rw-r--r-- | mm/kmemleak.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 41df5b8efd25..3716cdb8ba42 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
@@ -909,12 +909,13 @@ EXPORT_SYMBOL_GPL(kmemleak_alloc); | |||
909 | * kmemleak_alloc_percpu - register a newly allocated __percpu object | 909 | * kmemleak_alloc_percpu - register a newly allocated __percpu object |
910 | * @ptr: __percpu pointer to beginning of the object | 910 | * @ptr: __percpu pointer to beginning of the object |
911 | * @size: size of the object | 911 | * @size: size of the object |
912 | * @gfp: flags used for kmemleak internal memory allocations | ||
912 | * | 913 | * |
913 | * This function is called from the kernel percpu allocator when a new object | 914 | * This function is called from the kernel percpu allocator when a new object |
914 | * (memory block) is allocated (alloc_percpu). It assumes GFP_KERNEL | 915 | * (memory block) is allocated (alloc_percpu). |
915 | * allocation. | ||
916 | */ | 916 | */ |
917 | void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size) | 917 | void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size, |
918 | gfp_t gfp) | ||
918 | { | 919 | { |
919 | unsigned int cpu; | 920 | unsigned int cpu; |
920 | 921 | ||
@@ -927,7 +928,7 @@ void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size) | |||
927 | if (kmemleak_enabled && ptr && !IS_ERR(ptr)) | 928 | if (kmemleak_enabled && ptr && !IS_ERR(ptr)) |
928 | for_each_possible_cpu(cpu) | 929 | for_each_possible_cpu(cpu) |
929 | create_object((unsigned long)per_cpu_ptr(ptr, cpu), | 930 | create_object((unsigned long)per_cpu_ptr(ptr, cpu), |
930 | size, 0, GFP_KERNEL); | 931 | size, 0, gfp); |
931 | else if (kmemleak_early_log) | 932 | else if (kmemleak_early_log) |
932 | log_early(KMEMLEAK_ALLOC_PERCPU, ptr, size, 0); | 933 | log_early(KMEMLEAK_ALLOC_PERCPU, ptr, size, 0); |
933 | } | 934 | } |