From b7a08f453fc448415ce320532907e61fa34f95b7 Mon Sep 17 00:00:00 2001 Message-Id: From: Michal Privoznik Date: Tue, 9 Aug 2022 16:15:55 +0200 Subject: [PATCH] util: Extend virProcessGetStatInfo() for sysTime and userTime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The virProcessGetStatInfo() helper parses /proc stat file for given PID and/or TID and reports cumulative cpuTime which is just a sum of user and sys times. But in near future, we'll need those times separately, so make the function return them too (if caller desires). Signed-off-by: Michal Privoznik Reviewed-by: Ján Tomko (cherry picked from commit cdc22d9a21e472a02dae8157e3cca5832f161feb) Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2157094 Signed-off-by: Michal Privoznik --- src/ch/ch_driver.c | 1 + src/qemu/qemu_driver.c | 4 +++- src/util/virprocess.c | 33 ++++++++++++++++++++++----------- src/util/virprocess.h | 2 ++ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c index e7c172c894..bde148075d 100644 --- a/src/ch/ch_driver.c +++ b/src/ch/ch_driver.c @@ -1075,6 +1075,7 @@ chDomainHelperGetVcpus(virDomainObj *vm, vcpuinfo->number = i; vcpuinfo->state = VIR_VCPU_RUNNING; if (virProcessGetStatInfo(&vcpuinfo->cpuTime, + NULL, NULL, &vcpuinfo->cpu, NULL, vm->pid, vcpupid) < 0) { virReportSystemError(errno, "%s", diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ebd6365f52..84cf2c6a4f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1359,6 +1359,7 @@ qemuDomainHelperGetVcpus(virDomainObj *vm, vcpuinfo->state = VIR_VCPU_RUNNING; if (virProcessGetStatInfo(&vcpuinfo->cpuTime, + NULL, NULL, &vcpuinfo->cpu, NULL, vm->pid, vcpupid) < 0) { virReportSystemError(errno, "%s", @@ -2528,6 +2529,7 @@ qemuDomainGetInfo(virDomainPtr dom, if (virDomainObjIsActive(vm)) { if (virProcessGetStatInfo(&(info->cpuTime), NULL, NULL, + NULL, NULL, vm->pid, 0) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("cannot read cputime for domain")); @@ -10770,7 +10772,7 @@ qemuDomainMemoryStatsInternal(virQEMUDriver *driver, ret = 0; } - if (virProcessGetStatInfo(NULL, NULL, &rss, vm->pid, 0) < 0) { + if (virProcessGetStatInfo(NULL, NULL, NULL, NULL, &rss, vm->pid, 0) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("cannot get RSS for domain")); } else { diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 013afd91b4..11f36e00a8 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -1737,32 +1737,37 @@ virProcessGetStat(pid_t pid, #ifdef __linux__ int virProcessGetStatInfo(unsigned long long *cpuTime, + unsigned long long *userTime, + unsigned long long *sysTime, int *lastCpu, long *vm_rss, pid_t pid, pid_t tid) { g_auto(GStrv) proc_stat = virProcessGetStat(pid, tid); - unsigned long long usertime = 0, systime = 0; + unsigned long long utime = 0; + unsigned long long stime = 0; + const unsigned long long jiff2nsec = 1000ull * 1000ull * 1000ull / + (unsigned long long) sysconf(_SC_CLK_TCK); long rss = 0; int cpu = 0; if (!proc_stat || - virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_UTIME], NULL, 10, &usertime) < 0 || - virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_STIME], NULL, 10, &systime) < 0 || + virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_UTIME], NULL, 10, &utime) < 0 || + virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_STIME], NULL, 10, &stime) < 0 || virStrToLong_l(proc_stat[VIR_PROCESS_STAT_RSS], NULL, 10, &rss) < 0 || virStrToLong_i(proc_stat[VIR_PROCESS_STAT_PROCESSOR], NULL, 10, &cpu) < 0) { VIR_WARN("cannot parse process status data"); } - /* We got jiffies - * We want nanoseconds - * _SC_CLK_TCK is jiffies per second - * So calculate thus.... - */ + utime *= jiff2nsec; + stime *= jiff2nsec; if (cpuTime) - *cpuTime = 1000ull * 1000ull * 1000ull * (usertime + systime) - / (unsigned long long) sysconf(_SC_CLK_TCK); + *cpuTime = utime + stime; + if (userTime) + *userTime = utime; + if (sysTime) + *sysTime = stime; if (lastCpu) *lastCpu = cpu; @@ -1771,7 +1776,7 @@ virProcessGetStatInfo(unsigned long long *cpuTime, VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld", - (int) pid, tid, usertime, systime, cpu, rss); + (int) pid, tid, utime, stime, cpu, rss); return 0; } @@ -1844,6 +1849,8 @@ virProcessGetSchedInfo(unsigned long long *cpuWait, #else int virProcessGetStatInfo(unsigned long long *cpuTime, + unsigned long long *userTime, + unsigned long long *sysTime, int *lastCpu, long *vm_rss, pid_t pid G_GNUC_UNUSED, @@ -1853,6 +1860,10 @@ virProcessGetStatInfo(unsigned long long *cpuTime, * platforms, so just report neutral values */ if (cpuTime) *cpuTime = 0; + if (userTime) + *userTime = 0; + if (sysTime) + *sysTime = 0; if (lastCpu) *lastCpu = 0; if (vm_rss) diff --git a/src/util/virprocess.h b/src/util/virprocess.h index 086fbe0e4d..f5a4a4e508 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -195,6 +195,8 @@ typedef enum { int virProcessNamespaceAvailable(unsigned int ns); int virProcessGetStatInfo(unsigned long long *cpuTime, + unsigned long long *userTime, + unsigned long long *sysTime, int *lastCpu, long *vm_rss, pid_t pid, -- 2.39.0