vcpu_stat.c 3.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/******************************************************************************
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 * vmtop licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 * Description: get kvm exit data from vcpu_stat
 ********************************************************************************/
#include <stdio.h>
#include <string.h>
#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[] = {
#define GDF(f)  (void *)GET_NAME(f), (void *)DELTA_NAME(f), (void *)SUM_NAME(f)
#define GF(f)   (void *)GET_NAME(f), NULL, NULL
N
nocjj 已提交
24
    {"%*u",  NULL, NULL, NULL},
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
    {"%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)}
#undef GF
#undef GDF
};

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];
    FILE *fp = NULL;

63
    if (snprintf(pid, PID_STRING_SIZE, "%u", dom->pid) < 0) {
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
        return -1;
    }
    fp = fopen(KVM_VCPU_STAT_PATH, "r");
    if (!fp) {
        return -1;
    }
    while (fgets(buf, BUF_SIZE - 1, fp)) {
        char *p = NULL;
        char *p_next = NULL;
        int i = 0;

        if (strstr(buf, pid) == NULL) {
            continue;
        }
        for (p = strtok_r(buf, " \t\r\n", &p_next); p && i < vcpu_stat_size;
             p = strtok_r(NULL, " \t\r\n", &p_next)) {
N
nocjj 已提交
80 81 82
            if (vcpu_stat_stab[i].get_fun) {
                sscanf(p, vcpu_stat_stab[i].format,
                       (*vcpu_stat_stab[i].get_fun)(dom));
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
            }
            i++;
        }
        break;
    }
    fclose(fp);
    return 1;
}

/*
 * get delta value of kvm exit times over time
 */
void refresh_delta_vcpu_stat(struct domain *new, struct domain *old)
{
    if (!new || !old) {
        return;
    }
    for (int i = 0; i < vcpu_stat_size; i++) {
        if (vcpu_stat_stab[i].delta_fun) {
            (*vcpu_stat_stab[i].delta_fun)(new, old);
        }
    }
}

/*
 * get sum of kvm exit from threads of virtla machine
 */
void sum_vcpu_stat(struct domain *dom, struct domain *thread)
{
    if (!dom || !thread) {
        return;
    }
    for (int i = 0; i < vcpu_stat_size; i++) {
        if (vcpu_stat_stab[i].sum_fun) {
            (*vcpu_stat_stab[i].sum_fun)(dom, thread);
        }
    }
}