aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@sprg.uniroma2.it>2012-02-11 15:41:19 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2012-03-13 21:35:43 -0400
commit69de127d6bb76821884abb1c1ce5c1f6a5829ded (patch)
tree43029dcd31cbee83db05fb92153ed7122779d44e
parentd31199a77ef606f1d06894385f1852181ba6136b (diff)
Add kernel-style events for sched_trace_XXX() functions
Enable kernel-style events (tracepoint) for Litmus. Litmus events trace the same functions as the sched_trace_XXX(), but can be enabled independently. So, why another tracing infrastructure then: - Litmus tracepoints can be recorded and analyzed together (single time reference) with all other kernel tracing events (e.g., sched:sched_switch, etc.). It's easier to correlate the effects of kernel events on litmus tasks. - It enables a quick way to visualize and process schedule traces using trace-cmd utility and kernelshark visualizer. Kernelshark lacks unit-trace's schedule-correctness checks, but it enables a fast view of schedule traces and it has several filtering options (for all kernel events, not only Litmus').
-rw-r--r--include/litmus/sched_trace.h105
-rw-r--r--include/trace/events/litmus.h231
-rw-r--r--kernel/sched.c6
-rw-r--r--litmus/Kconfig18
4 files changed, 334 insertions, 26 deletions
diff --git a/include/litmus/sched_trace.h b/include/litmus/sched_trace.h
index 5cc05be8332f..6868a07dac46 100644
--- a/include/litmus/sched_trace.h
+++ b/include/litmus/sched_trace.h
@@ -165,34 +165,93 @@ feather_callback void do_sched_trace_sys_release(unsigned long id,
165 165
166#endif 166#endif
167 167
168#ifdef CONFIG_SCHED_LITMUS_TRACEPOINT
169
170#include <trace/events/litmus.h>
171
172#else
173
174/* Override trace macros to actually do nothing */
175#define trace_litmus_task_param(t)
176#define trace_litmus_task_release(t)
177#define trace_litmus_switch_to(t)
178#define trace_litmus_switch_away(prev)
179#define trace_litmus_task_completion(t, forced)
180#define trace_litmus_task_block(t)
181#define trace_litmus_task_resume(t)
182#define trace_litmus_sys_release(start)
183
184#endif
185
168 186
169#define SCHED_TRACE_BASE_ID 500 187#define SCHED_TRACE_BASE_ID 500
170 188
171 189
172#define sched_trace_task_name(t) \ 190#define sched_trace_task_name(t) \
173 SCHED_TRACE(SCHED_TRACE_BASE_ID + 1, do_sched_trace_task_name, t) 191 SCHED_TRACE(SCHED_TRACE_BASE_ID + 1, \
174#define sched_trace_task_param(t) \ 192 do_sched_trace_task_name, t)
175 SCHED_TRACE(SCHED_TRACE_BASE_ID + 2, do_sched_trace_task_param, t) 193
176#define sched_trace_task_release(t) \ 194#define sched_trace_task_param(t) \
177 SCHED_TRACE(SCHED_TRACE_BASE_ID + 3, do_sched_trace_task_release, t) 195 do { \
178#define sched_trace_task_switch_to(t) \ 196 SCHED_TRACE(SCHED_TRACE_BASE_ID + 2, \
179 SCHED_TRACE(SCHED_TRACE_BASE_ID + 4, do_sched_trace_task_switch_to, t) 197 do_sched_trace_task_param, t); \
180#define sched_trace_task_switch_away(t) \ 198 trace_litmus_task_param(t); \
181 SCHED_TRACE(SCHED_TRACE_BASE_ID + 5, do_sched_trace_task_switch_away, t) 199 } while (0)
182#define sched_trace_task_completion(t, forced) \ 200
183 SCHED_TRACE2(SCHED_TRACE_BASE_ID + 6, do_sched_trace_task_completion, t, \ 201#define sched_trace_task_release(t) \
184 (unsigned long) forced) 202 do { \
185#define sched_trace_task_block(t) \ 203 SCHED_TRACE(SCHED_TRACE_BASE_ID + 3, \
186 SCHED_TRACE(SCHED_TRACE_BASE_ID + 7, do_sched_trace_task_block, t) 204 do_sched_trace_task_release, t); \
187#define sched_trace_task_resume(t) \ 205 trace_litmus_task_release(t); \
188 SCHED_TRACE(SCHED_TRACE_BASE_ID + 8, do_sched_trace_task_resume, t) 206 } while (0)
189#define sched_trace_action(t, action) \ 207
190 SCHED_TRACE2(SCHED_TRACE_BASE_ID + 9, do_sched_trace_action, t, \ 208#define sched_trace_task_switch_to(t) \
191 (unsigned long) action); 209 do { \
192/* when is a pointer, it does not need an explicit cast to unsigned long */ 210 SCHED_TRACE(SCHED_TRACE_BASE_ID + 4, \
193#define sched_trace_sys_release(when) \ 211 do_sched_trace_task_switch_to, t); \
194 SCHED_TRACE(SCHED_TRACE_BASE_ID + 10, do_sched_trace_sys_release, when) 212 trace_litmus_switch_to(t); \
213 } while (0)
214
215#define sched_trace_task_switch_away(t) \
216 do { \
217 SCHED_TRACE(SCHED_TRACE_BASE_ID + 5, \
218 do_sched_trace_task_switch_away, t); \
219 trace_litmus_switch_away(t); \
220 } while (0)
221
222#define sched_trace_task_completion(t, forced) \
223 do { \
224 SCHED_TRACE2(SCHED_TRACE_BASE_ID + 6, \
225 do_sched_trace_task_completion, t, \
226 (unsigned long) forced); \
227 trace_litmus_task_completion(t, forced); \
228 } while (0)
229
230#define sched_trace_task_block(t) \
231 do { \
232 SCHED_TRACE(SCHED_TRACE_BASE_ID + 7, \
233 do_sched_trace_task_block, t); \
234 trace_litmus_task_block(t); \
235 } while (0)
236
237#define sched_trace_task_resume(t) \
238 do { \
239 SCHED_TRACE(SCHED_TRACE_BASE_ID + 8, \
240 do_sched_trace_task_resume, t); \
241 trace_litmus_task_resume(t); \
242 } while (0)
243
244#define sched_trace_action(t, action) \
245 SCHED_TRACE2(SCHED_TRACE_BASE_ID + 9, \
246 do_sched_trace_action, t, (unsigned long) action);
195 247
248/* when is a pointer, it does not need an explicit cast to unsigned long */
249#define sched_trace_sys_release(when) \
250 do { \
251 SCHED_TRACE(SCHED_TRACE_BASE_ID + 10, \
252 do_sched_trace_sys_release, when); \
253 trace_litmus_sys_release(when); \
254 } while (0)
196 255
197#define QT_START lt_t _qt_start = litmus_clock() 256#define QT_START lt_t _qt_start = litmus_clock()
198#define QT_END \ 257#define QT_END \
diff --git a/include/trace/events/litmus.h b/include/trace/events/litmus.h
new file mode 100644
index 000000000000..0fffcee02be0
--- /dev/null
+++ b/include/trace/events/litmus.h
@@ -0,0 +1,231 @@
1/*
2 * LITMUS^RT kernel style scheduling tracepoints
3 */
4#undef TRACE_SYSTEM
5#define TRACE_SYSTEM litmus
6
7#if !defined(_SCHED_TASK_TRACEPOINT_H) || defined(TRACE_HEADER_MULTI_READ)
8#define _SCHED_TASK_TRACEPOINT_H
9
10#include <linux/tracepoint.h>
11
12#include <litmus/litmus.h>
13#include <litmus/rt_param.h>
14
15/*
16 * Tracing task admission
17 */
18TRACE_EVENT(litmus_task_param,
19
20 TP_PROTO(struct task_struct *t),
21
22 TP_ARGS(t),
23
24 TP_STRUCT__entry(
25 __field( pid_t, pid )
26 __field( unsigned int, job )
27 __field( lt_t, wcet )
28 __field( lt_t, period )
29 __field( lt_t, phase )
30 __field( int, partition )
31 ),
32
33 TP_fast_assign(
34 __entry->pid = t ? t->pid : 0;
35 __entry->job = t ? t->rt_param.job_params.job_no : 0;
36 __entry->wcet = get_exec_cost(t);
37 __entry->period = get_rt_period(t);
38 __entry->phase = get_rt_phase(t);
39 __entry->partition = get_partition(t);
40 ),
41
42 TP_printk("period(%d, %Lu).\nwcet(%d, %Lu).\n",
43 __entry->pid, __entry->period,
44 __entry->pid, __entry->wcet)
45);
46
47/*
48 * Tracing jobs release
49 */
50TRACE_EVENT(litmus_task_release,
51
52 TP_PROTO(struct task_struct *t),
53
54 TP_ARGS(t),
55
56 TP_STRUCT__entry(
57 __field( pid_t, pid )
58 __field( unsigned int, job )
59 __field( lt_t, release )
60 __field( lt_t, deadline )
61 ),
62
63 TP_fast_assign(
64 __entry->pid = t ? t->pid : 0;
65 __entry->job = t ? t->rt_param.job_params.job_no : 0;
66 __entry->release = get_release(t);
67 __entry->deadline = get_deadline(t);
68 ),
69
70 TP_printk("release(job(%u, %u)): %Lu\ndeadline(job(%u, %u)): %Lu\n",
71 __entry->pid, __entry->job, __entry->release,
72 __entry->pid, __entry->job, __entry->deadline)
73);
74
75/*
76 * Tracepoint for switching to new task
77 */
78TRACE_EVENT(litmus_switch_to,
79
80 TP_PROTO(struct task_struct *t),
81
82 TP_ARGS(t),
83
84 TP_STRUCT__entry(
85 __field( pid_t, pid )
86 __field( unsigned int, job )
87 __field( lt_t, when )
88 __field( lt_t, exec_time )
89 ),
90
91 TP_fast_assign(
92 __entry->pid = is_realtime(t) ? t->pid : 0;
93 __entry->job = is_realtime(t) ? t->rt_param.job_params.job_no : 0;
94 __entry->when = litmus_clock();
95 __entry->exec_time = get_exec_time(t);
96 ),
97
98 TP_printk("switch_to(job(%u, %u)): %Lu (exec: %Lu)\n",
99 __entry->pid, __entry->job,
100 __entry->when, __entry->exec_time)
101);
102
103/*
104 * Tracepoint for switching away previous task
105 */
106TRACE_EVENT(litmus_switch_away,
107
108 TP_PROTO(struct task_struct *t),
109
110 TP_ARGS(t),
111
112 TP_STRUCT__entry(
113 __field( pid_t, pid )
114 __field( unsigned int, job )
115 __field( lt_t, when )
116 __field( lt_t, exec_time )
117 ),
118
119 TP_fast_assign(
120 __entry->pid = is_realtime(t) ? t->pid : 0;
121 __entry->job = is_realtime(t) ? t->rt_param.job_params.job_no : 0;
122 __entry->when = litmus_clock();
123 __entry->exec_time = get_exec_time(t);
124 ),
125
126 TP_printk("switch_away(job(%u, %u)): %Lu (exec: %Lu)\n",
127 __entry->pid, __entry->job,
128 __entry->when, __entry->exec_time)
129);
130
131/*
132 * Tracing jobs completion
133 */
134TRACE_EVENT(litmus_task_completion,
135
136 TP_PROTO(struct task_struct *t, unsigned long forced),
137
138 TP_ARGS(t, forced),
139
140 TP_STRUCT__entry(
141 __field( pid_t, pid )
142 __field( unsigned int, job )
143 __field( lt_t, when )
144 __field( unsigned long, forced )
145 ),
146
147 TP_fast_assign(
148 __entry->pid = t ? t->pid : 0;
149 __entry->job = t ? t->rt_param.job_params.job_no : 0;
150 __entry->when = litmus_clock();
151 __entry->forced = forced;
152 ),
153
154 TP_printk("completed(job(%u, %u)): %Lu (forced: %lu)\n",
155 __entry->pid, __entry->job,
156 __entry->when, __entry->forced)
157);
158
159/*
160 * Trace blocking tasks.
161 */
162TRACE_EVENT(litmus_task_block,
163
164 TP_PROTO(struct task_struct *t),
165
166 TP_ARGS(t),
167
168 TP_STRUCT__entry(
169 __field( pid_t, pid )
170 __field( lt_t, when )
171 ),
172
173 TP_fast_assign(
174 __entry->pid = t ? t->pid : 0;
175 __entry->when = litmus_clock();
176 ),
177
178 TP_printk("(%u) blocks: %Lu\n", __entry->pid, __entry->when)
179);
180
181/*
182 * Tracing jobs resume
183 */
184TRACE_EVENT(litmus_task_resume,
185
186 TP_PROTO(struct task_struct *t),
187
188 TP_ARGS(t),
189
190 TP_STRUCT__entry(
191 __field( pid_t, pid )
192 __field( unsigned int, job )
193 __field( lt_t, when )
194 ),
195
196 TP_fast_assign(
197 __entry->pid = t ? t->pid : 0;
198 __entry->job = t ? t->rt_param.job_params.job_no : 0;
199 __entry->when = litmus_clock();
200 ),
201
202 TP_printk("resume(job(%u, %u)): %Lu\n",
203 __entry->pid, __entry->job, __entry->when)
204);
205
206/*
207 * Trace synchronous release
208 */
209TRACE_EVENT(litmus_sys_release,
210
211 TP_PROTO(lt_t *start),
212
213 TP_ARGS(start),
214
215 TP_STRUCT__entry(
216 __field( lt_t, rel )
217 __field( lt_t, when )
218 ),
219
220 TP_fast_assign(
221 __entry->rel = *start;
222 __entry->when = litmus_clock();
223 ),
224
225 TP_printk("SynRelease(%Lu) at %Lu\n", __entry->rel, __entry->when)
226);
227
228#endif /* _SCHED_TASK_TRACEPOINT_H */
229
230/* Must stay outside the protection */
231#include <trace/define_trace.h>
diff --git a/kernel/sched.c b/kernel/sched.c
index 093df593e45d..1db6b746845c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -79,14 +79,14 @@
79#include "sched_cpupri.h" 79#include "sched_cpupri.h"
80#include "workqueue_sched.h" 80#include "workqueue_sched.h"
81 81
82#define CREATE_TRACE_POINTS
83#include <trace/events/sched.h>
84
82#include <litmus/sched_trace.h> 85#include <litmus/sched_trace.h>
83#include <litmus/trace.h> 86#include <litmus/trace.h>
84 87
85static void litmus_tick(struct rq*, struct task_struct*); 88static void litmus_tick(struct rq*, struct task_struct*);
86 89
87#define CREATE_TRACE_POINTS
88#include <trace/events/sched.h>
89
90/* 90/*
91 * Convert user-nice values [ -20 ... 0 ... 19 ] 91 * Convert user-nice values [ -20 ... 0 ... 19 ]
92 * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], 92 * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
diff --git a/litmus/Kconfig b/litmus/Kconfig
index 4635ac9a6cbb..bd6ec9f2d3e8 100644
--- a/litmus/Kconfig
+++ b/litmus/Kconfig
@@ -170,6 +170,24 @@ config SCHED_TASK_TRACE_SHIFT
170 10 => 1k events 170 10 => 1k events
171 8 => 512 events 171 8 => 512 events
172 172
173config SCHED_LITMUS_TRACEPOINT
174 bool "Enable Event/Tracepoint Tracing for real-time task tracing"
175 depends on TRACEPOINTS
176 default n
177 help
178 Enable kernel-style events (tracepoint) for Litmus. Litmus events
179 trace the same functions as the above sched_trace_XXX(), but can
180 be enabled independently.
181 Litmus tracepoints can be recorded and analyzed together (single
182 time reference) with all other kernel tracing events (e.g.,
183 sched:sched_switch, etc.).
184
185 This also enables a quick way to visualize schedule traces using
186 trace-cmd utility and kernelshark visualizer.
187
188 Say Yes for debugging and visualization purposes.
189 Say No for overhead tracing.
190
173config SCHED_OVERHEAD_TRACE 191config SCHED_OVERHEAD_TRACE
174 bool "Record timestamps for overhead measurements" 192 bool "Record timestamps for overhead measurements"
175 depends on FEATHER_TRACE 193 depends on FEATHER_TRACE