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, 56 insertions, 29 deletions
diff --git a/driver/gator_trace_sched.c b/driver/gator_trace_sched.c
index 52990e9..6550086 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 }; 117 static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF, ACTIVITY_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,35 +137,44 @@ 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, 0, 0); 140 marshal_sched_trace_switch(0, 0);
141} 141}
142 142
143GATOR_DEFINE_PROBE(sched_process_fork, TP_PROTO(struct task_struct *parent, struct task_struct *child)) 143static void gator_trace_emit_link(struct task_struct *p)
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, child); 148 cookie = get_exec_cookie(cpu, p);
149 emit_pid_name(child); 149 emit_pid_name(p);
150 150
151 marshal_sched_trace_start(child->tgid, child->pid, cookie); 151 marshal_link(cookie, p->tgid, p->pid);
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
154#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) 166#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
155GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next)) 167GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct rq *rq, struct task_struct *prev, struct task_struct *next))
156#else 168#else
157GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next)) 169GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_struct *next))
158#endif 170#endif
159{ 171{
160 int cookie;
161 int state; 172 int state;
162 int cpu = get_physical_cpu(); 173 int cpu = get_physical_cpu();
163 174
164 per_cpu(in_scheduler_context, cpu) = true; 175 per_cpu(in_scheduler_context, cpu) = true;
165 176
166 // do as much work as possible before disabling interrupts 177 // do as much work as possible before disabling interrupts
167 cookie = get_exec_cookie(cpu, next);
168 emit_pid_name(next);
169 if (prev->state == TASK_RUNNING) { 178 if (prev->state == TASK_RUNNING) {
170 state = STATE_CONTENTION; 179 state = STATE_CONTENTION;
171 } else if (prev->in_iowait) { 180 } else if (prev->in_iowait) {
@@ -178,7 +187,10 @@ GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_
178 collect_counters(gator_get_time(), prev); 187 collect_counters(gator_get_time(), prev);
179 per_cpu(collecting, cpu) = 0; 188 per_cpu(collecting, cpu) = 0;
180 189
181 marshal_sched_trace_switch(next->tgid, next->pid, cookie, state); 190#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
191 gator_trace_emit_link(next);
192#endif
193 marshal_sched_trace_switch(next->pid, state);
182 194
183 per_cpu(in_scheduler_context, cpu) = false; 195 per_cpu(in_scheduler_context, cpu) = false;
184} 196}
@@ -199,6 +211,10 @@ static int register_scheduler_tracepoints(void)
199 // register tracepoints 211 // register tracepoints
200 if (GATOR_REGISTER_TRACE(sched_process_fork)) 212 if (GATOR_REGISTER_TRACE(sched_process_fork))
201 goto fail_sched_process_fork; 213 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
202 if (GATOR_REGISTER_TRACE(sched_switch)) 218 if (GATOR_REGISTER_TRACE(sched_switch))
203 goto fail_sched_switch; 219 goto fail_sched_switch;
204 if (GATOR_REGISTER_TRACE(sched_process_free)) 220 if (GATOR_REGISTER_TRACE(sched_process_free))
@@ -216,15 +232,42 @@ fail_sched_process_free:
216 GATOR_UNREGISTER_TRACE(sched_switch); 232 GATOR_UNREGISTER_TRACE(sched_switch);
217fail_sched_switch: 233fail_sched_switch:
218 GATOR_UNREGISTER_TRACE(sched_process_fork); 234 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
219fail_sched_process_fork: 239fail_sched_process_fork:
220 pr_err("gator: tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n"); 240 pr_err("gator: tracepoints failed to activate, please verify that tracepoints are enabled in the linux kernel\n");
221 241
222 return -1; 242 return -1;
223} 243}
224 244
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
225static int gator_trace_sched_start(void) 267static int gator_trace_sched_start(void)
226{ 268{
227 int cpu, size; 269 int cpu, size;
270 int ret;
228 271
229 for_each_present_cpu(cpu) { 272 for_each_present_cpu(cpu) {
230 size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t); 273 size = TASK_MAP_ENTRIES * TASK_MAX_COLLISIONS * sizeof(uint64_t);
@@ -234,7 +277,9 @@ static int gator_trace_sched_start(void)
234 memset(per_cpu(taskname_keys, cpu), 0, size); 277 memset(per_cpu(taskname_keys, cpu), 0, size);
235 } 278 }
236 279
237 return register_scheduler_tracepoints(); 280 ret = register_scheduler_tracepoints();
281
282 return ret;
238} 283}
239 284
240static void gator_trace_sched_offline(void) 285static void gator_trace_sched_offline(void)
@@ -242,24 +287,6 @@ static void gator_trace_sched_offline(void)
242 trace_sched_insert_idle(); 287 trace_sched_insert_idle();
243} 288}
244 289
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
263static void gator_trace_sched_init(void) 290static void gator_trace_sched_init(void)
264{ 291{
265 int i; 292 int i;