]>
Commit | Line | Data |
---|---|---|
35e8e302 SR |
1 | /* |
2 | * trace context switch | |
3 | * | |
4 | * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com> | |
5 | * | |
6 | */ | |
7 | #include <linux/module.h> | |
35e8e302 SR |
8 | #include <linux/kallsyms.h> |
9 | #include <linux/uaccess.h> | |
35e8e302 | 10 | #include <linux/ftrace.h> |
ad8d75ff | 11 | #include <trace/events/sched.h> |
35e8e302 SR |
12 | |
13 | #include "trace.h" | |
14 | ||
d914ba37 JF |
15 | #define RECORD_CMDLINE 1 |
16 | #define RECORD_TGID 2 | |
17 | ||
18 | static int sched_cmdline_ref; | |
19 | static int sched_tgid_ref; | |
efade6e7 | 20 | static DEFINE_MUTEX(sched_register_mutex); |
82e04af4 | 21 | |
e309b41d | 22 | static void |
c73464b1 PZ |
23 | probe_sched_switch(void *ignore, bool preempt, |
24 | struct task_struct *prev, struct task_struct *next) | |
35e8e302 | 25 | { |
d914ba37 JF |
26 | int flags; |
27 | ||
28 | flags = (RECORD_TGID * !!sched_tgid_ref) + | |
29 | (RECORD_CMDLINE * !!sched_cmdline_ref); | |
b07c3f19 | 30 | |
d914ba37 JF |
31 | if (!flags) |
32 | return; | |
33 | tracing_record_taskinfo_sched_switch(prev, next, flags); | |
35e8e302 SR |
34 | } |
35 | ||
4e655519 | 36 | static void |
fbd705a0 | 37 | probe_sched_wakeup(void *ignore, struct task_struct *wakee) |
57422797 | 38 | { |
d914ba37 JF |
39 | int flags; |
40 | ||
41 | flags = (RECORD_TGID * !!sched_tgid_ref) + | |
42 | (RECORD_CMDLINE * !!sched_cmdline_ref); | |
57422797 | 43 | |
d914ba37 JF |
44 | if (!flags) |
45 | return; | |
46 | tracing_record_taskinfo(current, flags); | |
57422797 IM |
47 | } |
48 | ||
5b82a1b0 MD |
49 | static int tracing_sched_register(void) |
50 | { | |
51 | int ret; | |
52 | ||
38516ab5 | 53 | ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL); |
5b82a1b0 | 54 | if (ret) { |
b07c3f19 | 55 | pr_info("wakeup trace: Couldn't activate tracepoint" |
5b82a1b0 MD |
56 | " probe to kernel_sched_wakeup\n"); |
57 | return ret; | |
58 | } | |
59 | ||
38516ab5 | 60 | ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL); |
5b82a1b0 | 61 | if (ret) { |
b07c3f19 | 62 | pr_info("wakeup trace: Couldn't activate tracepoint" |
5b82a1b0 MD |
63 | " probe to kernel_sched_wakeup_new\n"); |
64 | goto fail_deprobe; | |
65 | } | |
66 | ||
38516ab5 | 67 | ret = register_trace_sched_switch(probe_sched_switch, NULL); |
5b82a1b0 | 68 | if (ret) { |
b07c3f19 | 69 | pr_info("sched trace: Couldn't activate tracepoint" |
73d8b8bc | 70 | " probe to kernel_sched_switch\n"); |
5b82a1b0 MD |
71 | goto fail_deprobe_wake_new; |
72 | } | |
73 | ||
74 | return ret; | |
75 | fail_deprobe_wake_new: | |
38516ab5 | 76 | unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); |
5b82a1b0 | 77 | fail_deprobe: |
38516ab5 | 78 | unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); |
5b82a1b0 MD |
79 | return ret; |
80 | } | |
81 | ||
82 | static void tracing_sched_unregister(void) | |
83 | { | |
38516ab5 SR |
84 | unregister_trace_sched_switch(probe_sched_switch, NULL); |
85 | unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); | |
86 | unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); | |
5b82a1b0 MD |
87 | } |
88 | ||
d914ba37 | 89 | static void tracing_start_sched_switch(int ops) |
5b82a1b0 | 90 | { |
d914ba37 | 91 | bool sched_register = (!sched_cmdline_ref && !sched_tgid_ref); |
efade6e7 | 92 | mutex_lock(&sched_register_mutex); |
d914ba37 JF |
93 | |
94 | switch (ops) { | |
95 | case RECORD_CMDLINE: | |
96 | sched_cmdline_ref++; | |
97 | break; | |
98 | ||
99 | case RECORD_TGID: | |
100 | sched_tgid_ref++; | |
101 | break; | |
102 | } | |
103 | ||
104 | if (sched_register && (sched_cmdline_ref || sched_tgid_ref)) | |
5b82a1b0 | 105 | tracing_sched_register(); |
efade6e7 | 106 | mutex_unlock(&sched_register_mutex); |
5b82a1b0 MD |
107 | } |
108 | ||
d914ba37 | 109 | static void tracing_stop_sched_switch(int ops) |
5b82a1b0 | 110 | { |
efade6e7 | 111 | mutex_lock(&sched_register_mutex); |
d914ba37 JF |
112 | |
113 | switch (ops) { | |
114 | case RECORD_CMDLINE: | |
115 | sched_cmdline_ref--; | |
116 | break; | |
117 | ||
118 | case RECORD_TGID: | |
119 | sched_tgid_ref--; | |
120 | break; | |
121 | } | |
122 | ||
123 | if (!sched_cmdline_ref && !sched_tgid_ref) | |
5b82a1b0 | 124 | tracing_sched_unregister(); |
efade6e7 | 125 | mutex_unlock(&sched_register_mutex); |
5b82a1b0 MD |
126 | } |
127 | ||
41bc8144 SR |
128 | void tracing_start_cmdline_record(void) |
129 | { | |
d914ba37 | 130 | tracing_start_sched_switch(RECORD_CMDLINE); |
41bc8144 SR |
131 | } |
132 | ||
133 | void tracing_stop_cmdline_record(void) | |
134 | { | |
d914ba37 JF |
135 | tracing_stop_sched_switch(RECORD_CMDLINE); |
136 | } | |
137 | ||
138 | void tracing_start_tgid_record(void) | |
139 | { | |
140 | tracing_start_sched_switch(RECORD_TGID); | |
141 | } | |
142 | ||
143 | void tracing_stop_tgid_record(void) | |
144 | { | |
145 | tracing_stop_sched_switch(RECORD_TGID); | |
41bc8144 | 146 | } |