}
+static int
+qemuGetSchedstatDelay(unsigned long long *cpudelay,
+ pid_t pid,
+ pid_t tid)
+{
+ g_autofree char *path = NULL;
+ g_autofree char *buf = NULL;
+
+ if (tid)
+ path = g_strdup_printf("/proc/%d/task/%d/schedstat", (int)pid, (int)tid);
+ else
+ path = g_strdup_printf("/proc/%d/schedstat", (int)pid);
+
+ /* This file might not exist (needs CONFIG_SCHED_INFO) */
+ if (!virFileExists(path))
+ return 0;
+
+ if (virFileReadAll(path, 1024, &buf) < 0)
+ return -1;
+
+ if (sscanf(buf, "%*u %llu", cpudelay) != 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to parse schedstat info at '%s'"),
+ path);
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
qemuGetSchedInfo(unsigned long long *cpuWait,
pid_t pid, pid_t tid)
qemuDomainHelperGetVcpus(virDomainObjPtr vm,
virVcpuInfoPtr info,
unsigned long long *cpuwait,
+ unsigned long long *cpudelay,
int maxinfo,
unsigned char *cpumaps,
int maplen)
return -1;
}
+ if (cpudelay) {
+ if (qemuGetSchedstatDelay(&(cpudelay[ncpuinfo]), vm->pid, vcpupid) < 0)
+ return -1;
+ }
+
ncpuinfo++;
}
goto cleanup;
}
- ret = qemuDomainHelperGetVcpus(vm, info, NULL, maxinfo, cpumaps, maplen);
+ ret = qemuDomainHelperGetVcpus(vm, info, NULL, NULL, maxinfo, cpumaps, maplen);
cleanup:
virDomainObjEndAPI(&vm);
int ret = -1;
virVcpuInfoPtr cpuinfo = NULL;
g_autofree unsigned long long *cpuwait = NULL;
+ g_autofree unsigned long long *cpudelay = NULL;
if (virTypedParamListAddUInt(params, virDomainDefGetVcpus(dom->def),
"vcpu.current") < 0)
cpuinfo = g_new0(virVcpuInfo, virDomainDefGetVcpus(dom->def));
cpuwait = g_new0(unsigned long long, virDomainDefGetVcpus(dom->def));
+ cpudelay = g_new0(unsigned long long, virDomainDefGetVcpus(dom->def));
if (HAVE_JOB(privflags) && virDomainObjIsActive(dom) &&
qemuDomainRefreshVcpuHalted(driver, dom, QEMU_ASYNC_JOB_NONE) < 0) {
virResetLastError();
}
- if (qemuDomainHelperGetVcpus(dom, cpuinfo, cpuwait,
+ if (qemuDomainHelperGetVcpus(dom, cpuinfo, cpuwait, cpudelay,
virDomainDefGetVcpus(dom->def),
NULL, 0) < 0) {
virResetLastError();
"vcpu.%u.wait", cpuinfo[i].number) < 0)
goto cleanup;
+ if (virTypedParamListAddULLong(params, cpudelay[i],
+ "vcpu.%u.delay", cpuinfo[i].number) < 0)
+ goto cleanup;
+
/* state below is extracted from the individual vcpu structs */
if (!(vcpu = virDomainDefGetVcpu(dom->def, cpuinfo[i].number)))
continue;