From d8f7c634054c6336d96a159070fdb87b18d833ca Mon Sep 17 00:00:00 2001 From: nocjj <1250062498@qq.com> Date: Sun, 27 Sep 2020 15:25:41 +0800 Subject: [PATCH 1/6] 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..e3790d1 --- /dev/null +++ b/vcpustat-modify-vcpu-info-acquirement-from-debugfs.patch @@ -0,0 +1,54 @@ +From 3e17cc136a1cb2a2ae5798448c553b16694ec408 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.23.0 + From be522b3b23e4a841903aa1467def4e1e8e0fbb22 Mon Sep 17 00:00:00 2001 From: nocjj <1250062498@qq.com> Date: Sun, 27 Sep 2020 16:11:45 +0800 Subject: [PATCH 2/6] 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..f478d29 --- /dev/null +++ b/display-expand-CPU-display.patch @@ -0,0 +1,27 @@ +From 56923111d6218dfd9de68c4d0ae9a3b1ec96ff9a 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.23.0 + From c37096d834002a3f3d3318d91021971fcdc7941b Mon Sep 17 00:00:00 2001 From: nocjj <1250062498@qq.com> Date: Sun, 27 Sep 2020 19:47:24 +0800 Subject: [PATCH 3/6] 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..c8d6ff1 --- /dev/null +++ b/display-add-limit-to-usage-display.patch @@ -0,0 +1,101 @@ +From 2eae6818fa2267a3fdbc213b85e479e86d451ad6 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.23.0 + From 6535f799a3ba3ea259ef868a447b22a7a1115fa6 Mon Sep 17 00:00:00 2001 From: nocjj <1250062498@qq.com> Date: Sun, 27 Sep 2020 20:36:16 +0800 Subject: [PATCH 4/6] 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..cfaf4e7 --- /dev/null +++ b/vmtop-simplify-print_domain_field.patch @@ -0,0 +1,234 @@ +From af7e7f69ef5d6759b3c87da44d70b684cbd1b43c 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.23.0 + From b640dfbebcb269ee9e768d21a6b59d02a49fdb17 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Mon, 28 Sep 2020 11:57:52 +0800 Subject: [PATCH 5/6] spec: Update patch and changelog with !7 vcpustat: modify vcpu info acquirement from debugfs display: expand %CPU display display: add limit to usage display vmtop: simplify print_domain_field --- vmtop.spec | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vmtop.spec b/vmtop.spec index d1a0aca..95b9584 100644 --- a/vmtop.spec +++ b/vmtop.spec @@ -13,6 +13,10 @@ 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 Requires: libvirt, ncurses @@ -53,6 +57,12 @@ install -m 550 vmtop ${RPM_BUILD_ROOT}/usr/bin/%{name} %{_bindir}/vmtop %changelog +* Sun Sep 27 2020 nocjj <1250062498@qq.com> +- vcpustat: modify vcpu info acquirement from debugfs +- display: expand %CPU display +- display: add limit to usage display +- vmtop: simplify print_domain_field + * Mon Sep 21 2020 Ruyi Chen - vmtop: add -h and -v From 0654c4697ac6affdf9228fb56df52cfb4f0e1fd6 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Mon, 28 Sep 2020 11:57:52 +0800 Subject: [PATCH 6/6] spec: Update release version with !7 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 95b9584..1cd85d5 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