aboutsummaryrefslogtreecommitdiffstats
path: root/rt-plot-vcpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'rt-plot-vcpu.c')
-rw-r--r--rt-plot-vcpu.c279
1 files changed, 151 insertions, 128 deletions
diff --git a/rt-plot-vcpu.c b/rt-plot-vcpu.c
index 7951ad4..0ec55da 100644
--- a/rt-plot-vcpu.c
+++ b/rt-plot-vcpu.c
@@ -2,7 +2,7 @@
2#include <string.h> 2#include <string.h>
3#include "trace-graph.h" 3#include "trace-graph.h"
4 4
5#define DEBUG_LEVEL 4 5#define DEBUG_LEVEL 0
6#if DEBUG_LEVEL > 0 6#if DEBUG_LEVEL > 0
7#define dprintf(l, x...) \ 7#define dprintf(l, x...) \
8 do { \ 8 do { \
@@ -22,95 +22,6 @@ static void update_tid(struct vcpu_info *info, int tid)
22 } 22 }
23} 23}
24 24
25
26static int try_release(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
27 struct record *record, struct plot_info *info)
28{
29 int sid, job, match, ret = 0;
30 unsigned long long release, deadline;
31
32 match = rt_graph_check_server_release(ginfo, record, &sid, &job,
33 &release, &deadline);
34 if (match && sid == vcpu_info->sid) {
35 info->release = TRUE;
36 info->rtime = release;
37
38 info->deadline = TRUE;
39 info->dtime = deadline;
40
41 dprintf(3, "VCPU release for %d:%d on %d, rel: %llu, dead: %llu\n",
42 sid, job, record->cpu, release, deadline);
43
44 ret = 1;
45 }
46 return ret;
47}
48
49static int try_completion(struct graph_info *ginfo,
50 struct vcpu_info *vcpu_info,
51 struct record *record, struct plot_info *info)
52{
53 int sid, job, match, ret = 0;
54 unsigned long long ts;
55
56 match = rt_graph_check_server_completion(ginfo, record, &sid, &job, &ts);
57 if (match && sid == vcpu_info->sid) {
58
59 info->completion = TRUE;
60 info->ctime = ts;
61
62 dprintf(3, "VCPU completion for %d:%d on %d at %llu\n",
63 sid, job, record->cpu, ts);
64 ret = 1;
65 }
66 return ret;
67}
68
69static int try_block(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
70 struct record *record, struct plot_info *info)
71{
72 int sid, match, ret = 0;
73 unsigned long long ts;
74
75 match = rt_graph_check_server_block(ginfo, record, &sid, &ts);
76 if (match && sid == vcpu_info->sid) {
77 vcpu_info->fresh = FALSE;
78 vcpu_info->block_time = ts;
79 vcpu_info->block_cpu = NO_CPU;
80 dprintf(3, "VCPU resume for %d on %d at %llu\n",
81 sid, record->cpu, ts);
82 ret = 1;
83 }
84 return ret;
85}
86
87static int try_resume(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
88 struct record *record, struct plot_info *info)
89{
90 int sid, match, ret = 0;
91 unsigned long long ts;
92
93 match = rt_graph_check_server_resume(ginfo, record, &sid, &ts);
94
95 if (match && sid == vcpu_info->sid) {
96 info->box = TRUE;
97 info->bcolor = 0x0;
98 info->bfill = TRUE;
99 info->bthin = TRUE;
100 info->bstart = vcpu_info->block_time;
101 info->bend = ts;
102 vcpu_info->fresh = FALSE;
103
104 vcpu_info->block_time = 0ULL;
105 vcpu_info->block_cpu = NO_CPU;
106 dprintf(3, "VCPU resume for %d on %d at %llu\n",
107 sid, record->cpu, ts);
108
109 ret = 1;
110 }
111 return ret;
112}
113
114static int 25static int
115try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info, 26try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
116 struct record *record, struct plot_info *info) 27 struct record *record, struct plot_info *info)
@@ -259,16 +170,55 @@ static int rt_vcpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot,
259 170
260 match = try_server_switch_away(ginfo, vcpu_info, record, info) || 171 match = try_server_switch_away(ginfo, vcpu_info, record, info) ||
261 try_server_switch_to(ginfo, vcpu_info, record, info) || 172 try_server_switch_to(ginfo, vcpu_info, record, info) ||
262 try_block(ginfo, vcpu_info, record, info) || 173 vcpu_try_block(ginfo, vcpu_info, record, info) ||
263 try_resume(ginfo, vcpu_info, record, info) || 174 vcpu_try_resume(ginfo, vcpu_info, record, info) ||
264 try_release(ginfo, vcpu_info, record, info) || 175 vcpu_try_release(ginfo, vcpu_info, record, info) ||
265 try_completion(ginfo, vcpu_info, record, info) || 176 vcpu_try_completion(ginfo, vcpu_info, record, info) ||
266 try_switch_to(ginfo, vcpu_info, record, info) || 177 try_switch_to(ginfo, vcpu_info, record, info) ||
267 try_switch_away(ginfo, vcpu_info, record, info); 178 try_switch_away(ginfo, vcpu_info, record, info);
268 return match; 179 return match;
269} 180}
270 181
271static void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot, 182
183const struct plot_callbacks rt_vcpu_cb = {
184 .start = rt_vcpu_plot_start,
185 .destroy = rt_vcpu_plot_destroy,
186 .plot_event = rt_vcpu_plot_event,
187 .display_last_event = rt_plot_display_last_event,
188 .display_info = rt_plot_display_info,
189 .match_time = rt_plot_match_time,
190 .find_record = rt_plot_find_record,
191};
192
193void insert_vcpu(struct graph_info *ginfo, struct cont_list *cont,
194 struct vcpu_list *vcpu_info)
195{
196 struct graph_plot *plot;
197 struct vcpu_info *vcpu;
198 char *label;
199
200 vcpu = malloc_or_die(sizeof(*vcpu));
201 vcpu->sid = vcpu_info->sid;
202 vcpu->cont = cont;
203 vcpu->label = malloc_or_die(LLABEL);
204
205 vcpu->common.record_matches = rt_vcpu_plot_record_matches;
206 vcpu->common.is_drawn = rt_vcpu_plot_is_drawn;
207 vcpu->common.write_header = rt_vcpu_plot_write_header;
208
209 g_assert(cont);
210
211 label = malloc_or_die(1);
212 snprintf(label, 2, " ");
213 plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_SERVER_CPU,
214 TIME_TYPE_RT, &rt_vcpu_cb, vcpu);
215 trace_graph_plot_add_all_recs(ginfo, plot);
216}
217
218/**
219 *
220 */
221void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot,
272 unsigned long long time) 222 unsigned long long time)
273{ 223{
274 struct vcpu_info *vcpu_info = plot->private; 224 struct vcpu_info *vcpu_info = plot->private;
@@ -284,11 +234,15 @@ static void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot
284 234
285 vcpu_info->fresh = TRUE; 235 vcpu_info->fresh = TRUE;
286 vcpu_info->running = FALSE; 236 vcpu_info->running = FALSE;
237 vcpu_info->last_job = -1;
287 238
288 vcpu_info->run_tid = 0; 239 vcpu_info->run_tid = 0;
289} 240}
290 241
291static void rt_vcpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) 242/**
243 *
244 */
245void rt_vcpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot)
292{ 246{
293 struct vcpu_info *vcpu_info = plot->private; 247 struct vcpu_info *vcpu_info = plot->private;
294 trace_graph_plot_remove_all_recs(ginfo, plot); 248 trace_graph_plot_remove_all_recs(ginfo, plot);
@@ -296,10 +250,10 @@ static void rt_vcpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *pl
296 free(vcpu_info); 250 free(vcpu_info);
297} 251}
298 252
299/* 253/**
300 * Return 1 if @record is relevant to @match_sid. 254 * Return 1 if @record is relevant to @match_sid.
301 */ 255 */
302static int rt_vcpu_plot_record_matches(struct rt_plot_common *rt, 256int rt_vcpu_plot_record_matches(struct rt_plot_common *rt,
303 struct graph_info *ginfo, 257 struct graph_info *ginfo,
304 struct record *record) 258 struct record *record)
305{ 259{
@@ -318,11 +272,11 @@ static int rt_vcpu_plot_record_matches(struct rt_plot_common *rt,
318 return (sid == vcpu_info->sid); 272 return (sid == vcpu_info->sid);
319} 273}
320 274
321/* 275/**
322 * Return true if the given record type is drawn on screen. This does not 276 * Return true if the given record type is drawn on screen. This does not
323 * include event line markes. 277 * include event line markes.
324 */ 278 */
325static int 279int
326rt_vcpu_plot_is_drawn(struct graph_info *ginfo, int eid) 280rt_vcpu_plot_is_drawn(struct graph_info *ginfo, int eid)
327{ 281{
328 struct rt_graph_info *rtg_info = &ginfo->rtg_info; 282 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
@@ -334,7 +288,10 @@ rt_vcpu_plot_is_drawn(struct graph_info *ginfo, int eid)
334 eid == rtg_info->server_resume_id); 288 eid == rtg_info->server_resume_id);
335} 289}
336 290
337static struct record* 291/**
292 *
293 */
294struct record*
338rt_vcpu_plot_write_header(struct rt_plot_common *rt, 295rt_vcpu_plot_write_header(struct rt_plot_common *rt,
339 struct graph_info *ginfo, 296 struct graph_info *ginfo,
340 struct trace_seq *s, 297 struct trace_seq *s,
@@ -358,38 +315,104 @@ rt_vcpu_plot_write_header(struct rt_plot_common *rt,
358 return record; 315 return record;
359} 316}
360 317
318/**
319 * vcpu_try_release - draw release and deadline arrows if record matches
320 */
321int vcpu_try_release(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
322 struct record *record, struct plot_info *info)
323{
324 int sid, job, match, ret = 0;
325 unsigned long long release, deadline;
361 326
362const struct plot_callbacks rt_vcpu_cb = { 327 match = rt_graph_check_server_release(ginfo, record, &sid, &job,
363 .start = rt_vcpu_plot_start, 328 &release, &deadline);
364 .destroy = rt_vcpu_plot_destroy, 329 if (match && sid == vcpu_info->sid) {
365 .plot_event = rt_vcpu_plot_event, 330 info->release = TRUE;
366 .display_last_event = rt_plot_display_last_event, 331 info->rtime = release;
367 .display_info = rt_plot_display_info,
368 .match_time = rt_plot_match_time,
369 .find_record = rt_plot_find_record,
370};
371 332
372void insert_vcpu(struct graph_info *ginfo, struct cont_list *cont, 333 info->deadline = TRUE;
373 struct vcpu_list *vcpu_info) 334 info->dtime = deadline;
335
336 dprintf(3, "VCPU release for %d:%d on %d, rel: %llu, dead: %llu\n",
337 sid, job, record->cpu, release, deadline);
338
339 ret = 1;
340 }
341 return ret;
342}
343
344/**
345 * vcpu_try_completion - draw completion if record matches
346 */
347int vcpu_try_completion(struct graph_info *ginfo,
348 struct vcpu_info *vcpu_info,
349 struct record *record, struct plot_info *info)
374{ 350{
375 struct graph_plot *plot; 351 int sid, job, match, ret = 0;
376 struct vcpu_info *vcpu; 352 unsigned long long ts;
377 char *label;
378 353
379 vcpu = malloc_or_die(sizeof(*vcpu)); 354 match = rt_graph_check_server_completion(ginfo, record, &sid, &job, &ts);
380 vcpu->sid = vcpu_info->sid; 355 if (match && sid == vcpu_info->sid) {
381 vcpu->cont = cont;
382 vcpu->label = malloc_or_die(LLABEL);
383 356
384 vcpu->common.record_matches = rt_vcpu_plot_record_matches; 357 info->completion = TRUE;
385 vcpu->common.is_drawn = rt_vcpu_plot_is_drawn; 358 info->ctime = ts;
386 vcpu->common.write_header = rt_vcpu_plot_write_header;
387 359
388 g_assert(cont); 360 dprintf(3, "VCPU completion for %d:%d on %d at %llu\n",
361 sid, job, record->cpu, ts);
362 ret = 1;
363 }
364 return ret;
365}
389 366
390 label = malloc_or_die(1); 367/**
391 snprintf(label, 2, " "); 368 * vcpu_try_block - start block box if record matches
392 plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_SERVER_CPU, 369 */
393 TIME_TYPE_RT, &rt_vcpu_cb, vcpu); 370int vcpu_try_block(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
394 trace_graph_plot_add_all_recs(ginfo, plot); 371 struct record *record, struct plot_info *info)
372{
373 int sid, match, ret = 0;
374 unsigned long long ts;
375
376 match = rt_graph_check_server_block(ginfo, record, &sid, &ts);
377 if (match && sid == vcpu_info->sid) {
378 vcpu_info->fresh = FALSE;
379 vcpu_info->block_time = ts;
380 vcpu_info->block_cpu = NO_CPU;
381 dprintf(3, "VCPU resume for %d on %d at %llu\n",
382 sid, record->cpu, ts);
383 ret = 1;
384 }
385 return ret;
395} 386}
387
388/**
389 * vcpu_try_resume - end block box if record matches
390 */
391int vcpu_try_resume(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
392 struct record *record, struct plot_info *info)
393{
394 int sid, match, ret = 0;
395 unsigned long long ts;
396
397 match = rt_graph_check_server_resume(ginfo, record, &sid, &ts);
398
399 if (match && sid == vcpu_info->sid) {
400 info->box = TRUE;
401 info->bcolor = 0x0;
402 info->bfill = TRUE;
403 info->bthin = TRUE;
404 info->bstart = vcpu_info->block_time;
405 info->bend = ts;
406 vcpu_info->fresh = FALSE;
407
408 vcpu_info->block_time = 0ULL;
409 vcpu_info->block_cpu = NO_CPU;
410 dprintf(3, "VCPU resume for %d on %d at %llu\n",
411 sid, record->cpu, ts);
412
413 ret = 1;
414 }
415 return ret;
416}
417
418