278 lines
8.5 KiB
Diff
278 lines
8.5 KiB
Diff
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 <unistd.h>
|
|
#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 <string.h>
|
|
#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
|
|
|