struct exit_event {
- uint_t exit_code;
- uint_t exit_count;
- uint_t handler_time;
+ uint_t exit_code;
+ uint_t exit_count;
+ uint_t handler_time;
- struct rb_node tree_node;
+ struct rb_node tree_node;
};
void v3_init_profiler(struct guest_info * info) {
- info->profiler.total_exits = 0;
+ info->profiler.total_exits = 0;
- info->profiler.start_time = 0;
- info->profiler.end_time = 0;
+ info->profiler.start_time = 0;
+ info->profiler.end_time = 0;
+ info->profiler.guest_pf_cnt = 0;
- info->profiler.root.rb_node = NULL;
+ info->profiler.root.rb_node = NULL;
}
static inline struct exit_event * __insert_event(struct guest_info * info,
struct exit_event * evt) {
- struct rb_node ** p = &(info->profiler.root.rb_node);
- struct rb_node * parent = NULL;
- struct exit_event * tmp_evt = NULL;
-
- while (*p) {
- parent = *p;
- tmp_evt = rb_entry(parent, struct exit_event, tree_node);
-
- if (evt->exit_code < tmp_evt->exit_code) {
- p = &(*p)->rb_left;
- } else if (evt->exit_code > tmp_evt->exit_code) {
- p = &(*p)->rb_right;
- } else {
- return tmp_evt;
+ struct rb_node ** p = &(info->profiler.root.rb_node);
+ struct rb_node * parent = NULL;
+ struct exit_event * tmp_evt = NULL;
+
+ while (*p) {
+ parent = *p;
+ tmp_evt = rb_entry(parent, struct exit_event, tree_node);
+
+ if (evt->exit_code < tmp_evt->exit_code) {
+ p = &(*p)->rb_left;
+ } else if (evt->exit_code > tmp_evt->exit_code) {
+ p = &(*p)->rb_right;
+ } else {
+ return tmp_evt;
+ }
}
- }
- rb_link_node(&(evt->tree_node), parent, p);
+ rb_link_node(&(evt->tree_node), parent, p);
- return NULL;
+ return NULL;
}
static inline struct exit_event * insert_event(struct guest_info * info,
struct exit_event * evt) {
- struct exit_event * ret;
+ struct exit_event * ret;
- if ((ret = __insert_event(info, evt))) {
- return ret;
- }
+ if ((ret = __insert_event(info, evt))) {
+ return ret;
+ }
- v3_rb_insert_color(&(evt->tree_node), &(info->profiler.root));
+ v3_rb_insert_color(&(evt->tree_node), &(info->profiler.root));
- return NULL;
+ return NULL;
}
static struct exit_event * get_exit(struct guest_info * info, uint_t exit_code) {
- struct rb_node * n = info->profiler.root.rb_node;
- struct exit_event * evt = NULL;
+ struct rb_node * n = info->profiler.root.rb_node;
+ struct exit_event * evt = NULL;
- while (n) {
- evt = rb_entry(n, struct exit_event, tree_node);
+ while (n) {
+ evt = rb_entry(n, struct exit_event, tree_node);
- if (exit_code < evt->exit_code) {
- n = n->rb_left;
- } else if (exit_code > evt->exit_code) {
- n = n->rb_right;
- } else {
- return evt;
+ if (exit_code < evt->exit_code) {
+ n = n->rb_left;
+ } else if (exit_code > evt->exit_code) {
+ n = n->rb_right;
+ } else {
+ return evt;
+ }
}
- }
- return NULL;
+ return NULL;
}
static inline struct exit_event * create_exit(uint_t exit_code) {
- struct exit_event * evt = V3_Malloc(sizeof(struct exit_event));
+ struct exit_event * evt = V3_Malloc(sizeof(struct exit_event));
- evt->exit_code = exit_code;
- evt->exit_count = 0;
- evt->handler_time = 0;
+ evt->exit_code = exit_code;
+ evt->exit_count = 0;
+ evt->handler_time = 0;
- return evt;
+ return evt;
}
void v3_profile_exit(struct guest_info * info, uint_t exit_code) {
- uint_t time = (info->profiler.end_time - info->profiler.start_time);
- struct exit_event * evt = get_exit(info, exit_code);
+ uint_t time = (info->profiler.end_time - info->profiler.start_time);
+ struct exit_event * evt = get_exit(info, exit_code);
- if (evt == NULL) {
- evt = create_exit(exit_code);
- insert_event(info, evt);
- }
+ if (evt == NULL) {
+ evt = create_exit(exit_code);
+ insert_event(info, evt);
+ }
- evt->handler_time += time;
- evt->exit_count++;
- info->profiler.total_exits++;
+
+ evt->handler_time = (evt->handler_time * .99) + (time * .01);
+
+
+ evt->exit_count++;
+
+ info->profiler.total_exits++;
}
void v3_print_profile(struct guest_info * info) {
- struct exit_event * evt = NULL;
- struct rb_node * node = v3_rb_first(&(info->profiler.root));
+ struct exit_event * evt = NULL;
+ struct rb_node * node = v3_rb_first(&(info->profiler.root));
- do {
- evt = rb_entry(node, struct exit_event, tree_node);
-
- PrintDebug("%s: Cnt=%u, Time=%u\n",
- vmexit_code_to_str(evt->exit_code),
- evt->exit_count,
- evt->handler_time);
+ PrintDebug("GUEST_PF: %u\n", info->profiler.guest_pf_cnt);
+
+ do {
+ evt = rb_entry(node, struct exit_event, tree_node);
+ const char * code_str = vmexit_code_to_str(evt->exit_code);
+
+ PrintDebug("%s:%sCnt=%u,%sTime=%u\n",
+ code_str,
+ (strlen(code_str) > 14) ? "\t" : "\t\t",
+ evt->exit_count,
+ (evt->exit_count >= 100) ? "\t" : "\t\t",
+ evt->handler_time);
- } while ((node = v3_rb_next(node)));
+ } while ((node = v3_rb_next(node)));
}