This patch add new perf command to enable/disable perf event for a guest domain. Signed-off-by: Qiaowei Ren <qiaowei.ren@xxxxxxxxx> --- tools/virsh-domain.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 20 ++++++++ 2 files changed, 148 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index c2146d2..b1b5bfb 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -8483,6 +8483,128 @@ cmdMemtune(vshControl *ctl, const vshCmd *cmd) } /* + * "perf" command + */ +static const vshCmdInfo info_perf[] = { + {.name = "help", + .data = N_("Get or set perf event") + }, + {.name = "desc", + .data = N_("Get or set the current perf events for a guest" + " domain.\n" + " To get the perf events list use following command: \n\n" + " virsh # perf <domain>") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_perf[] = { + {.name = "domain", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("domain name, id or uuid") + }, + {.name = "enable", + .type = VSH_OT_STRING, + .help = N_("perf events which will be enabled") + }, + {.name = "disable", + .type = VSH_OT_STRING, + .help = N_("perf events which will be disabled") + }, + {.name = NULL} +}; + +static int +virshParseEventStr(vshControl *ctl, + const char *event, + bool state, + virTypedParameterPtr *params, + int *nparams, + int *maxparams) +{ + char **tok = NULL; + size_t i, ntok; + int ret = -1; + + if (!(tok = virStringSplitCount(event, "|", 0, &ntok))) + return -1; + + if (ntok > VIR_PERF_EVENT_LAST) { + vshError(ctl, _("event string '%s' has too many fields"), event); + goto cleanup; + } + + for(i = 0; i < ntok; i++) { + if ((*tok[i] != '\0') && + virTypedParamsAddBoolean(params, nparams, + maxparams, tok[i], state) < 0) + goto cleanup; + } + + ret = 0; + cleanup: + virStringFreeList(tok); + return ret; +} + +static bool +cmdPerf(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + int nparams = 0; + int maxparams = 0; + size_t i; + virTypedParameterPtr params = NULL; + bool ret = false; + const char *enable = NULL, *disable = NULL; + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (vshCommandOptStringReq(ctl, cmd, "enable", &enable) < 0 || + vshCommandOptStringReq(ctl, cmd, "disable", &disable) < 0) + return false; + + if (enable && virshParseEventStr(ctl, enable, true, + ¶ms, &nparams, &maxparams) < 0) + goto cleanup; + + if (disable && virshParseEventStr(ctl, disable, false, + ¶ms, &nparams, &maxparams) < 0) + goto cleanup; + + if (nparams == 0) { + if (virDomainGetPerfEvents(dom, ¶ms, &nparams) != 0) { + vshError(ctl, "%s", _("Unable to get perf events")); + goto cleanup; + } + for (i = 0; i < nparams; i++) { + if (params[i].type == VIR_TYPED_PARAM_BOOLEAN && + params[i].value.b) { + vshPrint(ctl, "%-15s: %s\n", params[i].field, _("enabled")); + } else { + vshPrint(ctl, "%-15s: %s\n", params[i].field, _("disabled")); + } + } + } else { + if (virDomainSetPerfEvents(dom, params, nparams) != 0) + goto error; + } + + ret = true; + cleanup: + virTypedParamsFree(params, nparams); + virDomainFree(dom); + return ret; + + error: + vshError(ctl, "%s", _("Unable to enable/disable perf events")); + goto cleanup; +} + + +/* * "numatune" command */ static const vshCmdInfo info_numatune[] = { @@ -12864,6 +12986,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_memtune, .flags = 0 }, + {.name = "perf", + .handler = cmdPerf, + .opts = opts_perf, + .info = info_perf, + .flags = 0 + }, {.name = "metadata", .handler = cmdMetadata, .opts = opts_metadata, diff --git a/tools/virsh.pod b/tools/virsh.pod index e830c59..eefe68a 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -2116,6 +2116,26 @@ The guaranteed minimum memory allocation for the guest. Specifying -1 as a value for these limits is interpreted as unlimited. +=item B<perf> I<domain> [I<--enable> B<eventName>] +[I<--disable> B<eventName>] + +Get the current perf events setting or enable/disable specific perf +event for a guest domain. + +Perf is a performance analyzing tool in Linux, and it can instrument +CPU performance counters, tracepoints, kprobes, and uprobes (dynamic +tracing). Perf supports a list of measurable events, and can measure +events coming from different sources. For instance, some event are +pure kernel counters, in this case they are called software events, +including context-switches, minor-faults, etc.. Now dozens of events +from different sources can be supported by perf. + +Currently only QEMU/KVM supports I<--enable> and I<--disable>. +B<eventName> is a string listing one or more events, in the format +of name|name|name. Only "cmt" event is supported presently. CMT is +a PQos (Platform Qos) feature to monitor the usage of cache by +applications running on the platform. + =item B<blkiotune> I<domain> [I<--weight> B<weight>] [I<--device-weights> B<device-weights>] [I<--device-read-iops-sec> B<device-read-iops-sec>] -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list