diff options
author | Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com> | 2015-05-28 18:44:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-28 21:25:18 -0400 |
commit | 649b8de2f75145bf14cb1783688e16d51ac9b89a (patch) | |
tree | 6f6429fc37f6343c71f55b5df4d76e2c0f4e78f5 | |
parent | 1f0c27b50f4f2567e649f49d77daee2bbf3f40e5 (diff) |
tracing/mm: don't trace mm_page_pcpu_drain on offline cpus
Since tracepoints use RCU for protection, they must not be called on
offline cpus. trace_mm_page_pcpu_drain can be called on an offline cpu
in this scenario caught by LOCKDEP:
===============================
[ INFO: suspicious RCU usage. ]
4.1.0-rc1+ #9 Not tainted
-------------------------------
include/trace/events/kmem.h:265 suspicious rcu_dereference_check() usage!
other info that might help us debug this:
RCU used illegally from offline CPU!
rcu_scheduler_active = 1, debug_locks = 1
1 lock held by swapper/5/0:
#0: (&(&zone->lock)->rlock){..-...}, at: [<c0000000002073b0>] .free_pcppages_bulk+0x70/0x920
stack backtrace:
CPU: 5 PID: 0 Comm: swapper/5 Not tainted 4.1.0-rc1+ #9
Call Trace:
.dump_stack+0x98/0xd4 (unreliable)
.lockdep_rcu_suspicious+0x108/0x170
.free_pcppages_bulk+0x60c/0x920
.free_hot_cold_page+0x208/0x280
.destroy_context+0x90/0xd0
.__mmdrop+0x58/0x160
.idle_task_exit+0xf0/0x100
.pnv_smp_cpu_kill_self+0x58/0x2c0
.cpu_die+0x34/0x50
.arch_cpu_idle_dead+0x20/0x40
.cpu_startup_entry+0x708/0x7a0
.start_secondary+0x36c/0x3a0
start_secondary_prolog+0x10/0x14
Fix this by converting mm_page_pcpu_drain trace point into
TRACE_EVENT_CONDITION where condition is cpu_online(smp_processor_id())
Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/trace/events/kmem.h | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h index aa863549e77a..f7554fd7fc62 100644 --- a/include/trace/events/kmem.h +++ b/include/trace/events/kmem.h | |||
@@ -276,12 +276,35 @@ DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, | |||
276 | TP_ARGS(page, order, migratetype) | 276 | TP_ARGS(page, order, migratetype) |
277 | ); | 277 | ); |
278 | 278 | ||
279 | DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, | 279 | TRACE_EVENT_CONDITION(mm_page_pcpu_drain, |
280 | 280 | ||
281 | TP_PROTO(struct page *page, unsigned int order, int migratetype), | 281 | TP_PROTO(struct page *page, unsigned int order, int migratetype), |
282 | 282 | ||
283 | TP_ARGS(page, order, migratetype), | 283 | TP_ARGS(page, order, migratetype), |
284 | 284 | ||
285 | /* | ||
286 | * This trace can be potentially called from an offlined cpu. | ||
287 | * Since trace points use RCU and RCU should not be used from | ||
288 | * offline cpus, filter such calls out. | ||
289 | * While this trace can be called from a preemptable section, | ||
290 | * it has no impact on the condition since tasks can migrate | ||
291 | * only from online cpus to other online cpus. Thus its safe | ||
292 | * to use raw_smp_processor_id. | ||
293 | */ | ||
294 | TP_CONDITION(cpu_online(raw_smp_processor_id())), | ||
295 | |||
296 | TP_STRUCT__entry( | ||
297 | __field( unsigned long, pfn ) | ||
298 | __field( unsigned int, order ) | ||
299 | __field( int, migratetype ) | ||
300 | ), | ||
301 | |||
302 | TP_fast_assign( | ||
303 | __entry->pfn = page ? page_to_pfn(page) : -1UL; | ||
304 | __entry->order = order; | ||
305 | __entry->migratetype = migratetype; | ||
306 | ), | ||
307 | |||
285 | TP_printk("page=%p pfn=%lu order=%d migratetype=%d", | 308 | TP_printk("page=%p pfn=%lu order=%d migratetype=%d", |
286 | pfn_to_page(__entry->pfn), __entry->pfn, | 309 | pfn_to_page(__entry->pfn), __entry->pfn, |
287 | __entry->order, __entry->migratetype) | 310 | __entry->order, __entry->migratetype) |