diff options
Diffstat (limited to 'rt-plot-vcpu.c')
-rw-r--r-- | rt-plot-vcpu.c | 175 |
1 files changed, 159 insertions, 16 deletions
diff --git a/rt-plot-vcpu.c b/rt-plot-vcpu.c index 2c07d77..b04bcfb 100644 --- a/rt-plot-vcpu.c +++ b/rt-plot-vcpu.c | |||
@@ -32,6 +32,13 @@ static void update_server_label(struct vcpu_info *info, int job) | |||
32 | } | 32 | } |
33 | } | 33 | } |
34 | 34 | ||
35 | #define check_server(cond, vcpu, time, fmt, args...) \ | ||
36 | do { \ | ||
37 | if (!(cond)) fprintf(stderr, "%s -> %s: " fmt " at %llu\n", \ | ||
38 | vcpu->server_label, \ | ||
39 | vcpu_info->task_label, ##args, time); \ | ||
40 | } while(0) | ||
41 | |||
35 | static int | 42 | static int |
36 | try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | 43 | try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info, |
37 | struct record *record, struct plot_info *info) | 44 | struct record *record, struct plot_info *info) |
@@ -48,10 +55,15 @@ try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | |||
48 | update_task_label(vcpu_info, tid, tjob); | 55 | update_task_label(vcpu_info, tid, tjob); |
49 | update_server_label(vcpu_info, job); | 56 | update_server_label(vcpu_info, job); |
50 | 57 | ||
58 | check_server(vcpu_info->server_running, vcpu_info, ts, | ||
59 | "switched away when server was not running"); | ||
60 | check_server(vcpu_info->task_running, vcpu_info, ts, | ||
61 | "switched away when no task was running"); | ||
62 | |||
51 | if (vcpu_info->task_run_time && vcpu_info->task_run_time < ts) { | 63 | if (vcpu_info->task_run_time && vcpu_info->task_run_time < ts) { |
52 | info->box = TRUE; | 64 | info->box = TRUE; |
53 | info->bcolor = hash_pid(tid); | 65 | info->bcolor = hash_pid(tid > 0 ? tid : -tid); |
54 | info->bfill = vcpu_info->task_running; | 66 | info->bfill = vcpu_info->task_exec; |
55 | info->bstart = vcpu_info->task_run_time; | 67 | info->bstart = vcpu_info->task_run_time; |
56 | info->bend = ts; | 68 | info->bend = ts; |
57 | info->blabel = vcpu_info->task_label; | 69 | info->blabel = vcpu_info->task_label; |
@@ -67,9 +79,17 @@ try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | |||
67 | /* This server is no longer running */ | 79 | /* This server is no longer running */ |
68 | update_server_label(vcpu_info, tjob); | 80 | update_server_label(vcpu_info, tjob); |
69 | 81 | ||
82 | check_server(vcpu_info->server_running, vcpu_info, ts, | ||
83 | "stopped running when wasn't running"); | ||
84 | check_server(!vcpu_info->task_running || vcpu_info->task_cpu == NO_CPU, | ||
85 | vcpu_info, ts, "stopped running while a task is active"); | ||
86 | |||
70 | if (vcpu_info->server_run_time && vcpu_info->server_run_time < ts) { | 87 | if (vcpu_info->server_run_time && vcpu_info->server_run_time < ts) { |
71 | info->box = TRUE; | 88 | info->box = TRUE; |
72 | info->bcolor = hash_cpu(sid - 1); | 89 | if (!sid) |
90 | info->bcolor = 0; | ||
91 | else | ||
92 | info->bcolor = hash_cpu(sid - 1); | ||
73 | info->bfill = TRUE; | 93 | info->bfill = TRUE; |
74 | info->bstart = vcpu_info->server_run_time; | 94 | info->bstart = vcpu_info->server_run_time; |
75 | info->bend = ts; | 95 | info->bend = ts; |
@@ -77,12 +97,13 @@ try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | |||
77 | } | 97 | } |
78 | vcpu_info->server_run_time = 0ULL; | 98 | vcpu_info->server_run_time = 0ULL; |
79 | vcpu_info->server_cpu = NO_CPU; | 99 | vcpu_info->server_cpu = NO_CPU; |
100 | vcpu_info->server_running = FALSE; | ||
80 | 101 | ||
81 | ret = 1; | 102 | ret = 1; |
82 | } | 103 | } |
83 | 104 | ||
84 | if (ret) { | 105 | if (ret) { |
85 | dprintf(3, "VCPU switch away from %d on %d:%d at %llu\n", | 106 | dprintf(3, "VCPU Switch away tid: %d on %d:%d at %llu\n", |
86 | tid, sid, job, ts); | 107 | tid, sid, job, ts); |
87 | 108 | ||
88 | vcpu_info->task_run_time = 0ULL; | 109 | vcpu_info->task_run_time = 0ULL; |
@@ -103,25 +124,40 @@ static int try_server_switch_to(struct graph_info *ginfo, struct vcpu_info *vcpu | |||
103 | match = rt_graph_check_server_switch_to(ginfo, record, | 124 | match = rt_graph_check_server_switch_to(ginfo, record, |
104 | &sid, &job, &tid, &tjob, &ts); | 125 | &sid, &job, &tid, &tjob, &ts); |
105 | if (match && sid == vcpu_info->sid) { | 126 | if (match && sid == vcpu_info->sid) { |
127 | update_server_label(vcpu_info, job); | ||
128 | check_server(!vcpu_info->task_running || vcpu_info->task_cpu == NO_CPU, vcpu_info, ts, | ||
129 | "started running %d:%d while another task ran", | ||
130 | tid, tjob); | ||
131 | |||
106 | /* This server is now running something */ | 132 | /* This server is now running something */ |
107 | update_task_label(vcpu_info, tid, tjob); | 133 | update_task_label(vcpu_info, tid, tjob); |
108 | update_server_label(vcpu_info, job); | 134 | |
135 | check_server(vcpu_info->server_running, vcpu_info, ts, | ||
136 | "started running task without running server"); | ||
109 | 137 | ||
110 | vcpu_info->task_run_time = ts; | 138 | vcpu_info->task_run_time = ts; |
111 | vcpu_info->task_cpu = sid; | 139 | vcpu_info->task_cpu = sid; |
112 | vcpu_info->server_cpu = record->cpu; | 140 | vcpu_info->server_cpu = record->cpu; |
113 | vcpu_info->task_tid = tid; | 141 | vcpu_info->task_tid = tid; |
142 | vcpu_info->task_running = TRUE; | ||
114 | ret = 1; | 143 | ret = 1; |
115 | } else if (vcpu_info->show_server && match && tid == vcpu_info->sid) { | 144 | } else if (vcpu_info->show_server && match && tid == vcpu_info->sid) { |
116 | /* This server is now running */ | 145 | /* This server is now running */ |
117 | update_server_label(vcpu_info, tjob); | 146 | update_server_label(vcpu_info, tjob); |
147 | |||
148 | check_server(vcpu_info->spare || !vcpu_info->server_running || vcpu_info->server_cpu == NO_CPU, | ||
149 | vcpu_info, ts, "running server again on %d:%d, run: %d, cpu: %d", sid, job, vcpu_info->server_running, vcpu_info->server_cpu); | ||
150 | |||
151 | vcpu_info->spare = FALSE; | ||
152 | |||
118 | vcpu_info->server_run_time = ts; | 153 | vcpu_info->server_run_time = ts; |
119 | vcpu_info->server_cpu = sid; | 154 | vcpu_info->server_cpu = sid; |
155 | vcpu_info->server_running = TRUE; | ||
120 | ret = 1; | 156 | ret = 1; |
121 | } | 157 | } |
122 | 158 | ||
123 | if (ret) { | 159 | if (ret) { |
124 | dprintf(3, "Switch to %d for %d:%d at %llu\n", | 160 | dprintf(3, "VCPU Switch to tid: %d on %d:%d at %llu\n", |
125 | tid, sid, job, ts); | 161 | tid, sid, job, ts); |
126 | } | 162 | } |
127 | 163 | ||
@@ -135,13 +171,13 @@ static int try_switch_to(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | |||
135 | unsigned long long ts; | 171 | unsigned long long ts; |
136 | 172 | ||
137 | match = rt_graph_check_switch_to(ginfo, record, &pid, &job, &ts); | 173 | match = rt_graph_check_switch_to(ginfo, record, &pid, &job, &ts); |
138 | if (match && pid && vcpu_info->task_run_time && | 174 | if (match && vcpu_info->task_run_time && pid && |
139 | (pid == vcpu_info->task_tid || pid == -vcpu_info->task_tid)) { | 175 | (pid == vcpu_info->task_tid || pid == -vcpu_info->task_tid)) { |
140 | /* This server is running a physical task */ | 176 | /* This server is running a physical task */ |
141 | if (pid == vcpu_info->task_tid) | 177 | if (pid == vcpu_info->task_tid) |
142 | update_task_label(vcpu_info, pid, job); | 178 | update_task_label(vcpu_info, pid, job); |
143 | 179 | ||
144 | vcpu_info->task_running = TRUE; | 180 | vcpu_info->task_exec = TRUE; |
145 | 181 | ||
146 | /* Draw empty box for time spent not running a task */ | 182 | /* Draw empty box for time spent not running a task */ |
147 | info->box = TRUE; | 183 | info->box = TRUE; |
@@ -154,6 +190,14 @@ static int try_switch_to(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | |||
154 | 190 | ||
155 | vcpu_info->task_run_time = ts; | 191 | vcpu_info->task_run_time = ts; |
156 | ret = 1; | 192 | ret = 1; |
193 | } else if (pid) { | ||
194 | check_server(pid != vcpu_info->sid, vcpu_info, ts, | ||
195 | "server missing its task %d:%d, run time: %llu", pid, job, vcpu_info->task_run_time); | ||
196 | } | ||
197 | |||
198 | if (ret) { | ||
199 | dprintf(3, "VCPU Switch away on VCPU %d for %d:%d at %llu\n", | ||
200 | vcpu_info->sid, pid, job, ts); | ||
157 | } | 201 | } |
158 | return ret; | 202 | return ret; |
159 | } | 203 | } |
@@ -165,13 +209,12 @@ static int try_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info | |||
165 | unsigned long long ts; | 209 | unsigned long long ts; |
166 | 210 | ||
167 | match = rt_graph_check_switch_away(ginfo, record, &pid, &job, &ts); | 211 | match = rt_graph_check_switch_away(ginfo, record, &pid, &job, &ts); |
168 | if (match && pid && vcpu_info->task_running && | 212 | if (match && pid && vcpu_info->task_exec && |
169 | (pid == vcpu_info->task_tid || pid == -vcpu_info->task_tid)) { | 213 | (pid == vcpu_info->task_tid || pid == -vcpu_info->task_tid)) { |
170 | update_task_label(vcpu_info, pid, job); | 214 | if (pid == vcpu_info->task_tid) |
215 | update_task_label(vcpu_info, pid, job); | ||
171 | 216 | ||
172 | /* This server is no longer running a real task */ | 217 | /* This server is no longer running a real task */ |
173 | vcpu_info->task_running = FALSE; | ||
174 | |||
175 | if (vcpu_info->task_run_time && vcpu_info->task_run_time < ts) { | 218 | if (vcpu_info->task_run_time && vcpu_info->task_run_time < ts) { |
176 | info->box = TRUE; | 219 | info->box = TRUE; |
177 | info->flip = vcpu_info->show_server; | 220 | info->flip = vcpu_info->show_server; |
@@ -180,10 +223,80 @@ static int try_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info | |||
180 | info->bstart = vcpu_info->task_run_time; | 223 | info->bstart = vcpu_info->task_run_time; |
181 | info->bend = ts; | 224 | info->bend = ts; |
182 | info->blabel = vcpu_info->task_label; | 225 | info->blabel = vcpu_info->task_label; |
226 | } else { | ||
227 | dprintf(3, "Bad run time: %llu\n", vcpu_info->task_run_time); | ||
183 | } | 228 | } |
184 | 229 | ||
230 | vcpu_info->task_exec = FALSE; | ||
231 | |||
185 | vcpu_info->task_run_time = ts; | 232 | vcpu_info->task_run_time = ts; |
186 | ret = 1; | 233 | ret = 1; |
234 | } else { | ||
235 | check_server(pid != vcpu_info->sid, vcpu_info, ts, | ||
236 | "server missing its task switch away %d:%d, exec: %d", pid, job, vcpu_info->task_exec); | ||
237 | } | ||
238 | if (ret) { | ||
239 | dprintf(3, "Switch away on VCPU %d for %d:%d at %llu\n", | ||
240 | vcpu_info->sid, pid, job, ts); | ||
241 | } | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | static int try_server_block(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | ||
246 | struct record *record, struct plot_info *info) | ||
247 | { | ||
248 | int sid, match, ret = 0; | ||
249 | unsigned long long ts; | ||
250 | |||
251 | match = rt_graph_check_server_block(ginfo, record, &sid, &ts); | ||
252 | if (match && sid == vcpu_info->sid) { | ||
253 | check_server(!vcpu_info->blocked || vcpu_info->block_cpu == NO_CPU, | ||
254 | vcpu_info, ts, "already blocked"); | ||
255 | check_server(!vcpu_info->server_running || vcpu_info->server_cpu == NO_CPU, | ||
256 | vcpu_info, ts, | ||
257 | "blocked before running stopped"); | ||
258 | |||
259 | vcpu_info->fresh = FALSE; | ||
260 | vcpu_info->block_time = ts; | ||
261 | vcpu_info->block_cpu = record->cpu; | ||
262 | vcpu_info->blocked = TRUE; | ||
263 | |||
264 | if (!ts) | ||
265 | die("Initally no block time\n"); | ||
266 | |||
267 | dprintf(3, "Server block for %d on %d at %llu\n", | ||
268 | sid, record->cpu, ts); | ||
269 | ret = 1; | ||
270 | } | ||
271 | return ret; | ||
272 | } | ||
273 | |||
274 | static int try_server_resume(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | ||
275 | struct record *record, struct plot_info *info) | ||
276 | { | ||
277 | int sid, match, ret = 0; | ||
278 | unsigned long long ts; | ||
279 | |||
280 | match = rt_graph_check_server_resume(ginfo, record, &sid, &ts); | ||
281 | if (match && sid == vcpu_info->sid) { | ||
282 | check_server(vcpu_info->blocked, vcpu_info, ts, | ||
283 | "resuming when not blocked"); | ||
284 | |||
285 | info->box = TRUE; | ||
286 | info->bcolor = 0x0; | ||
287 | info->bfill = TRUE; | ||
288 | info->bthin = TRUE; | ||
289 | info->bstart = vcpu_info->block_time; | ||
290 | info->bend = ts; | ||
291 | |||
292 | vcpu_info->fresh = FALSE; | ||
293 | vcpu_info->block_time = 0ULL; | ||
294 | vcpu_info->block_cpu = NO_CPU; | ||
295 | vcpu_info->blocked = FALSE; | ||
296 | |||
297 | dprintf(3, "Server resume for %d on %d at %llu\n", | ||
298 | sid, record->cpu, ts); | ||
299 | ret = 1; | ||
187 | } | 300 | } |
188 | return ret; | 301 | return ret; |
189 | } | 302 | } |
@@ -220,7 +333,8 @@ static int try_server_completion(struct graph_info *ginfo, | |||
220 | unsigned long long ts; | 333 | unsigned long long ts; |
221 | 334 | ||
222 | match = rt_graph_check_server_completion(ginfo, record, &sid, &job, &ts); | 335 | match = rt_graph_check_server_completion(ginfo, record, &sid, &job, &ts); |
223 | if (match && sid == vcpu_info->sid) { | 336 | if (match && (( vcpu_info->show_server && sid == vcpu_info->sid) || |
337 | (!vcpu_info->show_server && sid == vcpu_info->task_tid))) { | ||
224 | 338 | ||
225 | info->completion = TRUE; | 339 | info->completion = TRUE; |
226 | info->ctime = ts; | 340 | info->ctime = ts; |
@@ -229,9 +343,13 @@ static int try_server_completion(struct graph_info *ginfo, | |||
229 | sid, job, record->cpu, ts); | 343 | sid, job, record->cpu, ts); |
230 | ret = 1; | 344 | ret = 1; |
231 | } | 345 | } |
346 | |||
232 | return ret; | 347 | return ret; |
233 | } | 348 | } |
234 | 349 | ||
350 | /* | ||
351 | * TODO: doesn't work with blocking | ||
352 | */ | ||
235 | static void do_plot_end(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | 353 | static void do_plot_end(struct graph_info *ginfo, struct vcpu_info *vcpu_info, |
236 | struct plot_info *info) | 354 | struct plot_info *info) |
237 | { | 355 | { |
@@ -271,6 +389,22 @@ static void do_plot_end(struct graph_info *ginfo, struct vcpu_info *vcpu_info, | |||
271 | return; | 389 | return; |
272 | } | 390 | } |
273 | 391 | ||
392 | if (vcpu_info->show_server && vcpu_info->block_time && | ||
393 | vcpu_info->block_cpu != NO_CPU) { | ||
394 | /* The server was running */ | ||
395 | /* Blocking happened */ | ||
396 | info->box = TRUE; | ||
397 | info->bcolor = 0x0; | ||
398 | info->bfill = TRUE; | ||
399 | info->bthin = TRUE; | ||
400 | info->bstart = vcpu_info->block_time; | ||
401 | info->bend = ginfo->view_end_time; | ||
402 | vcpu_info->fresh = FALSE; | ||
403 | vcpu_info->block_cpu = NO_CPU; | ||
404 | vcpu_info->block_time = 0ULL; | ||
405 | return; | ||
406 | } | ||
407 | |||
274 | if (vcpu_info->fresh) { | 408 | if (vcpu_info->fresh) { |
275 | /* No records received. Get information about time */ | 409 | /* No records received. Get information about time */ |
276 | is_running = get_server_info(ginfo, | 410 | is_running = get_server_info(ginfo, |
@@ -308,7 +442,9 @@ static int rt_vcpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot, | |||
308 | try_server_release(ginfo, vcpu_info, record, info) || | 442 | try_server_release(ginfo, vcpu_info, record, info) || |
309 | try_server_completion(ginfo, vcpu_info, record, info) || | 443 | try_server_completion(ginfo, vcpu_info, record, info) || |
310 | try_switch_to(ginfo, vcpu_info, record, info) || | 444 | try_switch_to(ginfo, vcpu_info, record, info) || |
311 | try_switch_away(ginfo, vcpu_info, record, info); | 445 | try_switch_away(ginfo, vcpu_info, record, info) || |
446 | try_server_block(ginfo, vcpu_info, record, info) || | ||
447 | try_server_resume(ginfo, vcpu_info, record, info); | ||
312 | return match; | 448 | return match; |
313 | } | 449 | } |
314 | static void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot, | 450 | static void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot, |
@@ -318,12 +454,19 @@ static void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot | |||
318 | 454 | ||
319 | vcpu_info->task_tid = -1; | 455 | vcpu_info->task_tid = -1; |
320 | vcpu_info->task_run_time = time; | 456 | vcpu_info->task_run_time = time; |
321 | vcpu_info->task_running = FALSE; | 457 | vcpu_info->task_running = TRUE; |
458 | vcpu_info->task_exec = TRUE; | ||
322 | vcpu_info->task_cpu = NO_CPU; | 459 | vcpu_info->task_cpu = NO_CPU; |
323 | 460 | ||
324 | vcpu_info->server_job = -1; | 461 | vcpu_info->server_job = -1; |
325 | vcpu_info->server_run_time = time; | 462 | vcpu_info->server_run_time = time; |
326 | vcpu_info->server_cpu = NO_CPU; | 463 | vcpu_info->server_cpu = NO_CPU; |
464 | vcpu_info->server_running = TRUE; | ||
465 | vcpu_info->spare = TRUE; | ||
466 | |||
467 | vcpu_info->block_time = time; | ||
468 | vcpu_info->block_cpu = NO_CPU; | ||
469 | vcpu_info->blocked = TRUE; | ||
327 | 470 | ||
328 | vcpu_info->fresh = TRUE; | 471 | vcpu_info->fresh = TRUE; |
329 | 472 | ||
@@ -439,7 +582,7 @@ void insert_vcpu(struct graph_info *ginfo, struct cont_list *cont, | |||
439 | nano_as_milli(vcpu_info->params.period)); | 582 | nano_as_milli(vcpu_info->params.period)); |
440 | } else { | 583 | } else { |
441 | /* Always running, no need to see the server */ | 584 | /* Always running, no need to see the server */ |
442 | vcpu->show_server = FALSE; | 585 | vcpu->show_server = TRUE; |
443 | snprintf(label, len, "%s-%d", | 586 | snprintf(label, len, "%s-%d", |
444 | cont->name, -vcpu_info->sid); | 587 | cont->name, -vcpu_info->sid); |
445 | } | 588 | } |