From 58ffc873ced2cdf115a2f2a3bc08aa49c93a5350 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Sun, 27 Sep 2020 15:25:41 +0800 Subject: [PATCH 01/16] 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. --- ...y-vcpu-info-acquirement-from-debugfs.patch | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 vcpustat-modify-vcpu-info-acquirement-from-debugfs.patch 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 0000000..1722d57 --- /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 + -- Gitee From 866f56889df43258d1594a397640dbbf36f1ffaa Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Sun, 27 Sep 2020 16:11:45 +0800 Subject: [PATCH 02/16] 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. --- display-expand-CPU-display.patch | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 display-expand-CPU-display.patch diff --git a/display-expand-CPU-display.patch b/display-expand-CPU-display.patch new file mode 100644 index 0000000..6b1dbee --- /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 + -- Gitee From cf183d2c0c3a837598bc3d82ecfaad501bae946c Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Sun, 27 Sep 2020 19:47:24 +0800 Subject: [PATCH 03/16] 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. --- display-add-limit-to-usage-display.patch | 101 +++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 display-add-limit-to-usage-display.patch diff --git a/display-add-limit-to-usage-display.patch b/display-add-limit-to-usage-display.patch new file mode 100644 index 0000000..bee2339 --- /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 + -- Gitee From 7e667d2220f65fdfb76e87fba8febc795ff096d0 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Sun, 27 Sep 2020 20:36:16 +0800 Subject: [PATCH 04/16] vmtop: simplify print_domain_field Use array to simplify print_domain_field. --- vmtop-simplify-print_domain_field.patch | 234 ++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 vmtop-simplify-print_domain_field.patch diff --git a/vmtop-simplify-print_domain_field.patch b/vmtop-simplify-print_domain_field.patch new file mode 100644 index 0000000..0bffef5 --- /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 + -- Gitee From af28dfc823839df78f252b5063d78c91d77b54a3 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Wed, 28 Oct 2020 15:58:04 +0800 Subject: [PATCH 05/16] 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..3b0c8fe --- /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 + -- Gitee From fc1c68603ad37482f0acd7b31cdf0cc43d4a6723 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Wed, 28 Oct 2020 16:38:12 +0800 Subject: [PATCH 06/16] 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..b9f1b2d --- /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 + -- Gitee From 67d0047bfbd7ae38da1055e03956fe2d48fc1d0b Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 29 Oct 2020 14:08:47 +0800 Subject: [PATCH 07/16] 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..038c7ff --- /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 + -- Gitee From 54b5491ac1a3453759700fbec5dd2f3e1dbccf2f Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 29 Oct 2020 14:18:42 +0800 Subject: [PATCH 08/16] 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..520e551 --- /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 + -- Gitee From a1f2c6d05ea3acf38d6200ea56a0ee779324f69f Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 29 Oct 2020 15:35:37 +0800 Subject: [PATCH 09/16] 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..348e7a0 --- /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 + -- Gitee From 5217d8dc81869ad909a1f10ec0d9f61e2aaa7466 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 2 Nov 2020 11:36:19 +0800 Subject: [PATCH 10/16] 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..8bf8906 --- /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 + -- Gitee From d281abdd61011683172e4dee224c8fe5d3c0cf95 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 2 Nov 2020 13:44:54 +0800 Subject: [PATCH 11/16] 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..31ed9e5 --- /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 + -- Gitee From c225b75f70e5cc5ffe25e3e2f94f4ab47f32e910 Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 2 Nov 2020 13:47:22 +0800 Subject: [PATCH 12/16] 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..8cc4c6f --- /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 + -- Gitee From d5523484b44d194c6d2e84bfff3e1c09d06b7efa Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Mon, 7 Dec 2020 15:14:02 +0800 Subject: [PATCH 13/16] 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..ac5d892 --- /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 + -- Gitee From e1bc35bd786d8d3d9ba1250b2f1162e1b875048f Mon Sep 17 00:00:00 2001 From: "Huawei Technologies Co., Ltd" Date: Thu, 21 Jan 2021 10:57:09 +0800 Subject: [PATCH 14/16] 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..e7afbbd --- /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 + -- Gitee From 9cf52bc7b86a028bbfe5cb9c85e9765372553721 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 26 Jan 2021 11:57:24 +0800 Subject: [PATCH 15/16] spec: Update patch and changelog with !19 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 Signed-off-by: Jiajun Chen <1250062498@qq.com> Signed-off-by: nocjj <1250062498@qq.com> --- vmtop.spec | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/vmtop.spec b/vmtop.spec index d1a0aca..9811a2b 100644 --- a/vmtop.spec +++ b/vmtop.spec @@ -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 -- Gitee From 4c5f9865cd22ce6f0632814cbe28269673f7f22a Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Tue, 26 Jan 2021 11:57:28 +0800 Subject: [PATCH 16/16] spec: Update release version with !19 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 9811a2b..da6609d 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 -- Gitee