1 /* 2 * trace context switch 3 * 4 * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com> 5 * 6 */ 7 #include <linux/module.h> 8 #include <linux/kallsyms.h> 9 #include <linux/uaccess.h> 10 #include <linux/ftrace.h> 11 #include <trace/events/sched.h> 12 13 #include "trace.h" 14 15 static int sched_ref; 16 static DEFINE_MUTEX(sched_register_mutex); 17 18 static void 19 probe_sched_switch(void *ignore, bool preempt, 20 struct task_struct *prev, struct task_struct *next) 21 { 22 if (unlikely(!sched_ref)) 23 return; 24 25 tracing_record_cmdline(prev); 26 tracing_record_cmdline(next); 27 } 28 29 static void 30 probe_sched_wakeup(void *ignore, struct task_struct *wakee) 31 { 32 if (unlikely(!sched_ref)) 33 return; 34 35 tracing_record_cmdline(current); 36 } 37 38 static int tracing_sched_register(void) 39 { 40 int ret; 41 42 ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL); 43 if (ret) { 44 pr_info("wakeup trace: Couldn't activate tracepoint" 45 " probe to kernel_sched_wakeup\n"); 46 return ret; 47 } 48 49 ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 50 if (ret) { 51 pr_info("wakeup trace: Couldn't activate tracepoint" 52 " probe to kernel_sched_wakeup_new\n"); 53 goto fail_deprobe; 54 } 55 56 ret = register_trace_sched_switch(probe_sched_switch, NULL); 57 if (ret) { 58 pr_info("sched trace: Couldn't activate tracepoint" 59 " probe to kernel_sched_switch\n"); 60 goto fail_deprobe_wake_new; 61 } 62 63 return ret; 64 fail_deprobe_wake_new: 65 unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 66 fail_deprobe: 67 unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 68 return ret; 69 } 70 71 static void tracing_sched_unregister(void) 72 { 73 unregister_trace_sched_switch(probe_sched_switch, NULL); 74 unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 75 unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 76 } 77 78 static void tracing_start_sched_switch(void) 79 { 80 mutex_lock(&sched_register_mutex); 81 if (!(sched_ref++)) 82 tracing_sched_register(); 83 mutex_unlock(&sched_register_mutex); 84 } 85 86 static void tracing_stop_sched_switch(void) 87 { 88 mutex_lock(&sched_register_mutex); 89 if (!(--sched_ref)) 90 tracing_sched_unregister(); 91 mutex_unlock(&sched_register_mutex); 92 } 93 94 void tracing_start_cmdline_record(void) 95 { 96 tracing_start_sched_switch(); 97 } 98 99 void tracing_stop_cmdline_record(void) 100 { 101 tracing_stop_sched_switch(); 102 } 103