From 4e508c7b7c6f572a60b0118bfb2c93206144de96 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Wed, 28 Oct 2020 15:58:04 +0800 Subject: [PATCH 01/12] 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> --- ...remaining-kvm-exits-items-to-display.patch | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 vcpu_stat-add-remaining-kvm-exits-items-to-display.patch 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 0000000..30f6419 --- /dev/null +++ b/vcpu_stat-add-remaining-kvm-exits-items-to-display.patch @@ -0,0 +1,127 @@ +From d39ba9500c4fd87d0aec74e61ee7ec5936bb7f1b 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 + -- Gitee From 016b3bbed39b7e242dd1d12fd0b2540426826570 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Wed, 28 Oct 2020 16:38:12 +0800 Subject: [PATCH 02/12] 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> --- ...ilter-display-to-support-more-displa.patch | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 display-modify-filter-display-to-support-more-displa.patch 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 0000000..eea72a7 --- /dev/null +++ b/display-modify-filter-display-to-support-more-displa.patch @@ -0,0 +1,49 @@ +From 3cf4573472785b697b1e7b103f0792f21e4b63a1 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 + -- Gitee From faded99b8a7181f5426ab3775d2bc5975c31cc00 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 29 Oct 2020 14:08:47 +0800 Subject: [PATCH 03/12] 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> --- ...-Scheduling-Delay-time-items-to-disp.patch | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch 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 0000000..d9b7d7c --- /dev/null +++ b/vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch @@ -0,0 +1,75 @@ +From 870b3c407d4b590ed38a4563ce5eb4e650c17e46 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 + -- Gitee From 212f29596f836ee45d1416cd30ca68f7412f17a9 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 29 Oct 2020 14:18:42 +0800 Subject: [PATCH 04/12] 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> --- args-add-p-option.patch | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 args-add-p-option.patch diff --git a/args-add-p-option.patch b/args-add-p-option.patch new file mode 100644 index 0000000..7cc7e6e --- /dev/null +++ b/args-add-p-option.patch @@ -0,0 +1,84 @@ +From 6a68b5f025cffaa1b729f4ec7e5452628dacca82 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 + -- Gitee From eba8f4a5531ffd0cc3d7c8d3c2451f945609e96a Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 29 Oct 2020 15:35:37 +0800 Subject: [PATCH 05/12] 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> --- key-add-page-up-down-key-response.patch | 56 +++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 key-add-page-up-down-key-response.patch 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 0000000..b07b154 --- /dev/null +++ b/key-add-page-up-down-key-response.patch @@ -0,0 +1,56 @@ +From f6fd0a0c71ac6b26ccfb12dc14df185a2ba0e45c 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 + -- Gitee From 93ce1236420f675f40e3974eeb4c210c2dac3145 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 2 Nov 2020 11:36:19 +0800 Subject: [PATCH 06/12] 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> --- ...pu-stat-list-once-per-display-instea.patch | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch 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 0000000..f47a57e --- /dev/null +++ b/vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch @@ -0,0 +1,277 @@ +From 926a9273ce0d2e7f07ee2b8b210966f5d6c8018f 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 + -- Gitee From 69f0a340cb14e6cf088589ba8e5ed03c42100935 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 2 Nov 2020 13:44:54 +0800 Subject: [PATCH 07/12] 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> --- proc-del-prc-pid-comm-read.patch | 120 +++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 proc-del-prc-pid-comm-read.patch diff --git a/proc-del-prc-pid-comm-read.patch b/proc-del-prc-pid-comm-read.patch new file mode 100644 index 0000000..1fe00a4 --- /dev/null +++ b/proc-del-prc-pid-comm-read.patch @@ -0,0 +1,120 @@ +From 8f711370b2a10266afc9d8a2d35fac540be4a3bc 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 + -- Gitee From c8ed95eb9cad1960d0aa4003a5920747138025c0 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 2 Nov 2020 13:47:22 +0800 Subject: [PATCH 08/12] 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> --- ...-del-screen-clear-after-key-response.patch | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 display-del-screen-clear-after-key-response.patch 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 0000000..c688885 --- /dev/null +++ b/display-del-screen-clear-after-key-response.patch @@ -0,0 +1,27 @@ +From 45c478a8a42ebd9b1d5e0ca57f7595b416c70b48 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 + -- Gitee From 3e382606b9f734ffe94e3b8ce2b3c17d4d4d20ff Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 7 Dec 2020 15:14:02 +0800 Subject: [PATCH 09/12] codestyle: del unused var del unused var in vcpu_stat.c Signed-off-by: nocjj <1250062498@qq.com> --- codestyle-del-unused-var.patch | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 codestyle-del-unused-var.patch diff --git a/codestyle-del-unused-var.patch b/codestyle-del-unused-var.patch new file mode 100644 index 0000000..d69d657 --- /dev/null +++ b/codestyle-del-unused-var.patch @@ -0,0 +1,27 @@ +From 48dd3e3f4fb7e7f7b46b4711ff7300641b6e6f6b 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 + -- Gitee From 975db205ab085175c80ca9283c4e896c0fd2f24b Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 21 Jan 2021 10:57:09 +0800 Subject: [PATCH 10/12] 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. --- ...heck-to-avoid-invalid-ptr-for-strcmp.patch | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 bugfix-add-check-to-avoid-invalid-ptr-for-strcmp.patch 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 0000000..f5b1c36 --- /dev/null +++ b/bugfix-add-check-to-avoid-invalid-ptr-for-strcmp.patch @@ -0,0 +1,29 @@ +From 5e4d32547342814d1df1b7fb81824a6ba94ab89b 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 + -- Gitee From 4c861e05d9338eb950eb01894ab59e7754810003 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Wed, 27 Jan 2021 11:57:22 +0800 Subject: [PATCH 11/12] spec: Update patch and changelog with !18 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 Signed-off-by: Jiajun Chen <1250062498@qq.com> Signed-off-by: nocjj <1250062498@qq.com> --- vmtop.spec | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/vmtop.spec b/vmtop.spec index ce05037..0ca62d9 100644 --- a/vmtop.spec +++ b/vmtop.spec @@ -17,6 +17,16 @@ 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 @@ -57,6 +67,18 @@ install -m 550 vmtop ${RPM_BUILD_ROOT}/usr/bin/%{name} %{_bindir}/vmtop %changelog +* Thu Jan 21 2021 Huawei Technologies Co., Ltd +- 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 + * Sat Oct 10 2020 Jiajun Chen <1250062498@qq.com> -1.1-0 - spec: modify source url -- Gitee From cae6056ca499e7ea28c2510ddcb2be442276c5db Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Wed, 27 Jan 2021 11:57:22 +0800 Subject: [PATCH 12/12] spec: Update release version with !18 increase release verison by one Signed-off-by: Euler Robot --- vmtop.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmtop.spec b/vmtop.spec index 0ca62d9..094e1e0 100644 --- a/vmtop.spec +++ b/vmtop.spec @@ -1,6 +1,6 @@ Name: vmtop Version: 1.1 -Release: 0 +Release: 1 Summary: A tool for collecting and analyzing data of virtual machine License: Mulan PSL V2 Group: Application/System -- Gitee