diff options
Diffstat (limited to 'driver/gator_trace_sched.c')
-rw-r--r-- | driver/gator_trace_sched.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/driver/gator_trace_sched.c b/driver/gator_trace_sched.c index e98815e..332b3f6 100644 --- a/driver/gator_trace_sched.c +++ b/driver/gator_trace_sched.c | |||
@@ -22,6 +22,7 @@ enum { | |||
22 | 22 | ||
23 | static DEFINE_PER_CPU(uint64_t *, taskname_keys); | 23 | static DEFINE_PER_CPU(uint64_t *, taskname_keys); |
24 | static DEFINE_PER_CPU(int, collecting); | 24 | static DEFINE_PER_CPU(int, collecting); |
25 | static DEFINE_PER_CPU(bool, in_scheduler_context); | ||
25 | 26 | ||
26 | // this array is never read as the cpu wait charts are derived counters | 27 | // this array is never read as the cpu wait charts are derived counters |
27 | // the files are needed, nonetheless, to show that these counters are available | 28 | // the files are needed, nonetheless, to show that these counters are available |
@@ -89,7 +90,7 @@ void emit_pid_name(struct task_struct *task) | |||
89 | } | 90 | } |
90 | } | 91 | } |
91 | 92 | ||
92 | static void collect_counters(u64 time) | 93 | static void collect_counters(u64 time, struct task_struct *task) |
93 | { | 94 | { |
94 | int *buffer, len, cpu = get_physical_cpu(); | 95 | int *buffer, len, cpu = get_physical_cpu(); |
95 | long long *buffer64; | 96 | long long *buffer64; |
@@ -104,17 +105,26 @@ static void collect_counters(u64 time) | |||
104 | len = gi->read64(&buffer64); | 105 | len = gi->read64(&buffer64); |
105 | marshal_event64(len, buffer64); | 106 | marshal_event64(len, buffer64); |
106 | } | 107 | } |
108 | if (gi->read_proc && task != NULL) { | ||
109 | len = gi->read_proc(&buffer64, task); | ||
110 | marshal_event64(len, buffer64); | ||
111 | } | ||
107 | } | 112 | } |
108 | // Only check after writing all counters so that time and corresponding counters appear in the same frame | 113 | // Only check after writing all counters so that time and corresponding counters appear in the same frame |
109 | buffer_check(cpu, BLOCK_COUNTER_BUF, time); | 114 | buffer_check(cpu, BLOCK_COUNTER_BUF, time); |
110 | 115 | ||
111 | // Commit buffers on timeout | 116 | // Commit buffers on timeout |
112 | if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) { | 117 | if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) { |
113 | static const int buftypes[] = { COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF }; | 118 | static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF }; |
119 | unsigned long flags; | ||
114 | int i; | 120 | int i; |
121 | |||
122 | local_irq_save(flags); | ||
115 | for (i = 0; i < ARRAY_SIZE(buftypes); ++i) { | 123 | for (i = 0; i < ARRAY_SIZE(buftypes); ++i) { |
116 | gator_commit_buffer(cpu, buftypes[i], time); | 124 | gator_commit_buffer(cpu, buftypes[i], time); |
117 | } | 125 | } |
126 | local_irq_restore(flags); | ||
127 | |||
118 | // Try to preemptively flush the annotate buffer to reduce the chance of the buffer being full | 128 | // Try to preemptively flush the annotate buffer to reduce the chance of the buffer being full |
119 | if (on_primary_core() && spin_trylock(&annotate_lock)) { | 129 | if (on_primary_core() && spin_trylock(&annotate_lock)) { |
120 | gator_commit_buffer(0, ANNOTATE_BUF, time); | 130 | gator_commit_buffer(0, ANNOTATE_BUF, time); |
@@ -151,6 +161,8 @@ GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_ | |||
151 | int state; | 161 | int state; |
152 | int cpu = get_physical_cpu(); | 162 | int cpu = get_physical_cpu(); |
153 | 163 | ||
164 | per_cpu(in_scheduler_context, cpu) = true; | ||
165 | |||
154 | // do as much work as possible before disabling interrupts | 166 | // do as much work as possible before disabling interrupts |
155 | cookie = get_exec_cookie(cpu, next); | 167 | cookie = get_exec_cookie(cpu, next); |
156 | emit_pid_name(next); | 168 | emit_pid_name(next); |
@@ -163,10 +175,12 @@ GATOR_DEFINE_PROBE(sched_switch, TP_PROTO(struct task_struct *prev, struct task_ | |||
163 | } | 175 | } |
164 | 176 | ||
165 | per_cpu(collecting, cpu) = 1; | 177 | per_cpu(collecting, cpu) = 1; |
166 | collect_counters(gator_get_time()); | 178 | collect_counters(gator_get_time(), prev); |
167 | per_cpu(collecting, cpu) = 0; | 179 | per_cpu(collecting, cpu) = 0; |
168 | 180 | ||
169 | marshal_sched_trace_switch(next->tgid, next->pid, cookie, state); | 181 | marshal_sched_trace_switch(next->tgid, next->pid, cookie, state); |
182 | |||
183 | per_cpu(in_scheduler_context, cpu) = false; | ||
170 | } | 184 | } |
171 | 185 | ||
172 | GATOR_DEFINE_PROBE(sched_process_free, TP_PROTO(struct task_struct *p)) | 186 | GATOR_DEFINE_PROBE(sched_process_free, TP_PROTO(struct task_struct *p)) |