diff options
Diffstat (limited to 'driver/gator_trace_sched.c')
-rw-r--r-- | driver/gator_trace_sched.c | 85 |
1 files changed, 29 insertions, 56 deletions
diff --git a/driver/gator_trace_sched.c b/driver/gator_trace_sched.c index 6550086..52990e9 100644 --- a/driver/gator_trace_sched.c +++ b/driver/gator_trace_sched.c | |||
@@ -114,7 +114,7 @@ static void collect_counters(u64 time, struct task_struct *task) | |||
114 | 114 | ||
115 | // Commit buffers on timeout | 115 | // Commit buffers on timeout |
116 | if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) { | 116 | if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) { |
117 | static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF, ACTIVITY_BUF }; | 117 | static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF }; |
118 | int i; | 118 | int i; |
119 | 119 | ||
120 | for (i = 0; i < ARRAY_SIZE(buftypes); ++i) { | 120 | for (i = 0; i < ARRAY_SIZE(buftypes); ++i) { |
@@ -137,44 +137,35 @@ static void collect_counters(u64 time, struct task_struct *task) | |||
137 | // special case used during a suspend of the system | 137 | // special case used during a suspend of the system |
138 | static void trace_sched_insert_idle(void) | 138 | static void trace_sched_insert_idle(void) |
139 | { | 139 | { |
140 | marshal_sched_trace_switch(0, 0); | 140 | marshal_sched_trace_switch(0, 0, 0, 0); |
141 | } | 141 | } |
142 | 142 | ||
143 | static void gator_trace_emit_link(struct task_struct *p) | 143 | GATOR_DEFINE_PROBE(sched_process_fork, TP_PROTO(struct task_struct *parent, struct task_struct *child)) |
144 | { | 144 | { |
145 | int cookie; | 145 | int cookie; |
146 | int cpu = get_physical_cpu(); | 146 | int cpu = get_physical_cpu(); |
147 | 147 | ||
148 | cookie = get_exec_cookie(cpu, p); | 148 | cookie = get_exec_cookie(cpu, child); |
149 | emit_pid_name(p); | 149 | emit_pid_name(child); |
150 | 150 | ||
151 | marshal_link(cookie, p->tgid, p->pid); | 151 | marshal_sched_trace_start(child->tgid, child->pid, cookie); |
152 | } | 152 | } |
153 | 153 | ||
154 | GATOR_DEFINE_PROBE(sched_process_fork, TP_PROTO(struct task_struct *parent, struct task_struct *child)) | ||
155 | { | ||
156 | gator_trace_emit_link(child); | ||
157 | } | ||
158 | |||
159 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) | ||
160 | GATOR_DEFINE_PROBE(sched_process_exec, TP_PROTO(struct task_struct *p, pid_t old_pid, struct linux_binprm *bprm)) | ||
161 | { | ||
162 | gator_trace_emit_link(p); | ||
163 | } | ||
164 | #endif | ||
165 | |||
166 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) | 154 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) |
167 | GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next)) | 155 | GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next)) |
168 | #else | 156 | #else |
169 | GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next)) | 157 | GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next)) |
170 | #endif | 158 | #endif |
171 | { | 159 | { |
160 | int cookie; | ||
172 | int state; | 161 | int state; |
173 | int cpu = get_physical_cpu(); | 162 | int cpu = get_physical_cpu(); |
174 | 163 | ||
175 | per_cpu(in_scheduler_context, cpu) = true; | 164 | per_cpu(in_scheduler_context, cpu) = true; |
176 | 165 | ||
177 | // do as much work as possible before disabling interrupts | 166 | // do as much work as possible before disabling interrupts |
167 | cookie = get_exec_cookie(cpu, next); | ||
168 | emit_pid_name(next); | ||
178 | if (prev->state == TASK_RUNNING) { | 169 | if (prev->state == TASK_RUNNING) { |
179 | state = STATE_CONTENTION; | 170 | state = STATE_CONTENTION; |
180 | } else if (prev->in_iowait) { | 171 | } else if (prev->in_iowait) { |
@@ -187,10 +178,7 @@ GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_ | |||
187 | collect_counters(gator_get_time(), prev); | 178 | collect_counters(gator_get_time(), prev); |
188 | per_cpu(collecting, cpu) = 0; | 179 | per_cpu(collecting, cpu) = 0; |
189 | 180 | ||
190 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) | 181 | marshal_sched_trace_switch(next->tgid, next->pid, cookie, state); |
191 | gator_trace_emit_link(next); | ||
192 | #endif | ||
193 | marshal_sched_trace_switch(next->pid, state); | ||
194 | 182 | ||
195 | per_cpu(in_scheduler_context, cpu) = false; | 183 | per_cpu(in_scheduler_context, cpu) = false; |
196 | } | 184 | } |
@@ -211,10 +199,6 @@ static int register_scheduler_tracepoints(void) | |||
211 | // register tracepoints | 199 | // register tracepoints |
212 | if (GATOR_REGISTER_TRACE(sched_process_fork)) | 200 | if (GATOR_REGISTER_TRACE(sched_process_fork)) |
213 | goto fail_sched_process_fork; | 201 | goto fail_sched_process_fork; |
214 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) | ||
215 | if (GATOR_REGISTER_TRACE(sched_process_exec)) | ||
216 | goto fail_sched_process_exec; | ||
217 | #endif | ||
218 | if (GATOR_REGISTER_TRACE(sched_switch)) | 202 | if (GATOR_REGISTER_TRACE(sched_switch)) |
219 | goto fail_sched_switch; | 203 | goto fail_sched_switch; |
220 | if (GATOR_REGISTER_TRACE(sched_process_free)) | 204 | if (GATOR_REGISTER_TRACE(sched_process_free)) |
@@ -232,42 +216,15 @@ fail_sched_process_free: | |||
232 | GATOR_UNREGISTER_TRACE(sched_switch); | 216 | GATOR_UNREGISTER_TRACE(sched_switch); |
233 | fail_sched_switch: | 217 | fail_sched_switch: |
234 | GATOR_UNREGISTER_TRACE(sched_process_fork); | 218 | GATOR_UNREGISTER_TRACE(sched_process_fork); |
235 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) | ||
236 | fail_sched_process_exec: | ||
237 | GATOR_UNREGISTER_TRACE(sched_process_exec); | ||
238 | #endif | ||
239 | fail_sched_process_fork: | 219 | fail_sched_process_fork: |
240 | pr_err("gator: tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); | 220 | pr_err("gator: tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); |
241 | 221 | ||
242 | return -1; | 222 | return -1; |
243 | } | 223 | } |
244 | 224 | ||
245 | static void unregister_scheduler_tracepoints(void) | ||
246 | { | ||
247 | GATOR_UNREGISTER_TRACE(sched_process_fork); | ||
248 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) | ||
249 | GATOR_UNREGISTER_TRACE(sched_process_exec); | ||
250 | #endif | ||
251 | GATOR_UNREGISTER_TRACE(sched_switch); | ||
252 | GATOR_UNREGISTER_TRACE(sched_process_free); | ||
253 | pr_debug("gator: unregistered tracepoints\n"); | ||
254 | } | ||
255 | |||
256 | static void gator_trace_sched_stop(void) | ||
257 | { | ||
258 | int cpu; | ||
259 | |||
260 | unregister_scheduler_tracepoints(); | ||
261 | |||
262 | for_each_present_cpu(cpu) { | ||
263 | kfree(per_cpu(taskname_keys, cpu)); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static int gator_trace_sched_start(void) | 225 | static int gator_trace_sched_start(void) |
268 | { | 226 | { |
269 | int cpu, size; | 227 | int cpu, size; |
270 | int ret; | ||
271 | 228 | ||
272 | for_each_present_cpu(cpu) { | 229 | for_each_present_cpu(cpu) { |
273 | size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t); | 230 | size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t); |
@@ -277,9 +234,7 @@ static int gator_trace_sched_start(void) | |||
277 | memset(per_cpu(taskname_keys, cpu), 0, size); | 234 | memset(per_cpu(taskname_keys, cpu), 0, size); |
278 | } | 235 | } |
279 | 236 | ||
280 | ret = register_scheduler_tracepoints(); | 237 | return register_scheduler_tracepoints(); |
281 | |||
282 | return ret; | ||
283 | } | 238 | } |
284 | 239 | ||
285 | static void gator_trace_sched_offline(void) | 240 | static void gator_trace_sched_offline(void) |
@@ -287,6 +242,24 @@ static void gator_trace_sched_offline(void) | |||
287 | trace_sched_insert_idle(); | 242 | trace_sched_insert_idle(); |
288 | } | 243 | } |
289 | 244 | ||
245 | static void unregister_scheduler_tracepoints(void) | ||
246 | { | ||
247 | GATOR_UNREGISTER_TRACE(sched_process_fork); | ||
248 | GATOR_UNREGISTER_TRACE(sched_switch); | ||
249 | GATOR_UNREGISTER_TRACE(sched_process_free); | ||
250 | pr_debug("gator: unregistered tracepoints\n"); | ||
251 | } | ||
252 | |||
253 | static void gator_trace_sched_stop(void) | ||
254 | { | ||
255 | int cpu; | ||
256 | unregister_scheduler_tracepoints(); | ||
257 | |||
258 | for_each_present_cpu(cpu) { | ||
259 | kfree(per_cpu(taskname_keys, cpu)); | ||
260 | } | ||
261 | } | ||
262 | |||
290 | static void gator_trace_sched_init(void) | 263 | static void gator_trace_sched_init(void) |
291 | { | 264 | { |
292 | int i; | 265 | int i; |