X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_profiler.c;h=567f652084e78f0acdbfc99eebe2f2d79fbed22e;hb=ad6ae90a3f3ec599f2cbc37d867614b8dbcf75ee;hp=362b8c939f429549aad37d1322f2b49ab69aa226;hpb=362391accc505b29d938e9d0a21bf6a28a8cee34;p=palacios.git diff --git a/palacios/src/palacios/vmm_profiler.c b/palacios/src/palacios/vmm_profiler.c index 362b8c9..567f652 100644 --- a/palacios/src/palacios/vmm_profiler.c +++ b/palacios/src/palacios/vmm_profiler.c @@ -24,119 +24,130 @@ 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 = (evt->handler_time * 127ull + time) / 128; - evt->handler_time += time; - evt->exit_count++; + + evt->exit_count++; - info->profiler.total_exits++; + 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))); }