qemu_driver: add support to perf event

This patch implement the internal driver API for perf event into
qemu driver.

Signed-off-by: Qiaowei Ren <qiaowei.ren@intel.com>
Message-id: 1459171833-26416-5-git-send-email-qiaowei.ren@intel.com
This commit is contained in:
Qiaowei Ren 2016-03-28 21:30:29 +08:00 committed by Daniel P. Berrange
parent 28b446292b
commit 0dd0165c03
4 changed files with 143 additions and 0 deletions

View File

@ -1804,6 +1804,7 @@ typedef enum {
VIR_DOMAIN_STATS_VCPU = (1 << 3), /* return domain virtual CPU info */
VIR_DOMAIN_STATS_INTERFACE = (1 << 4), /* return domain interfaces info */
VIR_DOMAIN_STATS_BLOCK = (1 << 5), /* return domain block info */
VIR_DOMAIN_STATS_PERF = (1 << 6), /* return domain perf event info */
} virDomainStatsTypes;
typedef enum {

View File

@ -26,6 +26,7 @@
# include "virthread.h"
# include "vircgroup.h"
# include "virperf.h"
# include "domain_addr.h"
# include "domain_conf.h"
# include "snapshot_conf.h"
@ -195,6 +196,8 @@ struct _qemuDomainObjPrivate {
virCgroupPtr cgroup;
virPerfPtr perf;
virCond unplugFinished; /* signals that unpluggingDevice was unplugged */
const char *unpluggingDevice; /* alias of the device that is being unplugged */
char **qemuDevices; /* NULL-terminated list of devices aliases known to QEMU */

View File

@ -99,6 +99,7 @@
#include "virhostdev.h"
#include "domain_capabilities.h"
#include "vircgroup.h"
#include "virperf.h"
#include "virnuma.h"
#include "dirname.h"
#include "network/bridge_driver.h"
@ -10036,6 +10037,86 @@ qemuSetGlobalBWLive(virCgroupPtr cgroup, unsigned long long period,
return 0;
}
static int
qemuDomainSetPerfEvents(virDomainPtr dom,
virTypedParameterPtr params,
int nparams)
{
size_t i;
virDomainObjPtr vm = NULL;
qemuDomainObjPrivatePtr priv;
int ret = -1;
virPerfEventType type;
bool enabled;
if (virTypedParamsValidate(params, nparams, VIR_PERF_PARAMETERS) < 0)
return -1;
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
priv = vm->privateData;
if (virDomainSetPerfEventsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = &params[i];
enabled = params->value.b;
type = virPerfEventTypeFromString(param->field);
if (!enabled && virPerfEventDisable(priv->perf, type))
goto cleanup;
if (enabled && virPerfEventEnable(priv->perf, type, vm->pid))
goto cleanup;
}
ret = 0;
cleanup:
virDomainObjEndAPI(&vm);
return ret;
}
static int
qemuDomainGetPerfEvents(virDomainPtr dom,
virTypedParameterPtr *params,
int *nparams)
{
size_t i;
virDomainObjPtr vm = NULL;
qemuDomainObjPrivatePtr priv;
int ret = -1;
virTypedParameterPtr par = NULL;
int maxpar = 0;
int npar = 0;
if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
priv = vm->privateData;
if (virDomainGetPerfEventsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
if (virTypedParamsAddBoolean(&par, &npar, &maxpar,
virPerfEventTypeToString(i),
virPerfEventIsEnabled(priv->perf, i)) < 0) {
virTypedParamsFree(par, npar);
goto cleanup;
}
}
*params = par;
*nparams = npar;
ret = 0;
cleanup:
virDomainObjEndAPI(&vm);
return ret;
}
static int
qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup,
unsigned long long period, long long quota)
@ -19401,6 +19482,55 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
#undef QEMU_ADD_COUNT_PARAM
static int
qemuDomainGetStatsPerfCmt(virPerfPtr perf,
virDomainStatsRecordPtr record,
int *maxparams)
{
uint64_t cache = 0;
if (virPerfReadEvent(perf, VIR_PERF_EVENT_CMT, &cache) < 0)
return -1;
if (virTypedParamsAddULLong(&record->params,
&record->nparams,
maxparams,
"perf.cache",
cache) < 0)
return -1;
return 0;
}
static int
qemuDomainGetStatsPerf(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
virDomainObjPtr dom,
virDomainStatsRecordPtr record,
int *maxparams,
unsigned int privflags ATTRIBUTE_UNUSED)
{
size_t i;
qemuDomainObjPrivatePtr priv = dom->privateData;
int ret = -1;
for (i = 0; i < VIR_PERF_EVENT_LAST; i++) {
if (!virPerfEventIsEnabled(priv->perf, i))
continue;
switch (i) {
case VIR_PERF_EVENT_CMT:
if (qemuDomainGetStatsPerfCmt(priv->perf, record, maxparams) < 0)
goto cleanup;
break;
}
}
ret = 0;
cleanup:
return ret;
}
typedef int
(*qemuDomainGetStatsFunc)(virQEMUDriverPtr driver,
virDomainObjPtr dom,
@ -19421,6 +19551,7 @@ static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers[] = {
{ qemuDomainGetStatsVcpu, VIR_DOMAIN_STATS_VCPU, false },
{ qemuDomainGetStatsInterface, VIR_DOMAIN_STATS_INTERFACE, false },
{ qemuDomainGetStatsBlock, VIR_DOMAIN_STATS_BLOCK, true },
{ qemuDomainGetStatsPerf, VIR_DOMAIN_STATS_PERF, false },
{ NULL, 0, false }
};
@ -20177,6 +20308,8 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainMigrateFinish3 = qemuDomainMigrateFinish3, /* 0.9.2 */
.domainMigrateConfirm3 = qemuDomainMigrateConfirm3, /* 0.9.2 */
.domainSendKey = qemuDomainSendKey, /* 0.9.4 */
.domainGetPerfEvents = qemuDomainGetPerfEvents, /* 1.3.3 */
.domainSetPerfEvents = qemuDomainSetPerfEvents, /* 1.3.3 */
.domainBlockJobAbort = qemuDomainBlockJobAbort, /* 0.9.4 */
.domainGetBlockJobInfo = qemuDomainGetBlockJobInfo, /* 0.9.4 */
.domainBlockJobSetSpeed = qemuDomainBlockJobSetSpeed, /* 0.9.4 */

View File

@ -5253,6 +5253,10 @@ qemuProcessLaunch(virConnectPtr conn,
if (qemuSetupCgroup(driver, vm, nnicindexes, nicindexes) < 0)
goto cleanup;
priv->perf = virPerfNew();
if (!priv->perf)
goto cleanup;
/* This must be done after cgroup placement to avoid resetting CPU
* affinity */
if (!vm->def->cputune.emulatorpin &&
@ -5890,6 +5894,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
}
virCgroupFree(&priv->cgroup);
virPerfFree(priv->perf);
qemuProcessRemoveDomainStatus(driver, vm);
/* Remove VNC and Spice ports from port reservation bitmap, but only if