135e8e302SSteven Rostedt /* 235e8e302SSteven Rostedt * trace context switch 335e8e302SSteven Rostedt * 435e8e302SSteven Rostedt * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com> 535e8e302SSteven Rostedt * 635e8e302SSteven Rostedt */ 735e8e302SSteven Rostedt #include <linux/module.h> 835e8e302SSteven Rostedt #include <linux/kallsyms.h> 935e8e302SSteven Rostedt #include <linux/uaccess.h> 1035e8e302SSteven Rostedt #include <linux/ftrace.h> 11ad8d75ffSSteven Rostedt #include <trace/events/sched.h> 1235e8e302SSteven Rostedt 1335e8e302SSteven Rostedt #include "trace.h" 1435e8e302SSteven Rostedt 15efade6e7SFrederic Weisbecker static int sched_ref; 16efade6e7SFrederic Weisbecker static DEFINE_MUTEX(sched_register_mutex); 1782e04af4SFrederic Weisbecker 18e309b41dSIngo Molnar static void 19c73464b1SPeter Zijlstra probe_sched_switch(void *ignore, bool preempt, 20c73464b1SPeter Zijlstra struct task_struct *prev, struct task_struct *next) 2135e8e302SSteven Rostedt { 22dcef788eSZhaolei if (unlikely(!sched_ref)) 23b07c3f19SMathieu Desnoyers return; 24b07c3f19SMathieu Desnoyers 2541bc8144SSteven Rostedt tracing_record_cmdline(prev); 2641bc8144SSteven Rostedt tracing_record_cmdline(next); 2735e8e302SSteven Rostedt } 2835e8e302SSteven Rostedt 295b82a1b0SMathieu Desnoyers static void 30fbd705a0SPeter Zijlstra probe_sched_wakeup(void *ignore, struct task_struct *wakee) 315b82a1b0SMathieu Desnoyers { 32dcef788eSZhaolei if (unlikely(!sched_ref)) 33dcef788eSZhaolei return; 34dcef788eSZhaolei 35dcef788eSZhaolei tracing_record_cmdline(current); 3657422797SIngo Molnar } 3757422797SIngo Molnar 385b82a1b0SMathieu Desnoyers static int tracing_sched_register(void) 395b82a1b0SMathieu Desnoyers { 405b82a1b0SMathieu Desnoyers int ret; 415b82a1b0SMathieu Desnoyers 4238516ab5SSteven Rostedt ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL); 435b82a1b0SMathieu Desnoyers if (ret) { 44b07c3f19SMathieu Desnoyers pr_info("wakeup trace: Couldn't activate tracepoint" 455b82a1b0SMathieu Desnoyers " probe to kernel_sched_wakeup\n"); 465b82a1b0SMathieu Desnoyers return ret; 475b82a1b0SMathieu Desnoyers } 485b82a1b0SMathieu Desnoyers 4938516ab5SSteven Rostedt ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 505b82a1b0SMathieu Desnoyers if (ret) { 51b07c3f19SMathieu Desnoyers pr_info("wakeup trace: Couldn't activate tracepoint" 525b82a1b0SMathieu Desnoyers " probe to kernel_sched_wakeup_new\n"); 535b82a1b0SMathieu Desnoyers goto fail_deprobe; 545b82a1b0SMathieu Desnoyers } 555b82a1b0SMathieu Desnoyers 5638516ab5SSteven Rostedt ret = register_trace_sched_switch(probe_sched_switch, NULL); 575b82a1b0SMathieu Desnoyers if (ret) { 58b07c3f19SMathieu Desnoyers pr_info("sched trace: Couldn't activate tracepoint" 5973d8b8bcSWenji Huang " probe to kernel_sched_switch\n"); 605b82a1b0SMathieu Desnoyers goto fail_deprobe_wake_new; 615b82a1b0SMathieu Desnoyers } 625b82a1b0SMathieu Desnoyers 635b82a1b0SMathieu Desnoyers return ret; 645b82a1b0SMathieu Desnoyers fail_deprobe_wake_new: 6538516ab5SSteven Rostedt unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 665b82a1b0SMathieu Desnoyers fail_deprobe: 6738516ab5SSteven Rostedt unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 685b82a1b0SMathieu Desnoyers return ret; 695b82a1b0SMathieu Desnoyers } 705b82a1b0SMathieu Desnoyers 715b82a1b0SMathieu Desnoyers static void tracing_sched_unregister(void) 725b82a1b0SMathieu Desnoyers { 7338516ab5SSteven Rostedt unregister_trace_sched_switch(probe_sched_switch, NULL); 7438516ab5SSteven Rostedt unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 7538516ab5SSteven Rostedt unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 765b82a1b0SMathieu Desnoyers } 775b82a1b0SMathieu Desnoyers 78f2252935SIngo Molnar static void tracing_start_sched_switch(void) 795b82a1b0SMathieu Desnoyers { 80efade6e7SFrederic Weisbecker mutex_lock(&sched_register_mutex); 81e168e051SSteven Rostedt if (!(sched_ref++)) 825b82a1b0SMathieu Desnoyers tracing_sched_register(); 83efade6e7SFrederic Weisbecker mutex_unlock(&sched_register_mutex); 845b82a1b0SMathieu Desnoyers } 855b82a1b0SMathieu Desnoyers 86f2252935SIngo Molnar static void tracing_stop_sched_switch(void) 875b82a1b0SMathieu Desnoyers { 88efade6e7SFrederic Weisbecker mutex_lock(&sched_register_mutex); 89e168e051SSteven Rostedt if (!(--sched_ref)) 905b82a1b0SMathieu Desnoyers tracing_sched_unregister(); 91efade6e7SFrederic Weisbecker mutex_unlock(&sched_register_mutex); 925b82a1b0SMathieu Desnoyers } 935b82a1b0SMathieu Desnoyers 9441bc8144SSteven Rostedt void tracing_start_cmdline_record(void) 9541bc8144SSteven Rostedt { 9641bc8144SSteven Rostedt tracing_start_sched_switch(); 9741bc8144SSteven Rostedt } 9841bc8144SSteven Rostedt 9941bc8144SSteven Rostedt void tracing_stop_cmdline_record(void) 10041bc8144SSteven Rostedt { 10141bc8144SSteven Rostedt tracing_stop_sched_switch(); 10241bc8144SSteven Rostedt } 103