On 11/12/18 8:31 AM, Wang Huaqiang wrote:
> Adding the interface in qemu to report CMT statistic information
> through command 'virsh domstats --cpu-total'.
I believe virsh.pod needs an update to list this type of data in the
domstats --cpu-total output.
In any case, I need to drop off for the evening - I'll pick this up in
the morning. You can send an update to this patch and I can merge it in.
The first 15 patches look good with some minor adjustments...
John
>
> Below is a typical output:
>
> # virsh domstats 1 --cpu-total
> Domain: 'ubuntu16.04-base'
> ...
> cpu.cache.monitor.count=2
> cpu.cache.monitor.0.name=vcpus_1
> cpu.cache.monitor.0.vcpus=1
> cpu.cache.monitor.0.bank.count=2
> cpu.cache.monitor.0.bank.0.id=0
> cpu.cache.monitor.0.bank.0.bytes=4505600
> cpu.cache.monitor.0.bank.1.id=1
> cpu.cache.monitor.0.bank.1.bytes=5586944
> cpu.cache.monitor.1.name=vcpus_4-6
> cpu.cache.monitor.1.vcpus=4,5,6
> cpu.cache.monitor.1.bank.count=2
> cpu.cache.monitor.1.bank.0.id=0
> cpu.cache.monitor.1.bank.0.bytes=17571840
> cpu.cache.monitor.1.bank.1.id=1
> cpu.cache.monitor.1.bank.1.bytes=29106176
>
> Signed-off-by: Wang Huaqiang <huaqiang.w...@intel.com>
> ---
> src/libvirt-domain.c | 9 +++
> src/qemu/qemu_driver.c | 198
> +++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 207 insertions(+)
>
> diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
> index 7690339..4895f9f 100644
> --- a/src/libvirt-domain.c
> +++ b/src/libvirt-domain.c
> @@ -11345,6 +11345,15 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
> * "cpu.user" - user cpu time spent in nanoseconds as unsigned long long.
> * "cpu.system" - system cpu time spent in nanoseconds as unsigned long
> * long.
> + * "cpu.cache.monitor.count" - tocal cache monitoring groups
> + * "cpu.cache.monitor.M.name" - name of cache monitoring group 'M'
> + * "cpu.cache.monitor.M.vcpus" - vcpus for cache monitoring group 'M'
> + * "cpu.cache.monitor.M.bank.count" - total bank number of cache
> monitoring
> + * group 'M'
> + * "cpu.cache.monitor.M.bank.N.id" - OS assigned cache bank id for cache
> + * 'N' in cache monitoring group 'M'
> + * "cpu.cache.monitor.M.bank.N.bytes" - monitor's cache occupancy of
> cache
> + * bank 'N' in cache monitoring group 'M'
> *
> * VIR_DOMAIN_STATS_BALLOON:
> * Return memory balloon device information.
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 89d46ee..d41ae66 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -19698,6 +19698,199 @@ typedef enum {
> #define HAVE_JOB(flags) ((flags) & QEMU_DOMAIN_STATS_HAVE_JOB)
>
>
> +typedef struct _virQEMUCpuResMonitorData virQEMUCpuResMonitorData;
> +typedef virQEMUCpuResMonitorData *virQEMUCpuResMonitorDataPtr;
> +struct _virQEMUCpuResMonitorData{
Data {
> + const char *name;
> + char *vcpus;
> + virResctrlMonitorType tag;
> + virResctrlMonitorStatsPtr stats;
> + size_t nstats;
> +};
> +
> +
> +static int
> +qemuDomainGetCpuResMonitorData(virDomainObjPtr dom,
> + virQEMUCpuResMonitorDataPtr mondata)
> +{
> + virDomainResctrlDefPtr resctrl = NULL;
> + size_t i = 0;
> + size_t j = 0;
> + size_t l = 0;
> +
> + for (i = 0; i < dom->def->nresctrls; i++) {
> + resctrl = dom->def->resctrls[i];
> +
> + for (j = 0; j < resctrl->nmonitors; j++) {
> + virDomainResctrlMonDefPtr domresmon = NULL;
> + virResctrlMonitorPtr monitor = resctrl->monitors[j]->instance;
> +
> + domresmon = resctrl->monitors[j];
> + mondata[l].tag = domresmon->tag;
> +
> + /* If virBitmapFormat successfully returns an vcpu string, then
> + * mondata[l].vcpus is assigned with an memory space holding it,
> + * let this newly allocated memory buffer to be freed along with
> + * the free of 'mondata' */
> + if (!(mondata[l].vcpus = virBitmapFormat(domresmon->vcpus)))
> + return -1;
> +
> + if (!(mondata[l].name = virResctrlMonitorGetID(monitor))) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Could not get monitor ID"));
> + return -1;
> + }
> +
> + if (domresmon->tag == VIR_RESCTRL_MONITOR_TYPE_CACHE) {
> + if (virResctrlMonitorGetCacheOccupancy(monitor,
> + &mondata[l].stats,
> + &mondata[l].nstats) <
> 0)
> + return -1;
> + } else {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Invalid CPU resource type"));
> + return -1;
> + }
> +
> + l++;
> + }
> + }
> +
> + return 0;
> +}
> +
> +
> +static int
> +qemuDomainGetStatsCpuResMonitorPerTag(virQEMUCpuResMonitorDataPtr mondata,
> + size_t nmondata,
> + virResctrlMonitorType tag,
> + virDomainStatsRecordPtr record,
> + int *maxparams)
> +{
> + char param_name[VIR_TYPED_PARAM_FIELD_LENGTH];
> + unsigned int nmonitors = 0;
> + const char *resname = NULL;
> + const char *resnodename = NULL;
> + size_t i = 0;
> +
> + for (i = 0; i < nmondata; i++) {
> + if (mondata[i].tag == tag)
> + nmonitors++;
> + }
> +
> + if (!nmonitors)
> + return 0;
> +
> + if (tag == VIR_RESCTRL_MONITOR_TYPE_CACHE) {
> + resname = "cache";
> + resnodename = "bank";
> + } else if (tag == VIR_RESCTRL_MONITOR_TYPE_MEMBW) {
> + resname = "memBW";
> + resnodename = "node";
> + } else {
> + return 0;
> + }
> +
> + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
> + "cpu.%s.monitor.count", resname);
> + if (virTypedParamsAddUInt(&record->params, &record->nparams,
> + maxparams, param_name, nmonitors) < 0)
> + return -1;
> +
> + for (i = 0; i < nmonitors; i++) {
> + size_t l = 0;
> +
> + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
> + "cpu.%s.monitor.%zd.name", resname, i);
> + if (virTypedParamsAddString(&record->params,
> + &record->nparams,
> + maxparams,
> + param_name,
> + mondata[i].name) < 0)
> + return -1;
> +
> + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
> + "cpu.%s.monitor.%zd.vcpus", resname, i);
> + if (virTypedParamsAddString(&record->params, &record->nparams,
> + maxparams, param_name,
> + mondata[i].vcpus) < 0)
> + return -1;
> +
> + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
> + "cpu.%s.monitor.%zd.%s.count", resname, i, resnodename);
> + if (virTypedParamsAddUInt(&record->params, &record->nparams,
> + maxparams, param_name,
> + mondata[i].nstats) < 0)
> + return -1;
> +
> + for (l = 0; l < mondata[i].nstats; l++) {
> + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
> + "cpu.%s.monitor.%zd.%s.%zd.id",
> + resname, i, resnodename, l);
> + if (virTypedParamsAddUInt(&record->params, &record->nparams,
> + maxparams, param_name,
> + mondata[i].stats[l].id) < 0)
> + return -1;
> +
> + snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH,
> + "cpu.%s.monitor.%zd.%s.%zd.bytes",
> + resname, i, resnodename, l);
> + if (virTypedParamsAddUInt(&record->params, &record->nparams,
> + maxparams, param_name,
> + mondata[i].stats[l].val) < 0)
> + return -1;
> + }
> + }
> +
> + return 0;
> +}
> +
> +
> +static int
> +qemuDomainGetStatsCpuResMonitor(virDomainObjPtr dom,
> + virDomainStatsRecordPtr record,
> + int *maxparams)
> +{
> + virDomainResctrlDefPtr resctrl = NULL;
> + virQEMUCpuResMonitorDataPtr mondata = NULL;
> + unsigned int nmonitors = 0;
> + size_t i = 0;
> + int ret = -1;
> +
> + if (!virDomainObjIsActive(dom))
> + return 0;
> +
> + for (i = 0; i < dom->def->nresctrls; i++) {
> + resctrl = dom->def->resctrls[i];
> + nmonitors += resctrl->nmonitors;
> + }
> +
> + if (!nmonitors)
> + return 0;
> +
> + if (VIR_ALLOC_N(mondata, nmonitors) < 0)
> + return -1;
> +
> + if (qemuDomainGetCpuResMonitorData(dom, mondata) < 0)
> + goto cleanup;
> +
> + for (i = VIR_RESCTRL_MONITOR_TYPE_UNSUPPORT + 1;
> + i < VIR_RESCTRL_MONITOR_TYPE_LAST; i++) {
> + if (qemuDomainGetStatsCpuResMonitorPerTag(mondata, nmonitors, i,
> + record, maxparams) < 0)
> + goto cleanup;
> + }
> +
> + ret = 0;
> + cleanup:
> + for (i = 0; i < nmonitors; i++)
> + VIR_FREE(mondata[i].vcpus);
> + VIR_FREE(mondata);
> +
> + return ret;
> +}
> +
> +
> static int
> qemuDomainGetStatsCpuCgroup(virDomainObjPtr dom,
> virDomainStatsRecordPtr record,
> @@ -19747,6 +19940,11 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr driver
> ATTRIBUTE_UNUSED,
> {
> if (qemuDomainGetStatsCpuCgroup(dom, record, maxparams) < 0)
> return -1;
> +
> + if (qemuDomainGetStatsCpuResMonitor(dom, record, maxparams) < 0)
> + return -1;
> +
> + return 0;
> }
>
>
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list