tracing/mm: don't trace mm_page_free on offline cpus
authorShreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
Thu, 28 May 2015 22:44:19 +0000 (15:44 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 May 2015 01:25:18 +0000 (18:25 -0700)
Since tracepoints use RCU for protection, they must not be called on
offline cpus.  trace_mm_page_free 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:170 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
     no locks held by swapper/1/0.

    stack backtrace:
     CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.1.0-rc1+ #9
     Call Trace:
       .dump_stack+0x98/0xd4 (unreliable)
       .lockdep_rcu_suspicious+0x108/0x170
       .free_pages_prepare+0x494/0x680
       .free_hot_cold_page+0x50/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_free 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>
include/trace/events/kmem.h

index 78efa0a197a9ec66467a1c1e666768039842c4e5..aa863549e77ae92fec54cbe4554bd587a9feb8c0 100644 (file)
@@ -158,12 +158,24 @@ DEFINE_EVENT_CONDITION(kmem_free, kmem_cache_free,
        TP_CONDITION(cpu_online(raw_smp_processor_id()))
 );
 
-TRACE_EVENT(mm_page_free,
+TRACE_EVENT_CONDITION(mm_page_free,
 
        TP_PROTO(struct page *page, unsigned int order),
 
        TP_ARGS(page, order),
 
+
+       /*
+        * This trace can be potentially called from an offlined cpu.
+        * Since trace points use RCU and RCU should not be used from
+        * offline cpus, filter such calls out.
+        * While this trace can be called from a preemptable section,
+        * it has no impact on the condition since tasks can migrate
+        * only from online cpus to other online cpus. Thus its safe
+        * to use raw_smp_processor_id.
+        */
+       TP_CONDITION(cpu_online(raw_smp_processor_id())),
+
        TP_STRUCT__entry(
                __field(        unsigned long,  pfn             )
                __field(        unsigned int,   order           )