summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'driver/gator_trace_sched.c')
-rw-r--r--driver/gator_trace_sched.c85
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
138static void trace_sched_insert_idle(void) 138static 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
143static void gator_trace_emit_link(struct task_struct *p) 143GATOR_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
154GATOR_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)
160GATOR_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)
167GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next)) 155GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next))
168#else 156#else
169GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next)) 157GATOR_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);
233fail_sched_switch: 217fail_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)
236fail_sched_process_exec:
237 GATOR_UNREGISTER_TRACE(sched_process_exec);
238#endif
239fail_sched_process_fork: 219fail_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
245static 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
256static 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
267static int gator_trace_sched_start(void) 225static 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
285static void gator_trace_sched_offline(void) 240static 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
245static 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
253static 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
290static void gator_trace_sched_init(void) 263static void gator_trace_sched_init(void)
291{ 264{
292 int i; 265 int i;