From 161f0e3ae7780af51e09c974aa67c81064e374e5 Mon Sep 17 00:00:00 2001 From: nocjj <1250062498@qq.com> Date: Thu, 14 Jan 2021 15:01:26 +0800 Subject: [PATCH] sync code from openeuler:vmtop and update release to 2 --- arch-add-x86-kvm-exits-items.patch | 311 ++++++++++++++++++ args-add-p-option.patch | 84 +++++ codestyle-del-unused-var.patch | 27 ++ ...-del-screen-clear-after-key-response.patch | 27 ++ key-add-page-up-down-key-response.patch | 56 ++++ proc-del-prc-pid-comm-read.patch | 120 +++++++ ...-Scheduling-Delay-time-items-to-disp.patch | 75 +++++ ...pu-stat-list-once-per-display-instea.patch | 277 ++++++++++++++++ vmtop.spec | 20 +- 9 files changed, 996 insertions(+), 1 deletion(-) create mode 100644 arch-add-x86-kvm-exits-items.patch create mode 100644 args-add-p-option.patch create mode 100644 codestyle-del-unused-var.patch create mode 100644 display-del-screen-clear-after-key-response.patch create mode 100644 key-add-page-up-down-key-response.patch create mode 100644 proc-del-prc-pid-comm-read.patch create mode 100644 vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch create mode 100644 vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch diff --git a/arch-add-x86-kvm-exits-items.patch b/arch-add-x86-kvm-exits-items.patch new file mode 100644 index 0000000..49d70e0 --- /dev/null +++ b/arch-add-x86-kvm-exits-items.patch @@ -0,0 +1,311 @@ +From 697ed50e404408d34e19afc493e5fe8270cc3433 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 2 Nov 2020 19:07:29 +0800 +Subject: [PATCH 7/8] arch: add x86 kvm exits items + +add x86 support for vmtop + +Signed-off-by: nocjj <1250062498@qq.com> +--- + src/field.c | 26 ++++++++++++++++++++++++++ + src/field.h | 26 ++++++++++++++++++++++++++ + src/type.h | 33 +++++++++++++++++++++++++++++++++ + src/vcpu_stat.c | 34 ++++++++++++++++++++++++++++++++++ + src/vcpu_stat.h | 33 +++++++++++++++++++++++++++++++++ + src/vmtop.c | 26 ++++++++++++++++++++++++++ + 6 files changed, 178 insertions(+) + +diff --git a/src/field.c b/src/field.c +index 7ff0d44..418d642 100644 +--- a/src/field.c ++++ b/src/field.c +@@ -42,6 +42,7 @@ FID fields[] = { + {"VM/task-name", FIELDS_DISPLAY, 14, NULL }, + {"PID", FIELDS_DISPLAY, 8, NULL }, + {"%CPU", FIELDS_DISPLAY, 8, NULL }, ++#ifdef __aarch64__ + {"EXThvc", FIELDS_DISPLAY, 10, GDF(hvc_exit_stat) }, + {"EXTwfe", FIELDS_DISPLAY, 10, GDF(wfe_exit_stat) }, + {"EXTwfi", FIELDS_DISPLAY, 10, GDF(wfi_exit_stat) }, +@@ -63,6 +64,31 @@ FID fields[] = { + {"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) }, ++#else ++ {"PFfix", FIELDS_HIDDEN, 10, GDF(pf_fixed) }, ++ {"PFgu", FIELDS_HIDDEN, 10, GDF(pf_guest) }, ++ {"INvlpg", FIELDS_HIDDEN, 10, GDF(invlpg) }, ++ {"EXTio", FIELDS_HIDDEN, 10, GDF(io_exits) }, ++ {"EXTmmio", FIELDS_HIDDEN, 10, GDF(mmio_exits) }, ++ {"EXTsum", FIELDS_DISPLAY, 10, GDF(exits) }, ++ {"EXThalt", FIELDS_HIDDEN, 10, GDF(halt_exits) }, ++ {"EXTsig", FIELDS_HIDDEN, 10, GDF(signal_exits) }, ++ {"EXTirq", FIELDS_HIDDEN, 10, GDF(irq_exits) }, ++ {"EXTnmiW", FIELDS_HIDDEN, 10, GDF(nmi_window_exits) }, ++ {"EXTirqW", FIELDS_HIDDEN, 10, GDF(irq_window_exits) }, ++ {"IrqIn", FIELDS_HIDDEN, 10, GDF(irq_injections) }, ++ {"NmiIn", FIELDS_HIDDEN, 10, GDF(nmi_injections) }, ++ {"TLBfl", FIELDS_HIDDEN, 10, GDF(tlb_flush) }, ++ {"HostReL", FIELDS_HIDDEN, 10, GDF(host_state_reload) }, ++ {"Hyperv", FIELDS_HIDDEN, 10, GDF(hypercalls) }, ++ {"EXTcr", FIELDS_HIDDEN, 10, GDF(cr_exits) }, ++ {"EXTrmsr", FIELDS_HIDDEN, 10, GDF(msr_rd_exits) }, ++ {"EXTwmsr", FIELDS_HIDDEN, 10, GDF(msr_wr_exits) }, ++ {"EXTapic", FIELDS_HIDDEN, 10, GDF(apic_wr_exits) }, ++ {"EXTeptv", FIELDS_DISPLAY, 10, GDF(ept_vio_exits) }, ++ {"EXTeptm", FIELDS_HIDDEN, 10, GDF(ept_mis_exits) }, ++ {"EXTpau", FIELDS_DISPLAY, 10, GDF(pause_exits) }, ++#endif + {"S", FIELDS_DISPLAY, 5, GF(state) }, + {"P", FIELDS_DISPLAY, 5, GF(processor) }, + {"%ST", FIELDS_DISPLAY, 8, GDF(steal) }, +diff --git a/src/field.h b/src/field.h +index 3a33008..8ce047a 100644 +--- a/src/field.h ++++ b/src/field.h +@@ -21,6 +21,7 @@ enum fields_type { + FD_VMNAME, + FD_PID, + FD_CPU, ++#ifdef __aarch64__ + FD_EXTHVC, + FD_EXTWFE, + FD_EXTWFI, +@@ -42,6 +43,31 @@ enum fields_type { + FD_EXTSVE, + FD_EXTDBG, + FD_EXTFAIL, ++#else ++ FD_PFFIXED, ++ FD_PFGUEST, ++ FD_INVLPG, ++ FD_IOEXITS, ++ FD_MMIOEXITS, ++ FD_EXTSUM, ++ FD_EXTHALT, ++ FD_EXTSIG, ++ FD_EXTIRQ, ++ FD_EXTNMIW, ++ FD_EXTIRQW, ++ FD_IRQIN, ++ FD_NMIIN, ++ FD_TLB, ++ FD_HOSTREL, ++ FD_HYPERV, ++ FD_EXTCR, ++ FD_EXTRMSR, ++ FD_EXTWMSR, ++ FD_EXTAPIC, ++ FD_EXTEPTV, ++ FD_EXTEPTM, ++ FD_EXTPAU, ++#endif + FD_STATE, + FD_P, + FD_ST, +diff --git a/src/type.h b/src/type.h +index 40b7287..3c08387 100644 +--- a/src/type.h ++++ b/src/type.h +@@ -116,6 +116,7 @@ struct domain { + start_time; + /* vcpu_stat items */ + u64 ++#ifdef __aarch64__ + DFX_VALUE(hvc_exit_stat), + DFX_VALUE(wfe_exit_stat), + DFX_VALUE(wfi_exit_stat), +@@ -137,6 +138,38 @@ struct domain { + DFX_VALUE(smc_exit_stat), + DFX_VALUE(sve_exit_stat), + DFX_VALUE(debug_exit_stat), ++#else ++ DFX_VALUE(pf_fixed), ++ DFX_VALUE(pf_guest), ++ DFX_VALUE(tlb_flush), ++ DFX_VALUE(invlpg), ++ DFX_VALUE(exits), ++ DFX_VALUE(io_exits), ++ DFX_VALUE(mmio_exits), ++ DFX_VALUE(signal_exits), ++ DFX_VALUE(irq_window_exits), ++ DFX_VALUE(nmi_window_exits), ++ DFX_VALUE(halt_exits), ++ DFX_VALUE(halt_successful_poll), ++ DFX_VALUE(halt_attempted_poll), ++ DFX_VALUE(halt_wakeup), ++ DFX_VALUE(request_irq_exits), ++ DFX_VALUE(irq_exits), ++ DFX_VALUE(host_state_reload), ++ DFX_VALUE(fpu_reload), ++ DFX_VALUE(insn_emulation), ++ DFX_VALUE(insn_emulation_fail), ++ DFX_VALUE(hypercalls), ++ DFX_VALUE(irq_injections), ++ DFX_VALUE(nmi_injections), ++ DFX_VALUE(cr_exits), ++ DFX_VALUE(msr_rd_exits), ++ DFX_VALUE(msr_wr_exits), ++ DFX_VALUE(apic_wr_exits), ++ DFX_VALUE(ept_vio_exits), ++ DFX_VALUE(ept_mis_exits), ++ DFX_VALUE(pause_exits), ++#endif + DFX_VALUE(steal), + st_max, + DFX_VALUE(vcpu_utime), +diff --git a/src/vcpu_stat.c b/src/vcpu_stat.c +index 7009d41..55cfc7b 100644 +--- a/src/vcpu_stat.c ++++ b/src/vcpu_stat.c +@@ -22,6 +22,7 @@ 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", GF(pid) }, ++#ifdef __aarch64__ + {"%llu", GDF(hvc_exit_stat) }, + {"%llu", GDF(wfe_exit_stat) }, + {"%llu", GDF(wfi_exit_stat) }, +@@ -43,11 +44,44 @@ struct file_item vcpu_stat_stab[] = { + {"%llu", GDF(smc_exit_stat) }, + {"%llu", GDF(sve_exit_stat) }, + {"%llu", GDF(debug_exit_stat) }, ++#else ++ {"%llu", GDF(pf_fixed) }, ++ {"%llu", GDF(pf_guest) }, ++ {"%llu", GDF(tlb_flush) }, ++ {"%llu", GDF(invlpg) }, ++ {"%llu", GDF(exits) }, ++ {"%llu", GDF(io_exits) }, ++ {"%llu", GDF(mmio_exits) }, ++ {"%llu", GDF(signal_exits) }, ++ {"%llu", GDF(irq_window_exits) }, ++ {"%llu", GDF(nmi_window_exits) }, ++ {"%llu", GDF(halt_exits) }, ++ {"%llu", GDF(halt_successful_poll) }, ++ {"%llu", GDF(halt_attempted_poll) }, ++ {"%llu", GDF(halt_wakeup) }, ++ {"%llu", GDF(request_irq_exits) }, ++ {"%llu", GDF(irq_exits) }, ++ {"%llu", GDF(host_state_reload) }, ++ {"%llu", GDF(fpu_reload) }, ++ {"%llu", GDF(insn_emulation) }, ++ {"%llu", GDF(insn_emulation_fail) }, ++ {"%llu", GDF(hypercalls) }, ++ {"%llu", GDF(irq_injections) }, ++ {"%llu", GDF(nmi_injections) }, ++ {"%llu", GDF(cr_exits) }, ++ {"%llu", GDF(msr_rd_exits) }, ++ {"%llu", GDF(msr_wr_exits) }, ++ {"%llu", GDF(apic_wr_exits) }, ++ {"%llu", GDF(ept_vio_exits) }, ++ {"%llu", GDF(ept_mis_exits) }, ++ {"%llu", GDF(pause_exits) }, ++#endif + {"%llu", GDF(steal) }, + {"%llu", GF(st_max) }, + {"%llu", GDF(vcpu_utime) }, + {"%llu", GDF(vcpu_stime) }, + {"%llu", GDF(gtime) } ++ + #undef GF + #undef GDF + }; +diff --git a/src/vcpu_stat.h b/src/vcpu_stat.h +index edbef86..9b3f4c2 100644 +--- a/src/vcpu_stat.h ++++ b/src/vcpu_stat.h +@@ -15,6 +15,7 @@ + + /* vcpu_stat items get fun */ + GET_VALUE(pid) ++#ifdef __aarch64__ + GET_DELTA_FUN(hvc_exit_stat) + GET_DELTA_FUN(wfe_exit_stat) + GET_DELTA_FUN(wfi_exit_stat) +@@ -36,6 +37,38 @@ GET_DELTA_FUN(cp14_64_exit_stat) + GET_DELTA_FUN(smc_exit_stat) + GET_DELTA_FUN(sve_exit_stat) + GET_DELTA_FUN(debug_exit_stat) ++#else ++GET_DELTA_FUN(pf_fixed) ++GET_DELTA_FUN(pf_guest) ++GET_DELTA_FUN(tlb_flush) ++GET_DELTA_FUN(invlpg) ++GET_DELTA_FUN(exits) ++GET_DELTA_FUN(io_exits) ++GET_DELTA_FUN(mmio_exits) ++GET_DELTA_FUN(signal_exits) ++GET_DELTA_FUN(irq_window_exits) ++GET_DELTA_FUN(nmi_window_exits) ++GET_DELTA_FUN(halt_exits) ++GET_DELTA_FUN(halt_successful_poll) ++GET_DELTA_FUN(halt_attempted_poll) ++GET_DELTA_FUN(halt_wakeup) ++GET_DELTA_FUN(request_irq_exits) ++GET_DELTA_FUN(irq_exits) ++GET_DELTA_FUN(host_state_reload) ++GET_DELTA_FUN(fpu_reload) ++GET_DELTA_FUN(insn_emulation) ++GET_DELTA_FUN(insn_emulation_fail) ++GET_DELTA_FUN(hypercalls) ++GET_DELTA_FUN(irq_injections) ++GET_DELTA_FUN(nmi_injections) ++GET_DELTA_FUN(cr_exits) ++GET_DELTA_FUN(msr_rd_exits) ++GET_DELTA_FUN(msr_wr_exits) ++GET_DELTA_FUN(apic_wr_exits) ++GET_DELTA_FUN(ept_vio_exits) ++GET_DELTA_FUN(ept_mis_exits) ++GET_DELTA_FUN(pause_exits) ++#endif + GET_DELTA_FUN(steal) + GET_VALUE(st_max) + GET_DELTA_FUN(vcpu_utime) +diff --git a/src/vmtop.c b/src/vmtop.c +index 0137fdd..f5fd4bd 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -192,6 +192,7 @@ static void print_domain_field(struct domain *dom, int field) + break; + } + /* kvm exit fields show */ ++#ifdef __aarch64__ + case FD_EXTHVC: + case FD_EXTWFE: + case FD_EXTWFI: +@@ -213,6 +214,31 @@ static void print_domain_field(struct domain *dom, int field) + case FD_EXTSVE: + case FD_EXTDBG: + case FD_EXTFAIL: { ++#else ++ case FD_PFFIXED: ++ case FD_PFGUEST: ++ case FD_INVLPG: ++ case FD_IOEXITS: ++ case FD_MMIOEXITS: ++ case FD_EXTSUM: ++ case FD_EXTHALT: ++ case FD_EXTSIG: ++ case FD_EXTIRQ: ++ case FD_EXTNMIW: ++ case FD_EXTIRQW: ++ case FD_IRQIN: ++ case FD_NMIIN: ++ case FD_TLB: ++ case FD_HOSTREL: ++ case FD_HYPERV: ++ case FD_EXTCR: ++ case FD_EXTRMSR: ++ case FD_EXTWMSR: ++ case FD_EXTAPIC: ++ case FD_EXTEPTV: ++ case FD_EXTEPTM: ++ case FD_EXTPAU: { ++#endif + print_scr("%*llu", fields[i].align, *(u64 *)(*fields[i].get_fun)(dom)); + break; + } +-- +2.27.0 + diff --git a/args-add-p-option.patch b/args-add-p-option.patch new file mode 100644 index 0000000..827ffb6 --- /dev/null +++ b/args-add-p-option.patch @@ -0,0 +1,84 @@ +From c38bd9e30368d521554dc56cea094d6ff2312636 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Thu, 29 Oct 2020 14:18:42 +0800 +Subject: [PATCH 2/8] 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 d22ddfd..f4ef9ab 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/codestyle-del-unused-var.patch b/codestyle-del-unused-var.patch new file mode 100644 index 0000000..1bc157c --- /dev/null +++ b/codestyle-del-unused-var.patch @@ -0,0 +1,27 @@ +From 6d13d03943965d0f7c923de40d243c35105d75de Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 7 Dec 2020 15:14:02 +0800 +Subject: [PATCH 8/8] 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-del-screen-clear-after-key-response.patch b/display-del-screen-clear-after-key-response.patch new file mode 100644 index 0000000..8022eb7 --- /dev/null +++ b/display-del-screen-clear-after-key-response.patch @@ -0,0 +1,27 @@ +From 101713bbe26fc60721de1259df15232ccd6aab50 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 2 Nov 2020 13:47:22 +0800 +Subject: [PATCH 6/8] 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/key-add-page-up-down-key-response.patch b/key-add-page-up-down-key-response.patch new file mode 100644 index 0000000..147b51b --- /dev/null +++ b/key-add-page-up-down-key-response.patch @@ -0,0 +1,56 @@ +From 10be69aa54764c8314501fd1130d9bf8c9f859f2 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Thu, 29 Oct 2020 15:35:37 +0800 +Subject: [PATCH 3/8] 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 f4ef9ab..65181a1 100644 +--- a/src/vmtop.c ++++ b/src/vmtop.c +@@ -373,6 +373,8 @@ static void show_filter(void) + + static void parse_keys(int key) + { ++ int scroll_size = 1; ++ + switch (key) { + case 'f': { + show_filter(); +@@ -382,17 +384,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 0000000..bed0fe3 --- /dev/null +++ b/proc-del-prc-pid-comm-read.patch @@ -0,0 +1,120 @@ +From 11d95f0d941825ba183115cd24ab2ea2242ed805 Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 2 Nov 2020 13:44:54 +0800 +Subject: [PATCH 5/8] 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 0000000..2305af6 --- /dev/null +++ b/vcp_stat-add-Max-Scheduling-Delay-time-items-to-disp.patch @@ -0,0 +1,75 @@ +From d7093b894ee00a11e2fdf21c859215fcf535b2de Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Thu, 29 Oct 2020 14:08:47 +0800 +Subject: [PATCH 1/8] 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 d22ddfd..27126b9 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-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..3501fe2 --- /dev/null +++ b/vcpu_stat-get-vcpu-stat-list-once-per-display-instea.patch @@ -0,0 +1,277 @@ +From c5d5370affb56c3f02c6b6dbdabc28138be9522a Mon Sep 17 00:00:00 2001 +From: nocjj <1250062498@qq.com> +Date: Mon, 2 Nov 2020 11:36:19 +0800 +Subject: [PATCH 4/8] 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/vmtop.spec b/vmtop.spec index c74c438..4b03652 100644 --- a/vmtop.spec +++ b/vmtop.spec @@ -1,6 +1,6 @@ Name: vmtop Version: 1.1 -Release: 1 +Release: 2 Summary: A tool for collecting and analyzing data of virtual machine License: Mulan PSL V2 Group: Application/System @@ -19,6 +19,14 @@ 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: arch-add-x86-kvm-exits-items.patch +Patch0019: codestyle-del-unused-var.patch Requires: libvirt, ncurses @@ -59,6 +67,16 @@ install -m 550 vmtop ${RPM_BUILD_ROOT}/usr/bin/%{name} %{_bindir}/vmtop %changelog +* Thu 14 Jan 2021 Jiajun Chen <1250062498@qq.com> -1.1-2 +- 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 +- arch: add x86 kvm exits items +- codestyle: del unused var + * Wed Oct 28 2020 Huawei Technologies Co., Ltd - display: modify filter display to support more display fields items -- Gitee