diff options
Diffstat (limited to 'include/litmus/sched_trace.h')
-rw-r--r-- | include/litmus/sched_trace.h | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/include/litmus/sched_trace.h b/include/litmus/sched_trace.h new file mode 100644 index 00000000000..fa7042f744c --- /dev/null +++ b/include/litmus/sched_trace.h | |||
@@ -0,0 +1,342 @@ | |||
1 | /* | ||
2 | * sched_trace.h -- record scheduler events to a byte stream for offline analysis. | ||
3 | */ | ||
4 | #ifndef _LINUX_SCHED_TRACE_H_ | ||
5 | #define _LINUX_SCHED_TRACE_H_ | ||
6 | |||
7 | /* all times in nanoseconds */ | ||
8 | |||
9 | struct st_trace_header { | ||
10 | u8 type; /* Of what type is this record? */ | ||
11 | u8 cpu; /* On which CPU was it recorded? */ | ||
12 | u16 pid; /* PID of the task. */ | ||
13 | u32 job; /* The job sequence number. */ | ||
14 | }; | ||
15 | |||
16 | #define ST_NAME_LEN 16 | ||
17 | struct st_name_data { | ||
18 | char cmd[ST_NAME_LEN];/* The name of the executable of this process. */ | ||
19 | }; | ||
20 | |||
21 | struct st_param_data { /* regular params */ | ||
22 | u32 wcet; | ||
23 | u32 period; | ||
24 | u32 phase; | ||
25 | u8 partition; | ||
26 | u8 class; | ||
27 | u8 __unused[2]; | ||
28 | }; | ||
29 | |||
30 | struct st_release_data { /* A job is was/is going to be released. */ | ||
31 | u64 release; /* What's the release time? */ | ||
32 | u64 deadline; /* By when must it finish? */ | ||
33 | }; | ||
34 | |||
35 | struct st_assigned_data { /* A job was asigned to a CPU. */ | ||
36 | u64 when; | ||
37 | u8 target; /* Where should it execute? */ | ||
38 | u8 __unused[7]; | ||
39 | }; | ||
40 | |||
41 | struct st_switch_to_data { /* A process was switched to on a given CPU. */ | ||
42 | u64 when; /* When did this occur? */ | ||
43 | u32 exec_time; /* Time the current job has executed. */ | ||
44 | u8 __unused[4]; | ||
45 | |||
46 | }; | ||
47 | |||
48 | struct st_switch_away_data { /* A process was switched away from on a given CPU. */ | ||
49 | u64 when; | ||
50 | u64 exec_time; | ||
51 | }; | ||
52 | |||
53 | struct st_completion_data { /* A job completed. */ | ||
54 | u64 when; | ||
55 | u8 forced:1; /* Set to 1 if job overran and kernel advanced to the | ||
56 | * next task automatically; set to 0 otherwise. | ||
57 | */ | ||
58 | u8 __uflags:7; | ||
59 | u8 __unused[7]; | ||
60 | }; | ||
61 | |||
62 | struct st_block_data { /* A task blocks. */ | ||
63 | u64 when; | ||
64 | u64 __unused; | ||
65 | }; | ||
66 | |||
67 | struct st_resume_data { /* A task resumes. */ | ||
68 | u64 when; | ||
69 | u64 __unused; | ||
70 | }; | ||
71 | |||
72 | struct st_action_data { | ||
73 | u64 when; | ||
74 | u8 action; | ||
75 | u8 __unused[7]; | ||
76 | }; | ||
77 | |||
78 | struct st_sys_release_data { | ||
79 | u64 when; | ||
80 | u64 release; | ||
81 | }; | ||
82 | |||
83 | struct st_task_exit_data { | ||
84 | u64 avg_exec_time; | ||
85 | u64 max_exec_time; | ||
86 | }; | ||
87 | |||
88 | struct st_task_tardy_data { | ||
89 | u64 total_tardy; | ||
90 | u32 max_tardy; | ||
91 | u32 missed; | ||
92 | }; | ||
93 | |||
94 | #define DATA(x) struct st_ ## x ## _data x; | ||
95 | |||
96 | typedef enum { | ||
97 | ST_NAME = 1, /* Start at one, so that we can spot | ||
98 | * uninitialized records. */ | ||
99 | ST_PARAM, | ||
100 | ST_RELEASE, | ||
101 | ST_ASSIGNED, | ||
102 | ST_SWITCH_TO, | ||
103 | ST_SWITCH_AWAY, | ||
104 | ST_COMPLETION, | ||
105 | ST_BLOCK, | ||
106 | ST_RESUME, | ||
107 | ST_ACTION, | ||
108 | ST_SYS_RELEASE, | ||
109 | ST_TASK_EXIT, | ||
110 | ST_TASK_TARDY, | ||
111 | } st_event_record_type_t; | ||
112 | |||
113 | struct st_event_record { | ||
114 | struct st_trace_header hdr; | ||
115 | union { | ||
116 | u64 raw[2]; | ||
117 | |||
118 | DATA(name); | ||
119 | DATA(param); | ||
120 | DATA(release); | ||
121 | DATA(assigned); | ||
122 | DATA(switch_to); | ||
123 | DATA(switch_away); | ||
124 | DATA(completion); | ||
125 | DATA(block); | ||
126 | DATA(resume); | ||
127 | DATA(action); | ||
128 | DATA(sys_release); | ||
129 | DATA(task_exit); | ||
130 | DATA(task_tardy); | ||
131 | } data; | ||
132 | }; | ||
133 | |||
134 | #undef DATA | ||
135 | |||
136 | #ifdef __KERNEL__ | ||
137 | |||
138 | #include <linux/sched.h> | ||
139 | #include <litmus/feather_trace.h> | ||
140 | |||
141 | #ifdef CONFIG_SCHED_TASK_TRACE | ||
142 | |||
143 | #define SCHED_TRACE(id, callback, task) \ | ||
144 | ft_event1(id, callback, task) | ||
145 | #define SCHED_TRACE2(id, callback, task, xtra) \ | ||
146 | ft_event2(id, callback, task, xtra) | ||
147 | |||
148 | /* provide prototypes; needed on sparc64 */ | ||
149 | #ifndef NO_TASK_TRACE_DECLS | ||
150 | feather_callback void do_sched_trace_task_name(unsigned long id, | ||
151 | struct task_struct* task); | ||
152 | feather_callback void do_sched_trace_task_param(unsigned long id, | ||
153 | struct task_struct* task); | ||
154 | feather_callback void do_sched_trace_task_release(unsigned long id, | ||
155 | struct task_struct* task); | ||
156 | feather_callback void do_sched_trace_task_switch_to(unsigned long id, | ||
157 | struct task_struct* task); | ||
158 | feather_callback void do_sched_trace_task_switch_away(unsigned long id, | ||
159 | struct task_struct* task); | ||
160 | feather_callback void do_sched_trace_task_completion(unsigned long id, | ||
161 | struct task_struct* task, | ||
162 | unsigned long forced); | ||
163 | feather_callback void do_sched_trace_task_block(unsigned long id, | ||
164 | struct task_struct* task); | ||
165 | feather_callback void do_sched_trace_task_resume(unsigned long id, | ||
166 | struct task_struct* task); | ||
167 | feather_callback void do_sched_trace_action(unsigned long id, | ||
168 | struct task_struct* task, | ||
169 | unsigned long action); | ||
170 | feather_callback void do_sched_trace_sys_release(unsigned long id, | ||
171 | lt_t* start); | ||
172 | feather_callback void do_sched_trace_task_exit(unsigned long id, | ||
173 | struct task_struct* task); | ||
174 | feather_callback void do_sched_trace_task_tardy(unsigned long id, | ||
175 | struct task_struct* task); | ||
176 | |||
177 | #endif | ||
178 | |||
179 | #else | ||
180 | |||
181 | #define SCHED_TRACE(id, callback, task) /* no tracing */ | ||
182 | #define SCHED_TRACE2(id, callback, task, xtra) /* no tracing */ | ||
183 | |||
184 | #endif | ||
185 | |||
186 | #ifdef CONFIG_SCHED_LITMUS_TRACEPOINT | ||
187 | |||
188 | #include <trace/events/litmus.h> | ||
189 | |||
190 | #else | ||
191 | |||
192 | /* Override trace macros to actually do nothing */ | ||
193 | #define trace_litmus_task_param(t) | ||
194 | #define trace_litmus_task_release(t) | ||
195 | #define trace_litmus_switch_to(t) | ||
196 | #define trace_litmus_switch_away(prev) | ||
197 | #define trace_litmus_task_completion(t, forced) | ||
198 | #define trace_litmus_task_block(t) | ||
199 | #define trace_litmus_task_resume(t) | ||
200 | #define trace_litmus_sys_release(start) | ||
201 | #define trace_litmus_task_exit(t) | ||
202 | #define trace_litmus_task_tardy(t) | ||
203 | |||
204 | #define trace_litmus_container_param(cid, name) | ||
205 | #define trace_litmus_server_param(sid, cid, wcet, time) | ||
206 | #define trace_litmus_server_switch_to(sid, job, tid) | ||
207 | #define trace_litmus_server_switch_away(sid, job, tid) | ||
208 | #define trace_litmus_server_release(sid, job, release, deadline) | ||
209 | #define trace_litmus_server_completion(sid, job) | ||
210 | |||
211 | #define trace_litmus_container_param(cid, name) | ||
212 | #define trace_litmus_server_param(sid, cid, wcet, time) | ||
213 | #define trace_litmus_server_switch_to(sid, job, tid, tjob, cpu) | ||
214 | #define trace_litmus_server_switch_away(sid, job, tid, tjob, cpu) | ||
215 | #define trace_litmus_server_release(sid, job, release, deadline) | ||
216 | #define trace_litmus_server_completion(sid, job) | ||
217 | #define trace_litmus_server_block(sid) | ||
218 | #define trace_litmus_server_resume(sid) | ||
219 | |||
220 | #endif | ||
221 | |||
222 | |||
223 | #define SCHED_TRACE_BASE_ID 500 | ||
224 | |||
225 | |||
226 | #define sched_trace_task_name(t) \ | ||
227 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 1, \ | ||
228 | do_sched_trace_task_name, t) | ||
229 | |||
230 | #define sched_trace_task_param(t) \ | ||
231 | do { \ | ||
232 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 2, \ | ||
233 | do_sched_trace_task_param, t); \ | ||
234 | trace_litmus_task_param(t); \ | ||
235 | } while (0) | ||
236 | |||
237 | #define sched_trace_task_release(t) \ | ||
238 | do { \ | ||
239 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 3, \ | ||
240 | do_sched_trace_task_release, t); \ | ||
241 | trace_litmus_task_release(t); \ | ||
242 | } while (0) | ||
243 | |||
244 | #define sched_trace_task_switch_to(t) \ | ||
245 | do { \ | ||
246 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 4, \ | ||
247 | do_sched_trace_task_switch_to, t); \ | ||
248 | trace_litmus_switch_to(t); \ | ||
249 | } while (0) | ||
250 | |||
251 | #define sched_trace_task_switch_away(t) \ | ||
252 | do { \ | ||
253 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 5, \ | ||
254 | do_sched_trace_task_switch_away, t); \ | ||
255 | trace_litmus_switch_away(t); \ | ||
256 | } while (0) | ||
257 | |||
258 | #define sched_trace_task_completion(t, forced) \ | ||
259 | do { \ | ||
260 | SCHED_TRACE2(SCHED_TRACE_BASE_ID + 6, \ | ||
261 | do_sched_trace_task_completion, t, \ | ||
262 | (unsigned long) forced); \ | ||
263 | trace_litmus_task_completion(t, forced); \ | ||
264 | } while (0) | ||
265 | |||
266 | #define sched_trace_task_block_on(t, i) \ | ||
267 | do { \ | ||
268 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 7, \ | ||
269 | do_sched_trace_task_block, t); \ | ||
270 | trace_litmus_task_block(t, i); \ | ||
271 | } while (0) | ||
272 | |||
273 | #define sched_trace_task_block(t) \ | ||
274 | sched_trace_task_block_on(t, 0) | ||
275 | |||
276 | #define sched_trace_task_resume_on(t, i) \ | ||
277 | do { \ | ||
278 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 8, \ | ||
279 | do_sched_trace_task_resume, t); \ | ||
280 | trace_litmus_task_resume(t, i); \ | ||
281 | } while (0) | ||
282 | |||
283 | #define sched_trace_task_resume(t) \ | ||
284 | sched_trace_task_resume_on(t, 0) | ||
285 | |||
286 | #define sched_trace_resource_acquire(t, i) \ | ||
287 | do { \ | ||
288 | trace_litmus_resource_acquire(t, i); \ | ||
289 | } while (0) | ||
290 | |||
291 | #define sched_trace_resource_released(t, i) \ | ||
292 | do { \ | ||
293 | trace_litmus_resource_released(t, i); \ | ||
294 | } while (0) | ||
295 | |||
296 | #define sched_trace_action(t, action) \ | ||
297 | SCHED_TRACE2(SCHED_TRACE_BASE_ID + 9, \ | ||
298 | do_sched_trace_action, t, (unsigned long) action); | ||
299 | |||
300 | /* when is a pointer, it does not need an explicit cast to unsigned long */ | ||
301 | #define sched_trace_sys_release(when) \ | ||
302 | do { \ | ||
303 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 10, \ | ||
304 | do_sched_trace_sys_release, when); \ | ||
305 | trace_litmus_sys_release(when); \ | ||
306 | } while (0) | ||
307 | |||
308 | #define sched_trace_container_param(cid, name) \ | ||
309 | do { \ | ||
310 | trace_litmus_container_param(cid, name); \ | ||
311 | } while (0) | ||
312 | |||
313 | #define sched_trace_server_param(sid, cid, wcet, period) \ | ||
314 | do { \ | ||
315 | trace_litmus_server_param(sid, cid, wcet, period); \ | ||
316 | } while(0) | ||
317 | |||
318 | #define sched_trace_server_switch_to(sid, job, tid, tjob, cpu) \ | ||
319 | do { \ | ||
320 | trace_litmus_server_switch_to(sid, job, tid, tjob, cpu);\ | ||
321 | } while(0) | ||
322 | |||
323 | #define sched_trace_server_switch_away(sid, job, tid, tjob, cpu) \ | ||
324 | do { \ | ||
325 | trace_litmus_server_switch_away(sid, job, tid, tjob, cpu);\ | ||
326 | } while (0) | ||
327 | |||
328 | #define sched_trace_server_release(sid, job, release, deadline) \ | ||
329 | do { \ | ||
330 | trace_litmus_server_release(sid, job, release, deadline); \ | ||
331 | } while (0) | ||
332 | |||
333 | #define sched_trace_server_completion(sid, job) \ | ||
334 | do { \ | ||
335 | trace_litmus_server_completion(sid, job); \ | ||
336 | } while (0) | ||
337 | |||
338 | #define sched_trace_quantum_boundary() /* NOT IMPLEMENTED */ | ||
339 | |||
340 | #endif /* __KERNEL__ */ | ||
341 | |||
342 | #endif | ||