diff --git a/args-add-p-option.patch b/args-add-p-option.patch new file mode 100644 index 0000000000000000000000000000000000000000..520e551b21bc35e84612cd9bf3c50e44bdbdaaa3 --- /dev/null +++ b/args-add-p-option.patch @@ -0,0 +1,84 @@ +From 67cf54ea04205639c9d07648c838c9504f98670b Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Thu, 29 Oct 2020 14:18:42 +0800 +Subject: [PATCH] args: add -p option + +Add -p option to specify a virtual machine that vmtop monitors. +Usage: +vmtop -p vmid +vmid means domain's id. + +Signed-off-by: Jiajun Chen <1250062498@qq.com> +--- + src/domain.c | 5 +++++ + src/domain.h | 2 ++ + src/vmtop.c | 7 ++++++- + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/domain.c b/src/domain.c +index ac15d53..8683115 100644 +--- a/src/domain.c ++++ b/src/domain.c +@@ -25,6 +25,8 @@ + #define CGROUP_PATH_SIZE 30 + #define TASK_STRING_SIZE 30 + ++int monitor_id; ++ + /* domain list operation */ + void init_domains(struct domain_list *list) + { +@@ -231,6 +233,9 @@ static int set_domain(struct domain *dom, const char *name) + if (dom->domain_id < 0) { + return -1; + } ++ if (monitor_id >= 0 && dom->domain_id != monitor_id) { ++ return -1; ++ } + dom->type = ISDOMAIN; + if (get_proc_stat(dom) < 0 || get_child_pid(dom) < 0) { + return -1; +diff --git a/src/domain.h b/src/domain.h +index da3b20b..f4ce86b 100644 +--- a/src/domain.h ++++ b/src/domain.h +@@ -24,4 +24,6 @@ struct domain_list { + int refresh_domains(struct domain_list *now, struct domain_list *pre); + void init_domains(struct domain_list *list); + int get_task_num(struct domain_list *list); ++ ++extern int monitor_id; + #endif +diff --git a/src/vmtop.c b/src/vmtop.c +index d9cfb9f..fd3893b 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -65,12 +65,13 @@ static void init_parameter(void) + delay_time = 1; /* default delay 1s between display */ + scr_row_size = 2048; /* defualt size row */ + scr_col_size = 1024; /* default size col */ ++ monitor_id = -1; /* default monitor all domains */ + } + + static void parse_args(int argc, char *argv[]) + { + int opt; +- char *arg_ops = "hvHd:n:b"; ++ char *arg_ops = "hvHd:n:bp:"; + while ((opt = getopt(argc, argv, arg_ops)) != -1) { + switch (opt) { + case 'd': { +@@ -103,6 +104,10 @@ static void parse_args(int argc, char *argv[]) + scr_mode = TEXT_MODE; + break; + } ++ case 'p': { ++ monitor_id = atoi(optarg); ++ break; ++ } + default: + exit(1); /* exit vmtop when args are invalid */ + break; +-- +2.27.0 + diff --git a/bugfix-add-check-to-avoid-invalid-ptr-for-strcmp.patch b/bugfix-add-check-to-avoid-invalid-ptr-for-strcmp.patch new file mode 100644 index 0000000000000000000000000000000000000000..e7afbbd629f610280ab062d60c652122f401d957 --- /dev/null +++ b/bugfix-add-check-to-avoid-invalid-ptr-for-strcmp.patch @@ -0,0 +1,29 @@ +From e08922510af9e543d83c0e54ce89a8b72cc579be Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Thu, 21 Jan 2021 10:57:09 +0800 +Subject: [PATCH] bugfix: add check to avoid invalid ptr for strcmp + +If len of d_name is less than "pid", it will pass a invalid ptr +to strcmp, which will cause crash. +--- + src/domain.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/domain.c b/src/domain.c +index 7f9173d..f8dea48 100644 +--- a/src/domain.c ++++ b/src/domain.c +@@ -253,6 +253,10 @@ static int check_pid_file(const char *d_name) + int extern_len = strlen(extern_name); + int len = strlen(d_name); + ++ if (len <= extern_len) { ++ return -1; ++ } ++ + return strcmp(d_name + len - extern_len, extern_name); + } + +-- +2.27.0 + diff --git a/codestyle-del-unused-var.patch b/codestyle-del-unused-var.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac5d892a95242bf0331c1701d32f05192c4f35bd --- /dev/null +++ b/codestyle-del-unused-var.patch @@ -0,0 +1,27 @@ +From 4d442c4c44252dbaa5ce76c657e5320639cdc8e8 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 7 Dec 2020 15:14:02 +0800 +Subject: [PATCH] codestyle: del unused var + +del unused var in vcpu_stat.c + +Signed-off-by: nocjj <1250062498@qq.com> +--- + src/vcpu_stat.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/vcpu_stat.c b/src/vcpu_stat.c +index 7009d41..5705b9a 100644 +--- a/src/vcpu_stat.c ++++ b/src/vcpu_stat.c +@@ -57,7 +57,6 @@ const int vcpu_stat_size = sizeof(vcpu_stat_stab) / sizeof(struct file_item); + int get_vcpu_list(struct domain_list *list) + { + char buf[BUF_SIZE]; +- unsigned int pid; + FILE *fp = NULL; + + fp = fopen(KVM_VCPU_STAT_PATH, "r"); +-- +2.27.0 + diff --git a/display-add-limit-to-usage-display.patch b/display-add-limit-to-usage-display.patch new file mode 100644 index 0000000000000000000000000000000000000000..bee2339f7cd1bbe246b2a26418662621a18f42a9 --- /dev/null +++ b/display-add-limit-to-usage-display.patch @@ -0,0 +1,101 @@ +From 7246693b6df8aef5d9270252fbccaa07d2f1ac30 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Sun, 27 Sep 2020 19:47:24 +0800 +Subject: [PATCH] display: add limit to usage display + +Because of time accuracy, the usage sometime may be more than vcpu nums. +This is a matter of precision, so add limit to these usage. +--- + src/domain.c | 2 ++ + src/type.h | 1 + + src/vmtop.c | 33 ++++++++++++++++++++++++--------- + 3 files changed, 27 insertions(+), 9 deletions(-) + +diff --git a/src/domain.c b/src/domain.c +index 6b4ac2b..ac15d53 100644 +--- a/src/domain.c ++++ b/src/domain.c +@@ -194,7 +194,9 @@ static int get_child_pid(struct domain *dom) + if (strstr(dom->threads[i].vmname, "CPU") != NULL + && get_vcpu_stat(&(dom->threads[i])) > 0) { + dom->threads[i].type = ISVCPU; ++ dom->smp_vcpus++; + } ++ dom->threads[i].smp_vcpus = 1; + i++; + } + closedir(dirptr); +diff --git a/src/type.h b/src/type.h +index 0e92388..5bbde33 100644 +--- a/src/type.h ++++ b/src/type.h +@@ -141,6 +141,7 @@ struct domain { + DFX_VALUE(vcpu_stime), + DFX_VALUE(gtime); + struct domain *threads; ++ int smp_vcpus; + }; + + enum process_type { +diff --git a/src/vmtop.c b/src/vmtop.c +index 796c67f..4e10df7 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -172,6 +172,10 @@ static void print_domain_field(struct domain *dom, int field) + u64 cpu_jeffies = dom->DELTA_VALUE(utime) + dom->DELTA_VALUE(stime); + double usage = (double)cpu_jeffies * 100 / + sysconf(_SC_CLK_TCK) / delay_time; ++ ++ if (usage >= 100.0 * dom->smp_vcpus) { ++ usage = 100.0 * dom->smp_vcpus; ++ } + print_scr("%*.1f", fields[i].align, usage); + break; + } +@@ -227,23 +231,34 @@ static void print_domain_field(struct domain *dom, int field) + break; + } + case FD_ST: { +- print_scr("%*.1f", fields[i].align, +- (double)dom->DELTA_VALUE(steal) * 100 / +- 1000000000.0f / delay_time); ++ double usage = (double)dom->DELTA_VALUE(steal) * 100 / ++ 1000000000.0f / delay_time; ++ ++ if (usage >= 100.0 * dom->smp_vcpus) { ++ usage = 100.0 * dom->smp_vcpus; ++ } ++ print_scr("%*.1f", fields[i].align, usage); + break; + } + case FD_GUE: { +- print_scr("%*.1f", fields[i].align, +- (double)dom->DELTA_VALUE(gtime) * 100 / +- 1000000000.0f / delay_time); ++ double usage = (double)dom->DELTA_VALUE(gtime) * 100 / ++ 1000000000.0f / delay_time; ++ ++ if (usage >= 100.0 * dom->smp_vcpus) { ++ usage = 100.0 * dom->smp_vcpus; ++ } ++ print_scr("%*.1f", fields[i].align, usage); + break; + } + case FD_HYP: { + u64 hyp_time = dom->DELTA_VALUE(vcpu_utime) - dom->DELTA_VALUE(gtime) + + dom->DELTA_VALUE(vcpu_stime); +- print_scr("%*.1f", fields[i].align, +- (double)hyp_time * 100 / +- 1000000000.0f / delay_time); ++ double usage = (double)hyp_time * 100 / 1000000000.0f / delay_time; ++ ++ if (usage >= 100.0 * dom->smp_vcpus) { ++ usage = 100.0 * dom->smp_vcpus; ++ } ++ print_scr("%*.1f", fields[i].align, usage); + break; + } + default: +-- +2.27.0 + diff --git a/display-del-screen-clear-after-key-response.patch b/display-del-screen-clear-after-key-response.patch new file mode 100644 index 0000000000000000000000000000000000000000..8cc4c6fbbf34b2fa41a00f66c589ffa5f2306689 --- /dev/null +++ b/display-del-screen-clear-after-key-response.patch @@ -0,0 +1,27 @@ +From 6d3565009acece4c6cfcf4a492ef324ed6fda157 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 2 Nov 2020 13:47:22 +0800 +Subject: [PATCH] display: del screen clear after key response + +Clear will cause display to refresh off, so del clear afer key response. + +Signed-off-by: nocjj <1250062498@qq.com> +--- + src/vmtop.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/vmtop.c b/src/vmtop.c +index 693779c..0137fdd 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -489,7 +489,6 @@ int main(int argc, char *argv[]) + key = getch(); + if (key != ERR) { + parse_keys(key); +- clear(); + } + } else { + usleep(delay_time * 1000000); /* wait delay time in text mode */ +-- +2.27.0 + diff --git a/display-expand-CPU-display.patch b/display-expand-CPU-display.patch new file mode 100644 index 0000000000000000000000000000000000000000..6b1dbee3b0bff9124fd3097dfdaa858e7d187ace --- /dev/null +++ b/display-expand-CPU-display.patch @@ -0,0 +1,27 @@ +From cef638cb695cf39996ff02f86c6991660eeedd0e Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Sun, 27 Sep 2020 16:11:45 +0800 +Subject: [PATCH] display: expand %CPU display + +Now, %CPU's align is 6, and is not enough to display VM +that has vcpus more than 10. So expand align to 8. +--- + src/field.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/field.c b/src/field.c +index 6a07fcc..3ae2996 100644 +--- a/src/field.c ++++ b/src/field.c +@@ -36,7 +36,7 @@ FID fields[] = { + {"DID", FIELDS_DISPLAY, 5 }, + {"VM/task-name", FIELDS_DISPLAY, 14 }, + {"PID", FIELDS_DISPLAY, 8 }, +- {"%CPU", FIELDS_DISPLAY, 6 }, ++ {"%CPU", FIELDS_DISPLAY, 8 }, + {"EXThvc", FIELDS_DISPLAY, 10 }, + {"EXTwfe", FIELDS_DISPLAY, 10 }, + {"EXTwfi", FIELDS_DISPLAY, 10 }, +-- +2.27.0 + diff --git a/display-modify-filter-display-to-support-more-displa.patch b/display-modify-filter-display-to-support-more-displa.patch new file mode 100644 index 0000000000000000000000000000000000000000..b9f1b2dc146b4f44fd1ff1f92e1157274ad49b6d --- /dev/null +++ b/display-modify-filter-display-to-support-more-displa.patch @@ -0,0 +1,49 @@ +From c318934474b8aab51e287c4c018d31f0633a1187 Mon Sep 17 00:00:00 2001 +From: Jiajun Chen <1250062498@qq.com> +Date: Wed, 28 Oct 2020 16:38:12 +0800 +Subject: [PATCH] display: modify filter display to support more display fields + items + +If display fields items is more than screen rows, some of fields items +can't be displayed in screen. +So, start another col to show fields items if screen can't show all content in one col. + +Signed-off-by: Jiajun Chen <1250062498@qq.com> +--- + src/vmtop.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/src/vmtop.c b/src/vmtop.c +index d22ddfd..db5c4e0 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -298,11 +298,24 @@ static void show_domains(struct domain_list *list) + */ + static void print_field(int high_light) + { +- int x = 3; /* display x local */ +- int y = 4; /* display y local */ ++ int x, y, x_local, y_local; + unsigned int attr_flag; + ++ getyx(stdscr, y_local, x_local); /* get cursor coordinates */ ++ y = y_local; ++ x = x_local + 3; /* leave 3 spaces in the beginning for beauty */ ++ + for (int i = 0; i < FD_END; i++) { ++ /* ++ * if y local is more than scr_row_size, fields list display will ++ * out of screen range. So start another col to show fields list ++ * with 20 intervals. ++ */ ++ if (y >= scr_row_size) { ++ y = y_local; ++ x = x + 20; ++ } ++ + attr_flag = A_NORMAL; + if (i == high_light) { + attr_flag |= A_REVERSE; /* high light chosen field */ +-- +2.27.0 + diff --git a/key-add-page-up-down-key-response.patch b/key-add-page-up-down-key-response.patch new file mode 100644 index 0000000000000000000000000000000000000000..348e7a077346d62f9721e72985e30bfa72fb4df2 --- /dev/null +++ b/key-add-page-up-down-key-response.patch @@ -0,0 +1,56 @@ +From 7bdc448e2407cd56ec174319f5a6d2a857cf608a Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Thu, 29 Oct 2020 15:35:37 +0800 +Subject: [PATCH] key: add page up/down key response + +Add page up/down key response, move pagesize - 6 for beauty. + +Signed-off-by: Jiajun Chen <1250062498@qq.com> +--- + src/vmtop.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/vmtop.c b/src/vmtop.c +index fd3893b..66485c9 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -392,6 +392,8 @@ static void show_filter(void) + + static void parse_keys(int key) + { ++ int scroll_size = 1; ++ + switch (key) { + case 'f': { + show_filter(); +@@ -401,17 +403,25 @@ static void parse_keys(int key) + quit_flag = !quit_flag; + break; + } ++ case KEY_NPAGE: { ++ /* move pagesize - 6 for beauty */ ++ scroll_size = scr_row_size - 6; ++ } + case KEY_UP: { + int task_num = thread_mode ? get_task_num(&scr_cur) : scr_cur.num; + +- begin_task++; ++ begin_task += scroll_size; + if (begin_task > task_num) { + begin_task = task_num; + } + break; + } ++ case KEY_PPAGE: { ++ /* move pagesize - 6 for beauty */ ++ scroll_size = scr_row_size - 6; ++ } + case KEY_DOWN: { +- begin_task--; ++ begin_task -= scroll_size; + if (begin_task < 1) { + begin_task = 1; + } +-- +2.27.0 + diff --git a/proc-del-prc-pid-comm-read.patch b/proc-del-prc-pid-comm-read.patch new file mode 100644 index 0000000000000000000000000000000000000000..31ed9e57a163926c8f409f8619bb5b53e099d854 --- /dev/null +++ b/proc-del-prc-pid-comm-read.patch @@ -0,0 +1,120 @@ +From c0cc601652c696a7191adc40f434add8a23829af Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 2 Nov 2020 13:44:54 +0800 +Subject: [PATCH] proc: del /prc/pid/comm read + +The content obtained from comm file can also be obtianed from the stat file, +So there is no need to read comm file. + +Signed-off-by: nocjj <1250062498@qq.com> +--- + src/domain.c | 16 ++++++++-------- + src/proc.c | 36 +++++++++++++++--------------------- + 2 files changed, 23 insertions(+), 29 deletions(-) + +diff --git a/src/domain.c b/src/domain.c +index 05f85dd..7f9173d 100644 +--- a/src/domain.c ++++ b/src/domain.c +@@ -190,8 +190,7 @@ static int get_child_pid(struct domain *dom) + } + dom->threads[i].type = ISTHREAD; + dom->threads[i].ppid = dom->pid; +- if (get_proc_stat(&(dom->threads[i])) < 0 || +- get_proc_comm(&(dom->threads[i])) < 0) { ++ if (get_proc_stat(&(dom->threads[i])) < 0) { + continue; + } + if (strstr(dom->threads[i].vmname, "CPU") != NULL && +@@ -213,12 +212,6 @@ static int set_domain(struct domain *dom, const char *name) + char pid[PID_STRING_MAX]; + char *end = NULL; + +- if (len >= DOMAIN_NAME_MAX - 1) { +- return -1; +- } +- strcpy(dom->vmname, name); +- dom->vmname[len - strlen(".pid")] = '\0'; +- + if (snprintf(path, BUF_SIZE, "%s/%s", VAR_RUN_QEMU_PATH, name) < 0) { + return -1; + } +@@ -241,6 +234,13 @@ static int set_domain(struct domain *dom, const char *name) + if (get_proc_stat(dom) < 0 || get_child_pid(dom) < 0) { + return -1; + } ++ ++ if (len >= DOMAIN_NAME_MAX - 1) { ++ return -1; ++ } ++ strcpy(dom->vmname, name); ++ dom->vmname[len - strlen(".pid")] = '\0'; ++ + return 1; + } + +diff --git a/src/proc.c b/src/proc.c +index 2200bf0..0263c67 100644 +--- a/src/proc.c ++++ b/src/proc.c +@@ -70,10 +70,12 @@ int get_proc_stat(struct domain *dom) + { + char buf[BUF_SIZE]; + char path[STAT_PATH_SIZE]; +- char *tmp = NULL; ++ char *tmp1 = NULL; ++ char *tmp2 = NULL; + char *p = NULL; + char *p_next = NULL; + int i = 0; ++ int len; + + if (dom->type == ISDOMAIN) { + if (snprintf(path, STAT_PATH_SIZE, "/proc/%u/stat", dom->pid) < 0) { +@@ -89,11 +91,19 @@ int get_proc_stat(struct domain *dom) + return -1; + } + +- /* read from state item of "...) S ..." */ +- tmp = strrchr(buf, ')'); +- tmp = tmp + 2; ++ /* read comm from "pid (comm) S" */ ++ tmp1 = strrchr(buf, '(') + 1; ++ tmp2 = strrchr(buf, ')'); ++ len = tmp2 - tmp1; ++ if (len >= DOMAIN_NAME_MAX || len < 0) { ++ return -1; ++ } ++ strncpy(dom->vmname, tmp1, len); ++ dom->vmname[len] = '\0'; + +- for (p = strtok_r(tmp, " \t\r\n", &p_next); p && i < stat_size; ++ /* read start from process state */ ++ tmp2 = tmp2 + 2; ++ for (p = strtok_r(tmp2, " \t\r\n", &p_next); p && i < stat_size; + p = strtok_r(NULL, " \t\r\n", &p_next)) { + if (proc_stab[i].get_fun != NULL) { + sscanf(p, proc_stab[i].format, (*proc_stab[i].get_fun)(dom)); +@@ -111,19 +121,3 @@ void refresh_delta_stat(struct domain *new, struct domain *old) + } + } + } +- +-int get_proc_comm(struct domain *dom) +-{ +- char path[STAT_PATH_SIZE]; +- int len; +- +- if (snprintf(path, STAT_PATH_SIZE, "/proc/%u/comm", dom->pid) < 0) { +- return -1; +- } +- +- len = read_file(dom->vmname, DOMAIN_NAME_MAX, path); +- if (len > 1) { +- dom->vmname[len - 1] = '\0'; +- } +- return len; +-} +-- +2.27.0 + diff --git a/vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch b/vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch new file mode 100644 index 0000000000000000000000000000000000000000..038c7ff21c7e17a6ed2ff43b9fb554cd5998d554 --- /dev/null +++ b/vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch @@ -0,0 +1,75 @@ +From 2b3b90ad1239c71f03b6fef1107c76627a7f3deb Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Thu, 29 Oct 2020 14:08:47 +0800 +Subject: [PATCH] vcp_stat: add Max Scheduling Delay time items to display + +Add WAITmax item to display, which represent "Max Scheduling Delay". +Set default width to 9 spaces, and default hidden. +And WAITmax unit is ms. + +Signed-off-by: Jiajun Chen <1250062498@qq.com> +--- + src/field.c | 4 +++- + src/field.h | 1 + + src/vcpu_stat.c | 1 + + src/vmtop.c | 6 ++++++ + 4 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/field.c b/src/field.c +index 8793977..7ff0d44 100644 +--- a/src/field.c ++++ b/src/field.c +@@ -67,8 +67,10 @@ FID fields[] = { + {"P", FIELDS_DISPLAY, 5, GF(processor) }, + {"%ST", FIELDS_DISPLAY, 8, GDF(steal) }, + {"%GUE", FIELDS_DISPLAY, 8, GDF(gtime) }, +- {"%HYP", FIELDS_DISPLAY, 8, NULL } ++ {"%HYP", FIELDS_DISPLAY, 8, NULL }, ++ {"WAITmax", FIELDS_HIDDEN, 9, GF(st_max) } + #undef GDF ++#undef GF + }; + + int get_show_field_num(void) +diff --git a/src/field.h b/src/field.h +index 1fc7182..3a33008 100644 +--- a/src/field.h ++++ b/src/field.h +@@ -47,6 +47,7 @@ enum fields_type { + FD_ST, + FD_GUE, + FD_HYP, ++ FD_WAITMAX, + FD_END + }; + +diff --git a/src/vcpu_stat.c b/src/vcpu_stat.c +index 7ec2371..308e7bb 100644 +--- a/src/vcpu_stat.c ++++ b/src/vcpu_stat.c +@@ -115,4 +115,5 @@ void sum_vcpu_stat(struct domain *dom, struct domain *thread) + (*vcpu_stat_stab[i].sum_fun)(dom, thread); + } + } ++ dom->st_max += thread->st_max; + } +diff --git a/src/vmtop.c b/src/vmtop.c +index db5c4e0..d9cfb9f 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -234,6 +234,12 @@ static void print_domain_field(struct domain *dom, int field) + print_scr("%*.1f", fields[i].align, justify_usage(usage, dom)); + break; + } ++ case FD_WAITMAX: { ++ u64 st_max = *(u64 *)(*fields[i].get_fun)(dom); ++ /* show Max Scheduling Delay time in ms unit */ ++ print_scr("%*.3f", fields[i].align, st_max / 1000000.0f); ++ break; ++ } + default: + break; + } +-- +2.27.0 + diff --git a/vcpu_stat-add-remaining-kvm-exits-items-to-display.patch b/vcpu_stat-add-remaining-kvm-exits-items-to-display.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b0c8fe3089a6a7fbbe8c82cf790df6de9cc0159 --- /dev/null +++ b/vcpu_stat-add-remaining-kvm-exits-items-to-display.patch @@ -0,0 +1,127 @@ +From 40179a3342c9c3403c0224ca1b856d555076d989 Mon Sep 17 00:00:00 2001 +From: Jiajun Chen <1250062498@qq.com> +Date: Wed, 28 Oct 2020 15:58:04 +0800 +Subject: [PATCH] vcpu_stat: add remaining kvm exits items to display + +Add remaining kvm exits items to display, include: +EXTerr, EXTukn, EXTcp153, EXTcp156, EXTcp14m, +EXTcp14l, EXTcp146, EXTsmc, EXTsve, EXTdbg, EXTfail + +Set dafault width to 10 space, and set these items default hidden. + +Signed-off-by: Jiajun Chen <1250062498@qq.com> +--- + src/field.c | 49 ++++++++++++++++++++++++++++++------------------- + src/field.h | 11 +++++++++++ + src/vmtop.c | 13 ++++++++++++- + 3 files changed, 53 insertions(+), 20 deletions(-) + +diff --git a/src/field.c b/src/field.c +index 1fc2fee..8793977 100644 +--- a/src/field.c ++++ b/src/field.c +@@ -38,25 +38,36 @@ FID fields[] = { + #define GDF(f) (void *)GET_DELTA_NAME(f) + #define GF(f) (void *)GET_NAME(f) + /* name . flag . align */ +- {"DID", FIELDS_DISPLAY, 5, NULL }, +- {"VM/task-name", FIELDS_DISPLAY, 14, NULL }, +- {"PID", FIELDS_DISPLAY, 8, NULL }, +- {"%CPU", FIELDS_DISPLAY, 8, NULL }, +- {"EXThvc", FIELDS_DISPLAY, 10, GDF(hvc_exit_stat) }, +- {"EXTwfe", FIELDS_DISPLAY, 10, GDF(wfe_exit_stat) }, +- {"EXTwfi", FIELDS_DISPLAY, 10, GDF(wfi_exit_stat) }, +- {"EXTmmioU", FIELDS_DISPLAY, 10, GDF(mmio_exit_user) }, +- {"EXTmmioK", FIELDS_DISPLAY, 10, GDF(mmio_exit_kernel) }, +- {"EXTfp", FIELDS_DISPLAY, 10, GDF(fp_asimd_exit_stat)}, +- {"EXTirq", FIELDS_DISPLAY, 10, GDF(irq_exit_stat) }, +- {"EXTsys64", FIELDS_DISPLAY, 10, GDF(sys64_exit_stat) }, +- {"EXTmabt", FIELDS_DISPLAY, 10, GDF(mabt_exit_stat) }, +- {"EXTsum", FIELDS_DISPLAY, 10, GDF(exits) }, +- {"S", FIELDS_DISPLAY, 5, GF(state) }, +- {"P", FIELDS_DISPLAY, 5, GF(processor) }, +- {"%ST", FIELDS_DISPLAY, 8, GDF(steal) }, +- {"%GUE", FIELDS_DISPLAY, 8, GDF(gtime) }, +- {"%HYP", FIELDS_DISPLAY, 8, NULL} ++ {"DID", FIELDS_DISPLAY, 5, NULL }, ++ {"VM/task-name", FIELDS_DISPLAY, 14, NULL }, ++ {"PID", FIELDS_DISPLAY, 8, NULL }, ++ {"%CPU", FIELDS_DISPLAY, 8, NULL }, ++ {"EXThvc", FIELDS_DISPLAY, 10, GDF(hvc_exit_stat) }, ++ {"EXTwfe", FIELDS_DISPLAY, 10, GDF(wfe_exit_stat) }, ++ {"EXTwfi", FIELDS_DISPLAY, 10, GDF(wfi_exit_stat) }, ++ {"EXTmmioU", FIELDS_DISPLAY, 10, GDF(mmio_exit_user) }, ++ {"EXTmmioK", FIELDS_DISPLAY, 10, GDF(mmio_exit_kernel) }, ++ {"EXTfp", FIELDS_DISPLAY, 10, GDF(fp_asimd_exit_stat) }, ++ {"EXTirq", FIELDS_DISPLAY, 10, GDF(irq_exit_stat) }, ++ {"EXTsys64", FIELDS_DISPLAY, 10, GDF(sys64_exit_stat) }, ++ {"EXTmabt", FIELDS_DISPLAY, 10, GDF(mabt_exit_stat) }, ++ {"EXTsum", FIELDS_DISPLAY, 10, GDF(exits) }, ++ {"EXTerr", FIELDS_HIDDEN, 10, GDF(internal_error_exit_stat)}, ++ {"EXTukn", FIELDS_HIDDEN, 10, GDF(unknown_ec_exit_stat) }, ++ {"EXTcp153", FIELDS_HIDDEN, 10, GDF(cp15_32_exit_stat) }, ++ {"EXTcp156", FIELDS_HIDDEN, 10, GDF(cp15_64_exit_stat) }, ++ {"EXT14m", FIELDS_HIDDEN, 10, GDF(cp14_mr_exit_stat) }, ++ {"EXT14l", FIELDS_HIDDEN, 10, GDF(cp14_ls_exit_stat) }, ++ {"EXT146", FIELDS_HIDDEN, 10, GDF(cp14_64_exit_stat) }, ++ {"EXTsmc", FIELDS_HIDDEN, 10, GDF(smc_exit_stat) }, ++ {"EXTsve", FIELDS_HIDDEN, 10, GDF(sve_exit_stat) }, ++ {"EXTdbg", FIELDS_HIDDEN, 10, GDF(debug_exit_stat) }, ++ {"EXTfail", FIELDS_HIDDEN, 10, GDF(fail_entry_exit_stat) }, ++ {"S", FIELDS_DISPLAY, 5, GF(state) }, ++ {"P", FIELDS_DISPLAY, 5, GF(processor) }, ++ {"%ST", FIELDS_DISPLAY, 8, GDF(steal) }, ++ {"%GUE", FIELDS_DISPLAY, 8, GDF(gtime) }, ++ {"%HYP", FIELDS_DISPLAY, 8, NULL } + #undef GDF + }; + +diff --git a/src/field.h b/src/field.h +index 88808e7..1fc7182 100644 +--- a/src/field.h ++++ b/src/field.h +@@ -31,6 +31,17 @@ enum fields_type { + FD_EXTSYS64, + FD_EXTMABT, + FD_EXTSUM, ++ FD_EXTERR, ++ FD_EXTUKN, ++ FD_EXTCP153, ++ FD_EXTCP156, ++ FD_EXTCP14M, ++ FD_EXTCP14L, ++ FD_EXTCP146, ++ FD_EXTSMC, ++ FD_EXTSVE, ++ FD_EXTDBG, ++ FD_EXTFAIL, + FD_STATE, + FD_P, + FD_ST, +diff --git a/src/vmtop.c b/src/vmtop.c +index 12b073d..d22ddfd 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -195,7 +195,18 @@ static void print_domain_field(struct domain *dom, int field) + case FD_EXTIRQ: + case FD_EXTSYS64: + case FD_EXTMABT: +- case FD_EXTSUM: { ++ case FD_EXTSUM: ++ case FD_EXTERR: ++ case FD_EXTUKN: ++ case FD_EXTCP153: ++ case FD_EXTCP156: ++ case FD_EXTCP14M: ++ case FD_EXTCP14L: ++ case FD_EXTCP146: ++ case FD_EXTSMC: ++ case FD_EXTSVE: ++ case FD_EXTDBG: ++ case FD_EXTFAIL: { + print_scr("%*llu", fields[i].align, *(u64 *)(*fields[i].get_fun)(dom)); + break; + } +-- +2.27.0 + diff --git a/vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch b/vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch new file mode 100644 index 0000000000000000000000000000000000000000..8bf8906003c2df205acd0595757430cb27288569 --- /dev/null +++ b/vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch @@ -0,0 +1,277 @@ +From 4e8a28fd8491af06d79ed42c2a3ee150ce981702 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 2 Nov 2020 11:36:19 +0800 +Subject: [PATCH] vcpu_stat: get vcpu stat list once per display instead of per + vcpu + +Currently, every time you get vcpu data for vcpu thread, you have to open vcpu_stat file, +which is very time-consuming. If the number of vcpus is large, the display delay will be obvious. +So, save vcpu stat list before every display, and get vcpu stat from list in data refreshing. +And then. the vcpu_stat file will only be opened once in every display. + +Signed-off-by: nocjj <1250062498@qq.com> +--- + src/domain.c | 11 +++--- + src/domain.h | 9 ++--- + src/type.h | 6 ++++ + src/vcpu_stat.c | 91 ++++++++++++++++++++++++++++++++----------------- + src/vcpu_stat.h | 3 +- + src/vmtop.c | 1 + + 6 files changed, 78 insertions(+), 43 deletions(-) + +diff --git a/src/domain.c b/src/domain.c +index 8683115..05f85dd 100644 +--- a/src/domain.c ++++ b/src/domain.c +@@ -26,6 +26,7 @@ + #define TASK_STRING_SIZE 30 + + int monitor_id; ++struct domain_list vcpu_list; + + /* domain list operation */ + void init_domains(struct domain_list *list) +@@ -47,7 +48,7 @@ void clear_domains(struct domain_list *list) + init_domains(list); + } + +-static struct domain *add_domains(struct domain_list *list) ++struct domain *add_domains(struct domain_list *list) + { + struct domain *new_list = malloc(sizeof(struct domain) * (list->num + 1)); + +@@ -193,8 +194,8 @@ static int get_child_pid(struct domain *dom) + get_proc_comm(&(dom->threads[i])) < 0) { + continue; + } +- if (strstr(dom->threads[i].vmname, "CPU") != NULL +- && get_vcpu_stat(&(dom->threads[i])) > 0) { ++ if (strstr(dom->threads[i].vmname, "CPU") != NULL && ++ get_vcpu_stat(&(dom->threads[i]), &vcpu_list) >= 0) { + dom->threads[i].type = ISVCPU; + dom->smp_vcpus++; + } +@@ -305,8 +306,10 @@ int refresh_domains(struct domain_list *now, struct domain_list *pre) + + copy_domains(now, pre); /* save last data int pre */ + clear_domains(now); ++ if (get_vcpu_list(&vcpu_list) < 0) { ++ return -1; ++ } + num = get_qemu_id(now); +- + for (int i = 0; i < now->num; i++) { + int id = now->domains[i].domain_id; + struct domain *old_domain = get_domain_from_id(id, pre); +diff --git a/src/domain.h b/src/domain.h +index f4ce86b..1bb6116 100644 +--- a/src/domain.h ++++ b/src/domain.h +@@ -16,14 +16,11 @@ + #include + #include "type.h" + +-struct domain_list { +- struct domain *domains; +- int num; +-}; +- + int refresh_domains(struct domain_list *now, struct domain_list *pre); + void init_domains(struct domain_list *list); ++void clear_domains(struct domain_list *list); ++struct domain *add_domains(struct domain_list *list); + int get_task_num(struct domain_list *list); +- + extern int monitor_id; ++extern struct domain_list vcpu_list; + #endif +diff --git a/src/type.h b/src/type.h +index ac00b0d..40b7287 100644 +--- a/src/type.h ++++ b/src/type.h +@@ -19,6 +19,7 @@ typedef unsigned long long u64; + + #define DOMAIN_NAME_MAX 256 + #define BUF_SIZE 1024 ++#define MAX_VCPU_NUM 1024 + + #define DELTA_VALUE(v) delta_ ## v + #define DFX_VALUE(v) v, DELTA_VALUE(v) +@@ -145,6 +146,11 @@ struct domain { + int smp_vcpus; + }; + ++struct domain_list { ++ struct domain *domains; ++ int num; ++}; ++ + enum process_type { + ISDOMAIN, + ISVCPU, +diff --git a/src/vcpu_stat.c b/src/vcpu_stat.c +index 308e7bb..7009d41 100644 +--- a/src/vcpu_stat.c ++++ b/src/vcpu_stat.c +@@ -14,46 +14,47 @@ + #include + #include "type.h" + #include "vcpu_stat.h" ++#include "domain.h" + + #define KVM_VCPU_STAT_PATH "/sys/kernel/debug/kvm/vcpu_stat" + + struct file_item vcpu_stat_stab[] = { + #define GDF(f) (void *)GET_NAME(f), (void *)DELTA_NAME(f), (void *)SUM_NAME(f) + #define GF(f) (void *)GET_NAME(f), NULL, NULL +- {"%*u", NULL, NULL, NULL}, +- {"%llu", GDF(hvc_exit_stat)}, +- {"%llu", GDF(wfe_exit_stat)}, +- {"%llu", GDF(wfi_exit_stat)}, +- {"%llu", GDF(mmio_exit_user)}, +- {"%llu", GDF(mmio_exit_kernel)}, +- {"%llu", GDF(exits)}, +- {"%llu", GDF(fp_asimd_exit_stat)}, +- {"%llu", GDF(irq_exit_stat)}, +- {"%llu", GDF(sys64_exit_stat)}, +- {"%llu", GDF(mabt_exit_stat)}, +- {"%llu", GDF(fail_entry_exit_stat)}, ++ {"%u", GF(pid) }, ++ {"%llu", GDF(hvc_exit_stat) }, ++ {"%llu", GDF(wfe_exit_stat) }, ++ {"%llu", GDF(wfi_exit_stat) }, ++ {"%llu", GDF(mmio_exit_user) }, ++ {"%llu", GDF(mmio_exit_kernel) }, ++ {"%llu", GDF(exits) }, ++ {"%llu", GDF(fp_asimd_exit_stat) }, ++ {"%llu", GDF(irq_exit_stat) }, ++ {"%llu", GDF(sys64_exit_stat) }, ++ {"%llu", GDF(mabt_exit_stat) }, ++ {"%llu", GDF(fail_entry_exit_stat) }, + {"%llu", GDF(internal_error_exit_stat)}, +- {"%llu", GDF(unknown_ec_exit_stat)}, +- {"%llu", GDF(cp15_32_exit_stat)}, +- {"%llu", GDF(cp15_64_exit_stat)}, +- {"%llu", GDF(cp14_mr_exit_stat)}, +- {"%llu", GDF(cp14_ls_exit_stat)}, +- {"%llu", GDF(cp14_64_exit_stat)}, +- {"%llu", GDF(smc_exit_stat)}, +- {"%llu", GDF(sve_exit_stat)}, +- {"%llu", GDF(debug_exit_stat)}, +- {"%llu", GDF(steal)}, +- {"%llu", GF(st_max)}, +- {"%llu", GDF(vcpu_utime)}, +- {"%llu", GDF(vcpu_stime)}, +- {"%llu", GDF(gtime)} ++ {"%llu", GDF(unknown_ec_exit_stat) }, ++ {"%llu", GDF(cp15_32_exit_stat) }, ++ {"%llu", GDF(cp15_64_exit_stat) }, ++ {"%llu", GDF(cp14_mr_exit_stat) }, ++ {"%llu", GDF(cp14_ls_exit_stat) }, ++ {"%llu", GDF(cp14_64_exit_stat) }, ++ {"%llu", GDF(smc_exit_stat) }, ++ {"%llu", GDF(sve_exit_stat) }, ++ {"%llu", GDF(debug_exit_stat) }, ++ {"%llu", GDF(steal) }, ++ {"%llu", GF(st_max) }, ++ {"%llu", GDF(vcpu_utime) }, ++ {"%llu", GDF(vcpu_stime) }, ++ {"%llu", GDF(gtime) } + #undef GF + #undef GDF + }; + + const int vcpu_stat_size = sizeof(vcpu_stat_stab) / sizeof(struct file_item); + +-int get_vcpu_stat(struct domain *dom) ++int get_vcpu_list(struct domain_list *list) + { + char buf[BUF_SIZE]; + unsigned int pid; +@@ -63,16 +64,17 @@ int get_vcpu_stat(struct domain *dom) + if (!fp) { + return -1; + } ++ clear_domains(list); + while (fgets(buf, BUF_SIZE - 1, fp)) { + char *p = NULL; + char *p_next = NULL; + int i = 0; + +- /* judge whether vcpu pid is match */ +- sscanf(buf, "%u", &pid); +- if (pid != dom->pid) { +- continue; ++ /* limit vcpu nums to MAX_VCPU_NUM */ ++ if (list->num >= MAX_VCPU_NUM) { ++ break; + } ++ struct domain *dom = add_domains(list); + for (p = strtok_r(buf, " \t\r\n", &p_next); p && i < vcpu_stat_size; + p = strtok_r(NULL, " \t\r\n", &p_next)) { + if (vcpu_stat_stab[i].get_fun) { +@@ -81,9 +83,34 @@ int get_vcpu_stat(struct domain *dom) + } + i++; + } +- break; + } + fclose(fp); ++ return list->num; ++} ++ ++int get_vcpu_stat(struct domain *dom, struct domain_list *vcpu_list) ++{ ++ struct domain *vcpu = NULL; ++ int i; ++ ++ if (!dom || !vcpu_list) { ++ return -1; ++ } ++ for (i = 0; i < vcpu_list->num; i++) { ++ vcpu = &(vcpu_list->domains[i]); ++ if (vcpu->pid == dom->pid) { ++ break; ++ } ++ } ++ if (i >= vcpu_list->num) { ++ return 0; ++ } ++ for (i = 1; i < vcpu_stat_size; i++) { ++ if (vcpu_stat_stab[i].get_fun) { ++ memcpy((*vcpu_stat_stab[i].get_fun)(dom), ++ (*vcpu_stat_stab[i].get_fun)(vcpu), sizeof(u64)); ++ } ++ } + return 1; + } + +diff --git a/src/vcpu_stat.h b/src/vcpu_stat.h +index 6cb665a..edbef86 100644 +--- a/src/vcpu_stat.h ++++ b/src/vcpu_stat.h +@@ -42,7 +42,8 @@ GET_DELTA_FUN(vcpu_utime) + GET_DELTA_FUN(vcpu_stime) + GET_DELTA_FUN(gtime) + +-int get_vcpu_stat(struct domain *dom); ++int get_vcpu_list(struct domain_list *list); ++int get_vcpu_stat(struct domain *dom, struct domain_list *vcpu_list); + void refresh_delta_vcpu_stat(struct domain *new, struct domain *old); + void sum_vcpu_stat(struct domain *dom, struct domain *thread); + #endif +diff --git a/src/vmtop.c b/src/vmtop.c +index 66485c9..693779c 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -54,6 +54,7 @@ static void init_parameter(void) + { + init_domains(&scr_cur); + init_domains(&scr_pre); ++ init_domains(&vcpu_list); + begin_task = 1; + begin_field = 1; + thread_mode = 0; /* default not to show threads */ +-- +2.27.0 + diff --git a/vcpustat-modify-vcpu-info-acquirement-from-debugfs.patch b/vcpustat-modify-vcpu-info-acquirement-from-debugfs.patch new file mode 100644 index 0000000000000000000000000000000000000000..1722d57f18403b63068d74a6c7d5b18072755f94 --- /dev/null +++ b/vcpustat-modify-vcpu-info-acquirement-from-debugfs.patch @@ -0,0 +1,54 @@ +From de04d936a524eee4466335527ab04d847a6617c7 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Sun, 27 Sep 2020 15:25:41 +0800 +Subject: [PATCH] vcpustat: modify vcpu info acquirement from debugfs + +Previous judgement to determine whether the vcpustat info matches the process is: +strstr(buf, pid) == buf + 1 +But there is an exception that the kvm exit times may contain process pid string. +And then, we will calculate the delta between two defferent process. +So, modify this judgement codition. +--- + src/vcpu_stat.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/vcpu_stat.c b/src/vcpu_stat.c +index 2076563..7ec2371 100644 +--- a/src/vcpu_stat.c ++++ b/src/vcpu_stat.c +@@ -15,7 +15,6 @@ + #include "type.h" + #include "vcpu_stat.h" + +-#define PID_STRING_SIZE 20 + #define KVM_VCPU_STAT_PATH "/sys/kernel/debug/kvm/vcpu_stat" + + struct file_item vcpu_stat_stab[] = { +@@ -57,12 +56,9 @@ const int vcpu_stat_size = sizeof(vcpu_stat_stab) / sizeof(struct file_item); + int get_vcpu_stat(struct domain *dom) + { + char buf[BUF_SIZE]; +- char pid[PID_STRING_SIZE]; ++ unsigned int pid; + FILE *fp = NULL; + +- if (snprintf(pid, PID_STRING_SIZE, "%u", dom->pid) < 0) { +- return -1; +- } + fp = fopen(KVM_VCPU_STAT_PATH, "r"); + if (!fp) { + return -1; +@@ -72,7 +68,9 @@ int get_vcpu_stat(struct domain *dom) + char *p_next = NULL; + int i = 0; + +- if (strstr(buf, pid) == NULL) { ++ /* judge whether vcpu pid is match */ ++ sscanf(buf, "%u", &pid); ++ if (pid != dom->pid) { + continue; + } + for (p = strtok_r(buf, " \t\r\n", &p_next); p && i < vcpu_stat_size; +-- +2.27.0 + diff --git a/vmtop-simplify-print_domain_field.patch b/vmtop-simplify-print_domain_field.patch new file mode 100644 index 0000000000000000000000000000000000000000..0bffef537836649d60e64b1bd3179c0e7f976974 --- /dev/null +++ b/vmtop-simplify-print_domain_field.patch @@ -0,0 +1,234 @@ +From 220ccae02af18bdfb05b6611f4fad3c7b21df9a6 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Sun, 27 Sep 2020 20:36:16 +0800 +Subject: [PATCH] vmtop: simplify print_domain_field + +Use array to simplify print_domain_field. +--- + src/field.c | 44 ++++++++++++++----------- + src/field.h | 1 + + src/type.h | 1 + + src/vmtop.c | 92 ++++++++++++++++------------------------------------- + 4 files changed, 54 insertions(+), 84 deletions(-) + +diff --git a/src/field.c b/src/field.c +index 3ae2996..1fc2fee 100644 +--- a/src/field.c ++++ b/src/field.c +@@ -12,6 +12,9 @@ + ********************************************************************************/ + + #include "field.h" ++#include "type.h" ++#include "vcpu_stat.h" ++#include "proc.h" + + const char *summary_text = "" + "vmtop - %s - %s\n" +@@ -32,26 +35,29 @@ const char *version_text = "" + "vmtop-%s\n"; + + FID fields[] = { ++#define GDF(f) (void *)GET_DELTA_NAME(f) ++#define GF(f) (void *)GET_NAME(f) + /* name . flag . align */ +- {"DID", FIELDS_DISPLAY, 5 }, +- {"VM/task-name", FIELDS_DISPLAY, 14 }, +- {"PID", FIELDS_DISPLAY, 8 }, +- {"%CPU", FIELDS_DISPLAY, 8 }, +- {"EXThvc", FIELDS_DISPLAY, 10 }, +- {"EXTwfe", FIELDS_DISPLAY, 10 }, +- {"EXTwfi", FIELDS_DISPLAY, 10 }, +- {"EXTmmioU", FIELDS_DISPLAY, 10 }, +- {"EXTmmioK", FIELDS_DISPLAY, 10 }, +- {"EXTfp", FIELDS_DISPLAY, 10 }, +- {"EXTirq", FIELDS_DISPLAY, 10 }, +- {"EXTsys64", FIELDS_DISPLAY, 10 }, +- {"EXTmabt", FIELDS_DISPLAY, 10 }, +- {"EXTsum", FIELDS_DISPLAY, 10 }, +- {"S", FIELDS_DISPLAY, 5 }, +- {"P", FIELDS_DISPLAY, 5 }, +- {"%ST", FIELDS_DISPLAY, 8 }, +- {"%GUE", FIELDS_DISPLAY, 8 }, +- {"%HYP", FIELDS_DISPLAY, 8 } ++ {"DID", FIELDS_DISPLAY, 5, NULL }, ++ {"VM/task-name", FIELDS_DISPLAY, 14, NULL }, ++ {"PID", FIELDS_DISPLAY, 8, NULL }, ++ {"%CPU", FIELDS_DISPLAY, 8, NULL }, ++ {"EXThvc", FIELDS_DISPLAY, 10, GDF(hvc_exit_stat) }, ++ {"EXTwfe", FIELDS_DISPLAY, 10, GDF(wfe_exit_stat) }, ++ {"EXTwfi", FIELDS_DISPLAY, 10, GDF(wfi_exit_stat) }, ++ {"EXTmmioU", FIELDS_DISPLAY, 10, GDF(mmio_exit_user) }, ++ {"EXTmmioK", FIELDS_DISPLAY, 10, GDF(mmio_exit_kernel) }, ++ {"EXTfp", FIELDS_DISPLAY, 10, GDF(fp_asimd_exit_stat)}, ++ {"EXTirq", FIELDS_DISPLAY, 10, GDF(irq_exit_stat) }, ++ {"EXTsys64", FIELDS_DISPLAY, 10, GDF(sys64_exit_stat) }, ++ {"EXTmabt", FIELDS_DISPLAY, 10, GDF(mabt_exit_stat) }, ++ {"EXTsum", FIELDS_DISPLAY, 10, GDF(exits) }, ++ {"S", FIELDS_DISPLAY, 5, GF(state) }, ++ {"P", FIELDS_DISPLAY, 5, GF(processor) }, ++ {"%ST", FIELDS_DISPLAY, 8, GDF(steal) }, ++ {"%GUE", FIELDS_DISPLAY, 8, GDF(gtime) }, ++ {"%HYP", FIELDS_DISPLAY, 8, NULL} ++#undef GDF + }; + + int get_show_field_num(void) +diff --git a/src/field.h b/src/field.h +index ff98ee4..88808e7 100644 +--- a/src/field.h ++++ b/src/field.h +@@ -43,6 +43,7 @@ typedef struct _field { + const char *name; + int display_flag; + int align; ++ void *(*get_fun)(void *); + } FID; + + extern FID fields[]; +diff --git a/src/type.h b/src/type.h +index 5bbde33..ac00b0d 100644 +--- a/src/type.h ++++ b/src/type.h +@@ -59,6 +59,7 @@ typedef unsigned long long u64; + + #define GET_DELTA_FUN(v) \ + GET_VALUE(v) \ ++ GET_DELTA_VALUE(v) \ + DELTA_FUN(v) \ + SUM_FUN(v) + +diff --git a/src/vmtop.c b/src/vmtop.c +index 4e10df7..12b073d 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -144,6 +144,15 @@ static void show_header(void) + FLUSH_SCR(); + } + ++static double justify_usage(double usage, struct domain *dom) ++{ ++ double ret = usage; ++ if (usage >= 100.0 * dom->smp_vcpus) { ++ ret = 100.0 * dom->smp_vcpus; ++ } ++ return ret; ++} ++ + /* + * show single field of a domain task, align with header + */ +@@ -173,81 +182,37 @@ static void print_domain_field(struct domain *dom, int field) + double usage = (double)cpu_jeffies * 100 / + sysconf(_SC_CLK_TCK) / delay_time; + +- if (usage >= 100.0 * dom->smp_vcpus) { +- usage = 100.0 * dom->smp_vcpus; +- } +- print_scr("%*.1f", fields[i].align, usage); ++ print_scr("%*.1f", fields[i].align, justify_usage(usage, dom)); + break; + } + /* kvm exit fields show */ +- case FD_EXTHVC: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(hvc_exit_stat)); +- break; +- } +- case FD_EXTWFE: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(wfe_exit_stat)); +- break; +- } +- case FD_EXTWFI: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(wfi_exit_stat)); +- break; +- } +- case FD_EXTMMIOU: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(mmio_exit_user)); +- break; +- } +- case FD_EXTMMIOK: { +- print_scr("%*llu", fields[i].align, +- dom->DELTA_VALUE(mmio_exit_kernel)); +- break; +- } +- case FD_EXTFP: { +- print_scr("%*llu", fields[i].align, +- dom->DELTA_VALUE(fp_asimd_exit_stat)); +- break; +- } +- case FD_EXTIRQ: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(irq_exit_stat)); +- break; +- } +- case FD_EXTSYS64: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(sys64_exit_stat)); +- break; +- } +- case FD_EXTMABT: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(mabt_exit_stat)); +- break; +- } ++ case FD_EXTHVC: ++ case FD_EXTWFE: ++ case FD_EXTWFI: ++ case FD_EXTMMIOU: ++ case FD_EXTMMIOK: ++ case FD_EXTFP: ++ case FD_EXTIRQ: ++ case FD_EXTSYS64: ++ case FD_EXTMABT: + case FD_EXTSUM: { +- print_scr("%*llu", fields[i].align, dom->DELTA_VALUE(exits)); ++ print_scr("%*llu", fields[i].align, *(u64 *)(*fields[i].get_fun)(dom)); + break; + } + case FD_STATE: { +- print_scr("%*c", fields[i].align, dom->state); ++ print_scr("%*c", fields[i].align, *(char *)(*fields[i].get_fun)(dom)); + break; + } + case FD_P: { +- print_scr("%*d", fields[i].align, dom->processor); +- break; +- } +- case FD_ST: { +- double usage = (double)dom->DELTA_VALUE(steal) * 100 / +- 1000000000.0f / delay_time; +- +- if (usage >= 100.0 * dom->smp_vcpus) { +- usage = 100.0 * dom->smp_vcpus; +- } +- print_scr("%*.1f", fields[i].align, usage); ++ print_scr("%*d", fields[i].align, *(int *)(*fields[i].get_fun)(dom)); + break; + } ++ case FD_ST: + case FD_GUE: { +- double usage = (double)dom->DELTA_VALUE(gtime) * 100 / +- 1000000000.0f / delay_time; ++ u64 time = *(u64 *)(*fields[i].get_fun)(dom); ++ double usage = (double)time * 100 / 1000000000.0f / delay_time; + +- if (usage >= 100.0 * dom->smp_vcpus) { +- usage = 100.0 * dom->smp_vcpus; +- } +- print_scr("%*.1f", fields[i].align, usage); ++ print_scr("%*.1f", fields[i].align, justify_usage(usage, dom)); + break; + } + case FD_HYP: { +@@ -255,10 +220,7 @@ static void print_domain_field(struct domain *dom, int field) + dom->DELTA_VALUE(vcpu_stime); + double usage = (double)hyp_time * 100 / 1000000000.0f / delay_time; + +- if (usage >= 100.0 * dom->smp_vcpus) { +- usage = 100.0 * dom->smp_vcpus; +- } +- print_scr("%*.1f", fields[i].align, usage); ++ print_scr("%*.1f", fields[i].align, justify_usage(usage, dom)); + break; + } + default: +-- +2.27.0 + diff --git a/vmtop.spec b/vmtop.spec index d1a0acaf6e19818654fe06671dc448a0b410417b..da6609dc379a13c71ef4c531c33f74e6f74ecb0e 100644 --- a/vmtop.spec +++ b/vmtop.spec @@ -1,6 +1,6 @@ Name: vmtop Version: 1.0 -Release: 3 +Release: 4 Summary: A tool for collecting and analyzing data of virtual machine License: Mulan PSL V2 Group: Application/System @@ -13,6 +13,20 @@ Patch0002: display-expand-row-size-in-TEXT-mode.patch Patch0003: bugfix-exit-vmtop-when-arguments-are-invalid.patch Patch0004: bugfix-check-unsigned-number-flip-before-getting-del.patch Patch0005: vmtop-add-h-and-v.patch +Patch0006: vcpustat-modify-vcpu-info-acquirement-from-debugfs.patch +Patch0007: display-expand-CPU-display.patch +Patch0008: display-add-limit-to-usage-display.patch +Patch0009: vmtop-simplify-print_domain_field.patch +Patch0010: vcpu_stat-add-remaining-kvm-exits-items-to-display.patch +Patch0011: display-modify-filter-display-to-support-more-displa.patch +Patch0012: vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch +Patch0013: args-add-p-option.patch +Patch0014: key-add-page-up-down-key-response.patch +Patch0015: vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch +Patch0016: proc-del-prc-pid-comm-read.patch +Patch0017: display-del-screen-clear-after-key-response.patch +Patch0018: codestyle-del-unused-var.patch +Patch0019: bugfix-add-check-to-avoid-invalid-ptr-for-strcmp.patch Requires: libvirt, ncurses @@ -53,6 +67,22 @@ install -m 550 vmtop ${RPM_BUILD_ROOT}/usr/bin/%{name} %{_bindir}/vmtop %changelog +* Thu Jan 21 2021 Huawei Technologies Co., Ltd +- vcpustat: modify vcpu info acquirement from debugfs +- display: expand %CPU display +- display: add limit to usage display +- vmtop: simplify print_domain_field +- vcpu_stat: add remaining kvm exits items to display +- display: modify filter display to support more display fields items +- vcp_stat: add Max Scheduling Delay time items to display +- args: add -p option +- key: add page up/down key response +- vcpu_stat: get vcpu stat list once per display instead of per vcpu +- proc: del /prc/pid/comm read +- display: del screen clear after key response +- codestyle: del unused var +- bugfix: add check to avoid invalid ptr for strcmp + * Mon Sep 21 2020 Ruyi Chen - vmtop: add -h and -v