From nobody Tue Apr 16 11:15:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1528450378336274.7354217498455; Fri, 8 Jun 2018 02:32:58 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C3CE1C057FA0; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5F30E60C22; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9CB9C4CA83; Fri, 8 Jun 2018 09:32:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w589WpO1010286 for ; Fri, 8 Jun 2018 05:32:51 -0400 Received: by smtp.corp.redhat.com (Postfix) id A10755D9C6; Fri, 8 Jun 2018 09:32:51 +0000 (UTC) Received: from mx1.redhat.com (ext-mx08.extmail.prod.ext.phx2.redhat.com [10.5.110.32]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 95DC15D9C7 for ; Fri, 8 Jun 2018 09:32:48 +0000 (UTC) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 46FA0C057F87 for ; Fri, 8 Jun 2018 09:32:47 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Jun 2018 02:32:46 -0700 Received: from david-unc.bj.intel.com ([10.238.145.77]) by fmsmga004.fm.intel.com with ESMTP; 08 Jun 2018 02:32:45 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,490,1520924400"; d="scan'208";a="61461050" From: Wang Huaqiang To: libvir-list@redhat.com Date: Fri, 8 Jun 2018 17:02:17 +0800 Message-Id: <1528448539-25588-2-git-send-email-huaqiang.wang@intel.com> In-Reply-To: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> References: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 08 Jun 2018 09:32:47 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 08 Jun 2018 09:32:47 +0000 (UTC) for IP:'192.55.52.120' DOMAIN:'mga04.intel.com' HELO:'mga04.intel.com' FROM:'huaqiang.wang@intel.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 192.55.52.120 mga04.intel.com 192.55.52.120 mga04.intel.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.32 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: shaohe.feng@intel.com, Wang Huaqiang , bing.niu@intel.com, jian-feng.ding@intel.com, rui.zang@intel.com Subject: [libvirt] [PATCH 1/3] util: add Intel x86 RDT/CMT support X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 08 Jun 2018 09:32:57 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add RDT/CMT feature (Intel x86) by interacting with kernel resctrl file sys= tem. Integrate code into util/resctrl. --- src/libvirt_private.syms | 9 ++ src/util/virresctrl.c | 316 +++++++++++++++++++++++++++++++++++++++++++= +++- src/util/virresctrl.h | 44 +++++++ 3 files changed, 367 insertions(+), 2 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b4ab1f3..e16c3e0 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2634,6 +2634,15 @@ virResctrlAllocSetSize; virResctrlGetInfo; virResctrlInfoGetCache; virResctrlInfoNew; +virResctrlMonNew; +virResctrlMonSetID; +virResctrlMonGetID; +virResctrlMonDeterminePath; +virResctrlMonAddPID; +virResctrlMonCreate; +virResctrlMonRemove; +virResctrlMonIsRunning; +virResctrlMonGetCacheOccupancy; =20 =20 # util/virrotatingfile.h diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c index fc11635..e5f5caf 100644 --- a/src/util/virresctrl.c +++ b/src/util/virresctrl.c @@ -224,6 +224,22 @@ struct _virResctrlAlloc { =20 static virClassPtr virResctrlAllocClass; =20 +struct _virResctrlMon { + virObject parent; + + /* pairedalloc: pointer to a resctrl allocaion it paried with. + * NULL for a resctrl monitoring group not associated with + * any allocation. */ + virResctrlAllocPtr pairedalloc; + /* The identifier (any unique string for now) */ + char *id; + /* libvirt-generated path, may be identical to alloction path + * may not if allocation is ready */ + char *path; +}; + +static virClassPtr virResctrlMonClass; + static void virResctrlAllocDispose(void *obj) { @@ -275,7 +291,28 @@ virResctrlAllocOnceInit(void) } =20 =20 +static void +virResctrlMonDispose(void *obj) +{ + virResctrlMonPtr resctrlMon =3D obj; + + VIR_FREE(resctrlMon->id); + VIR_FREE(resctrlMon->path); +} + + +static int +virResctrlMonOnceInit(void) +{ + if (!VIR_CLASS_NEW(virResctrlMon, virClassForObject())) + return -1; + + return 0; +} + + VIR_ONCE_GLOBAL_INIT(virResctrlAlloc) +VIR_ONCE_GLOBAL_INIT(virResctrlMon) =20 =20 virResctrlAllocPtr @@ -288,6 +325,16 @@ virResctrlAllocNew(void) } =20 =20 +virResctrlMonPtr +virResctrlMonNew(void) +{ + if (virResctrlMonInitialize() < 0) + return NULL; + + return virObjectNew(virResctrlMonClass); +} + + /* Common functions */ #ifdef __linux__ static int @@ -329,8 +376,6 @@ virResctrlLockWrite(void) #endif =20 =20 - - static int virResctrlUnlock(int fd) { @@ -1646,3 +1691,270 @@ virResctrlAllocRemove(virResctrlAllocPtr alloc) =20 return ret; } + + +int +virResctrlMonSetID(virResctrlMonPtr mon, + const char *id) +{ + if (!id) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Resctrl mon group 'id' cannot be NULL")); + return -1; + } + + return VIR_STRDUP(mon->id, id); +} + + +const char * +virResctrlMonGetID(virResctrlMonPtr mon) +{ + return mon->id; +} + + +int +virResctrlMonDeterminePath(virResctrlMonPtr mon, + const char *machinename) +{ + + VIR_DEBUG("mon group, mon->path=3D%s\n", mon->path); + if (!mon->id) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Resctrl mon group id must be set before creation")); + return -1; + } + + if (mon->path) + return -1; + + if(mon->pairedalloc) + { + if (virAsprintf(&mon->path, "%s/%s-%s", + SYSFS_RESCTRL_PATH, machinename, mon->id) < 0) + return -1; + } + else + { + if (virAsprintf(&mon->path, "%s/mon_groups/%s-%s", + SYSFS_RESCTRL_PATH, machinename, mon->id) < 0) + return -1; + } + + return 0; +} + + +int +virResctrlMonAddPID(virResctrlMonPtr mon, + pid_t pid) +{ + char *tasks =3D NULL; + char *pidstr =3D NULL; + int ret =3D 0; + + if (!mon->path) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot add pid to non-existing resctrl mon group")); + return -1; + } + + VIR_DEBUG("Add PID %d to domain %s\n", + pid, mon->path); + + if (virAsprintf(&tasks, "%s/tasks", mon->path) < 0) + return -1; + + if (virAsprintf(&pidstr, "%lld", (long long int) pid) < 0) + goto cleanup; + + if (virFileWriteStr(tasks, pidstr, 0) < 0) { + virReportSystemError(errno, + _("Cannot write pid in tasks file '%s'"), + tasks); + goto cleanup; + } + + ret =3D 0; +cleanup: + VIR_FREE(tasks); + VIR_FREE(pidstr); + return ret; +} + + +int +virResctrlMonCreate(virResctrlAllocPtr pairedalloc, + virResctrlMonPtr mon, + const char *machinename) +{ + int ret =3D -1; + int lockfd =3D -1; + + if (!mon) + return 0; + + + if (pairedalloc) + { + if (!virFileExists(pairedalloc->path)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("For paired mon group, the resctrl allocation " + "must be created first")); + goto cleanup; + } + mon->pairedalloc =3D pairedalloc; + + if (virResctrlMonDeterminePath(mon, machinename) < 0) + return -1; + } + else + { + mon->pairedalloc =3D NULL; + + /* resctrl mon group object may use for multiple purpose, + * free mon group path information*/ + VIR_FREE(mon->path); + + if (virResctrlMonDeterminePath(mon, machinename) < 0) + return -1; + + lockfd =3D virResctrlLockWrite(); + if (lockfd < 0) + goto cleanup; + + if (virFileExists(mon->path)) + { + VIR_DEBUG("Removing resctrl mon group %s", mon->path); + if (rmdir(mon->path) !=3D 0 && errno !=3D ENOENT) { + ret =3D -errno; + VIR_ERROR(_("Unable to remove %s (%d)"), mon->path, errno); + goto cleanup; + } + } + + if (virFileMakePath(mon->path) < 0) { + virReportSystemError(errno, + _("Cannot create resctrl directory '%s'"), + mon->path); + goto cleanup; + } + } + + ret =3D 0; +cleanup: + virResctrlUnlock(lockfd); + return ret; +} + + +int +virResctrlMonRemove(virResctrlMonPtr mon) +{ + int ret =3D 0; + + if (!mon->path) + return 0; + + VIR_DEBUG("Removing resctrl mon group %s", mon->path); + if (rmdir(mon->path) !=3D 0 && errno !=3D ENOENT) { + ret =3D -errno; + VIR_ERROR(_("Unable to remove %s (%d)"), mon->path, errno); + } + + return ret; +} + + +bool +virResctrlMonIsRunning(virResctrlMonPtr mon) +{ + bool ret =3D false; + char *tasks =3D NULL; + + if (mon && virFileExists(mon->path)) { + ret =3D virFileReadValueString(&tasks, "%s/tasks", mon->path); + if (ret < 0) + goto cleanup; + + if (!tasks || !tasks[0]) + goto cleanup; + + ret =3D true; + } + +cleanup: + VIR_FREE(tasks); + + return ret; +} + + +int +virResctrlMonGetCacheOccupancy(virResctrlMonPtr mon, + unsigned int * cacheoccu) +{ + DIR *dirp =3D NULL; + int ret =3D -1; + int rv =3D -1; + struct dirent *ent =3D NULL; + unsigned int cachetotal =3D 0; + unsigned int cacheoccyperblock =3D 0; + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + char *pathmondata =3D NULL; + + if (!mon->path) + goto cleanup; + + rv =3D virDirOpenIfExists(&dirp,mon->path); + if (rv <=3D 0) { + goto cleanup; + } + + virBufferAsprintf(&buf, "%s/mon_data", + mon->path); + pathmondata =3D virBufferContentAndReset(&buf); + if (!pathmondata) + goto cleanup; + + VIR_DEBUG("Seek llc_occupancy file from root: %s ", + pathmondata); + + if (virDirOpen(&dirp, pathmondata) < 0) + goto cleanup; + + while ((rv =3D virDirRead(dirp, &ent, pathmondata)) > 0) { + VIR_DEBUG("Parsing file '%s'", ent->d_name); + if (ent->d_type !=3D DT_DIR) + continue; + + if (STRNEQLEN(ent->d_name, "mon_L", 5)) + continue; + + rv =3D virFileReadValueUint(&cacheoccyperblock, + "%s/%s/llc_occupancy", + pathmondata, ent->d_name); + if (rv =3D=3D -2) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "file %s/%s/llc_occupancy does not exist", + pathmondata, ent->d_name); + goto cleanup; + } else if (rv < 0) { + goto cleanup; + } + + VIR_DEBUG("%s/%s/llc_occupancy: occupancy %d bytes", + pathmondata, ent->d_name, cacheoccyperblock); + + cachetotal +=3D cacheoccyperblock; + } + + *cacheoccu =3D cachetotal; + + ret =3D 0; +cleanup: + VIR_FREE(pathmondata); + VIR_DIR_CLOSE(dirp); + return ret; +} diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h index 5368ba2..a23c425 100644 --- a/src/util/virresctrl.h +++ b/src/util/virresctrl.h @@ -35,6 +35,12 @@ typedef enum { =20 VIR_ENUM_DECL(virCache); =20 +typedef enum { + VIR_RESCTRL_MONACT_NONE, + VIR_RESCTRL_MONACT_ENABLE, + VIR_RESCTRL_MONACT_DISABLE +} virResctrlMonAct; + =20 typedef struct _virResctrlInfoPerCache virResctrlInfoPerCache; typedef virResctrlInfoPerCache *virResctrlInfoPerCachePtr; @@ -118,4 +124,42 @@ virResctrlAllocAddPID(virResctrlAllocPtr alloc, int virResctrlAllocRemove(virResctrlAllocPtr alloc); =20 + +/* Monitoring-related things */ +typedef struct _virResctrlMon virResctrlMon; +typedef virResctrlMon *virResctrlMonPtr; + +virResctrlMonPtr +virResctrlMonNew(void); + +int +virResctrlMonSetID(virResctrlMonPtr mon, + const char *id); + +const char * +virResctrlMonGetID(virResctrlMonPtr mon); + +int +virResctrlMonDeterminePath(virResctrlMonPtr mon, + const char *machinename); + +int +virResctrlMonAddPID(virResctrlMonPtr alloc, + pid_t pid); + +int +virResctrlMonCreate(virResctrlAllocPtr pairedalloc, + virResctrlMonPtr mon, + const char *machinename); + +int +virResctrlMonRemove(virResctrlMonPtr mon); + +bool +virResctrlMonIsRunning(virResctrlMonPtr mon); + +int +virResctrlMonGetCacheOccupancy(virResctrlMonPtr mon, + unsigned int * cacheoccu); + #endif /* __VIR_RESCTRL_H__ */ --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue Apr 16 11:15:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1528450378517707.7839616954203; Fri, 8 Jun 2018 02:32:58 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CE85A36807; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 91DFA62527; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 448504CA80; Fri, 8 Jun 2018 09:32:56 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w589WsQt010300 for ; Fri, 8 Jun 2018 05:32:54 -0400 Received: by smtp.corp.redhat.com (Postfix) id 646FC1001F45; Fri, 8 Jun 2018 09:32:54 +0000 (UTC) Received: from mx1.redhat.com (ext-mx10.extmail.prod.ext.phx2.redhat.com [10.5.110.39]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 59B8A100191B for ; Fri, 8 Jun 2018 09:32:51 +0000 (UTC) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 43CDA5D697 for ; Fri, 8 Jun 2018 09:32:49 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Jun 2018 02:32:48 -0700 Received: from david-unc.bj.intel.com ([10.238.145.77]) by fmsmga004.fm.intel.com with ESMTP; 08 Jun 2018 02:32:47 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,490,1520924400"; d="scan'208";a="61461057" From: Wang Huaqiang To: libvir-list@redhat.com Date: Fri, 8 Jun 2018 17:02:18 +0800 Message-Id: <1528448539-25588-3-git-send-email-huaqiang.wang@intel.com> In-Reply-To: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> References: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 08 Jun 2018 09:32:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 08 Jun 2018 09:32:49 +0000 (UTC) for IP:'192.55.52.120' DOMAIN:'mga04.intel.com' HELO:'mga04.intel.com' FROM:'huaqiang.wang@intel.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 192.55.52.120 mga04.intel.com 192.55.52.120 mga04.intel.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.39 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Cc: shaohe.feng@intel.com, Wang Huaqiang , bing.niu@intel.com, jian-feng.ding@intel.com, rui.zang@intel.com Subject: [libvirt] [PATCH 2/3] tools: virsh: add command for controling/monitoring resctrl X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 08 Jun 2018 09:32:57 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" --- include/libvirt/libvirt-domain.h | 9 +++ src/conf/domain_conf.c | 28 +++++++ src/conf/domain_conf.h | 3 + src/driver-hypervisor.h | 8 ++ src/libvirt-domain.c | 81 +++++++++++++++++++++ src/libvirt_public.syms | 6 ++ src/qemu/qemu_driver.c | 141 ++++++++++++++++++++++++++++++++= ++++ src/qemu/qemu_process.c | 65 ++++++++++++++++- src/remote/remote_daemon_dispatch.c | 45 ++++++++++++ src/remote/remote_driver.c | 2 + src/remote/remote_protocol.x | 28 ++++++- src/remote_protocol-structs | 12 +++ tools/virsh-domain.c | 74 +++++++++++++++++++ 13 files changed, 499 insertions(+), 3 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index da773b7..598db28 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4767,4 +4767,13 @@ int virDomainSetLifecycleAction(virDomainPtr domain, unsigned int action, unsigned int flags); =20 +/* + * resctrl API + */ +int virDomainSetResctrlMon(virDomainPtr domain, + int enable, int disable); + +int virDomainGetResctrlMonSts(virDomainPtr domain, + char **sts); + #endif /* __VIR_LIBVIRT_DOMAIN_H__ */ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5be773c..0ada3dc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18885,6 +18885,7 @@ virDomainCachetuneDefParse(virDomainDefPtr def, xmlNodePtr *nodes =3D NULL; virBitmapPtr vcpus =3D NULL; virResctrlAllocPtr alloc =3D virResctrlAllocNew(); + virResctrlMonPtr mon=3D virResctrlMonNew(); virDomainCachetuneDefPtr tmp_cachetune =3D NULL; char *tmp =3D NULL; char *vcpus_str =3D NULL; @@ -18898,6 +18899,9 @@ virDomainCachetuneDefParse(virDomainDefPtr def, if (!alloc) goto cleanup; =20 + if (!mon) + goto cleanup; + if (VIR_ALLOC(tmp_cachetune) < 0) goto cleanup; =20 @@ -18970,8 +18974,12 @@ virDomainCachetuneDefParse(virDomainDefPtr def, if (virResctrlAllocSetID(alloc, alloc_id) < 0) goto cleanup; =20 + if (virResctrlMonSetID(mon, alloc_id) < 0) + goto cleanup; + VIR_STEAL_PTR(tmp_cachetune->vcpus, vcpus); VIR_STEAL_PTR(tmp_cachetune->alloc, alloc); + VIR_STEAL_PTR(tmp_cachetune->mon, mon); =20 if (VIR_APPEND_ELEMENT(def->cachetunes, def->ncachetunes, tmp_cachetun= e) < 0) goto cleanup; @@ -18990,6 +18998,20 @@ virDomainCachetuneDefParse(virDomainDefPtr def, } =20 =20 +static int +virDomainResctrlDefParse(virDomainDefPtr def, + xmlXPathContextPtr ctxr ATTRIBUTE_UNUSED) +{ + virResctrlMonPtr mon=3D virResctrlMonNew(); + if (virResctrlMonSetID(mon, "vcpu-rest") < 0) + return -1; + + def->resctrlmon_noalloc =3D mon; + + return 0; +} + + static virDomainDefPtr virDomainDefParseXML(xmlDocPtr xml, xmlNodePtr root, @@ -19585,6 +19607,12 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(nodes); =20 + if (virDomainResctrlDefParse(def, ctxt) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot extract resctrl")); + goto error; + } + if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu)= < 0) goto error; =20 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8a8121b..2febe62 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2234,6 +2234,7 @@ typedef virDomainCachetuneDef *virDomainCachetuneDefP= tr; struct _virDomainCachetuneDef { virBitmapPtr vcpus; virResctrlAllocPtr alloc; + virResctrlMonPtr mon; }; =20 =20 @@ -2389,6 +2390,8 @@ struct _virDomainDef { =20 virDomainCputune cputune; =20 + virResctrlMonPtr resctrlmon_noalloc; + virDomainCachetuneDefPtr *cachetunes; size_t ncachetunes; =20 diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index aa99cbb..c2e5d2a 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1309,6 +1309,12 @@ typedef int unsigned int action, unsigned int flags); =20 +typedef int +(*virDrvDomainSetResctrlMon)(virDomainPtr domain, + int enable, int disable); + +typedef char * +(*virDrvDomainGetResctrlMonSts)(virDomainPtr domain); =20 typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1558,6 +1564,8 @@ struct _virHypervisorDriver { virDrvDomainSetLifecycleAction domainSetLifecycleAction; virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU; virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU; + virDrvDomainSetResctrlMon domainSetResctrlMon; + virDrvDomainGetResctrlMonSts domainGetResctrlMonSts; }; =20 =20 diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index d44b553..07a19a6 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -12154,3 +12154,84 @@ int virDomainSetLifecycleAction(virDomainPtr domai= n, virDispatchError(domain->conn); return -1; } + + +/** + * virDomainSetResctrlMon: + * @domain: a domain object + * @enable: true(non-zero) for enbling resctrl mon group. + * @disable: true(non-zero) for disbling resctrl mon group. + * valid if @enable is false + * + * Enable or disable resctrl monitoring. + * + * Returns -1 in case of failure, 0 in case of success. + */ +int +virDomainSetResctrlMon(virDomainPtr domain, + int enable, int disable) +{ + int ret; + virConnectPtr conn; + + virResetLastError(); + + if(!disable && !enable) + return 0; + + virCheckDomainReturn(domain, -1); + + conn =3D domain->conn; + + if (conn->driver->domainSetResctrlMon) { + ret =3D conn->driver->domainSetResctrlMon(domain, + enable, disable); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} + + +/** + * virDomainGetResctrlMonSts: + * @domain: a domain object + * @status: pointer of a string buffer for holding resctrl mon + * group status string, caller is responsible for free it. + * + * Get domain resctrl status. + * + * Returns -1 in case of failure, 0 in case of success. + */ +int +virDomainGetResctrlMonSts(virDomainPtr domain, + char **status) +{ + int ret =3D -1; + virConnectPtr conn; + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + + conn =3D domain->conn; + + if (conn->driver->domainGetResctrlMonSts) { + *status =3D conn->driver->domainGetResctrlMonSts(domain); + if (*status) + ret =3D 0; + + goto done; + } + + virReportUnsupportedError(); + done: + virDispatchError(domain->conn); + return ret; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 4f54b84..fb3eef5 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -798,4 +798,10 @@ LIBVIRT_4.5.0 { virGetLastErrorDomain; } LIBVIRT_4.4.0; =20 +LIBVIRT_4.6.0 { + global: + virDomainSetResctrlMon; + virDomainGetResctrlMonSts; +} LIBVIRT_4.5.0; + # .... define new API here using predicted next version number .... diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 38ea865..4075daa 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -108,6 +108,7 @@ #include "virnuma.h" #include "dirname.h" #include "netdev_bandwidth_conf.h" +#include "virresctrl.h" =20 #define VIR_FROM_THIS VIR_FROM_QEMU =20 @@ -21437,6 +21438,144 @@ qemuDomainSetLifecycleAction(virDomainPtr dom, } =20 =20 +static int +qemuDomainSetResctrlMon(virDomainPtr dom, + int enable ,int disable) +{ + int ret =3D -1; + virDomainObjPtr vm; + virResctrlMonAct act =3D VIR_RESCTRL_MONACT_NONE;; + int i =3D 0; + unsigned int maxvcpus =3D 0; + + /* The 'enable' action will override the 'disable' one */ + if(disable) + act =3D VIR_RESCTRL_MONACT_DISABLE; + if(enable) + act =3D VIR_RESCTRL_MONACT_ENABLE; + + if (act =3D=3D VIR_RESCTRL_MONACT_NONE) + return 0; + + if (!(vm =3D qemuDomObjFromDomain(dom))) + return ret; + + qemuDomainObjPrivatePtr priv =3D vm->privateData; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is not running")); + goto cleanup; + } + + /* If 'resctrl' is enabled in xml configuation file through 'cachetune' + * section, this interface doesn't work. return 1 for this case */ + if (vm->def->ncachetunes !=3D 0){ + VIR_DEBUG("resctrl monitoring interface is governed by domain " + "configration 'cachetune' sections. Interface disabled.\n"); + ret =3D 1; + goto cleanup; + } + + if (act =3D=3D VIR_RESCTRL_MONACT_ENABLE) { + + if (!vm->def->resctrlmon_noalloc){ + virReportError(VIR_ERR_NO_DOMAIN, + _("resctrlmon_noalloc should be allocated.")); + goto cleanup; + } + + if(!virResctrlMonIsRunning(vm->def->resctrlmon_noalloc)) { + + if (virResctrlMonCreate(NULL, + vm->def->resctrlmon_noalloc, priv->machineName) < = 0) + goto cleanup; + + /* Set vcpus */ + maxvcpus =3D virDomainDefGetVcpusMax(vm->def); + for (i =3D 0; i < maxvcpus; i++) { + virDomainVcpuDefPtr vcpu + =3D virDomainDefGetVcpu(vm->def, i); + + if (!vcpu->online) + continue; + + pid_t vcpupid =3D qemuDomainGetVcpuPid(vm, i); + if (virResctrlMonAddPID(vm->def->resctrlmon_noalloc, + vcpupid) < 0) + goto cleanup; + } + } + + VIR_DEBUG("resctrl monitoring is enabled"); + } else if (act =3D=3D VIR_RESCTRL_MONACT_DISABLE){ + if (!vm->def->resctrlmon_noalloc){ + virReportError(VIR_ERR_NO_DOMAIN, + _("resctrlmon_noalloc should be allocated.")); + goto cleanup; + } + + if(virResctrlMonIsRunning(vm->def->resctrlmon_noalloc)) { + if (virResctrlMonRemove(vm->def->resctrlmon_noalloc) < 0){ + virReportError(VIR_ERR_NO_DOMAIN, + _("Error in remove resctrl mon group.")); + goto cleanup; + } + } + + VIR_DEBUG("resctrl monitoring is disabled\n"); + } + + ret =3D 0; +cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + +static char * +qemuDomainGetResctrlMonSts(virDomainPtr dom) +{ + virDomainObjPtr vm; + char *sts =3D NULL; + + if (!(vm =3D qemuDomObjFromDomain(dom))) + return sts; + + if (vm->def->ncachetunes !=3D 0){ + VIR_DEBUG("resctrl monitoring interface is governed by domain " + "'cachetune' sections. resctrl monitoring is compulsively enabled.\= n"); + + /* only check cachetune[0] for domain resctrl mon group status */ + if (!virResctrlMonIsRunning(vm->def->cachetunes[0]->mon)) { + if (virAsprintf(&sts, "Disabled") < 0) + goto cleanup; + } else { + if (virAsprintf(&sts, "Enabled (forced by cachetune)") < 0) + goto cleanup; + } + + } else { + + if (vm->def->resctrlmon_noalloc && + virResctrlMonIsRunning(vm->def->resctrlmon_noalloc)){ + if (virAsprintf(&sts, "Enabled") < 0) + goto cleanup; + + } else { + if (virAsprintf(&sts, "Disabled") < 0) + goto cleanup; + } + } + + VIR_DEBUG("resctrl monitoring status: %s\n", sts); + +cleanup: + virDomainObjEndAPI(&vm); + return sts; +} + + static virHypervisorDriver qemuHypervisorDriver =3D { .name =3D QEMU_DRIVER_NAME, .connectURIProbe =3D qemuConnectURIProbe, @@ -21660,6 +21799,8 @@ static virHypervisorDriver qemuHypervisorDriver =3D= { .domainSetLifecycleAction =3D qemuDomainSetLifecycleAction, /* 3.9.0 */ .connectCompareHypervisorCPU =3D qemuConnectCompareHypervisorCPU, /* 4= .4.0 */ .connectBaselineHypervisorCPU =3D qemuConnectBaselineHypervisorCPU, /*= 4.4.0 */ + .domainSetResctrlMon =3D qemuDomainSetResctrlMon, /*FIXME: assign prop= er ver string */ + .domainGetResctrlMonSts =3D qemuDomainGetResctrlMonSts, /*FIXME: assig= n proper ver string */ }; =20 =20 diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 1606f4c..4fab0e1 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2461,6 +2461,11 @@ qemuProcessResctrlCreate(virQEMUDriverPtr driver, vm->def->cachetunes[i]->alloc, priv->machineName) < 0) goto cleanup; + + if (virResctrlMonCreate(vm->def->cachetunes[i]->alloc, + vm->def->cachetunes[i]->mon, + priv->machineName) < 0) + goto cleanup; } =20 ret =3D 0; @@ -5259,6 +5264,7 @@ qemuProcessSetupVcpu(virDomainObjPtr vm, &vcpu->sched) < 0) return -1; =20 + =20 for (i =3D 0; i < vm->def->ncachetunes; i++) { virDomainCachetuneDefPtr ct =3D vm->def->cachetunes[i]; =20 @@ -5279,6 +5285,10 @@ qemuProcessSetupVcpus(virDomainObjPtr vm) virDomainVcpuDefPtr vcpu; unsigned int maxvcpus =3D virDomainDefGetVcpusMax(vm->def); size_t i; + virBitmapPtr vcpuleft =3D NULL; + int ret =3D -1; + + qemuDomainObjPrivatePtr priv =3D vm->privateData; =20 if ((vm->def->cputune.period || vm->def->cputune.quota) && !virCgroupHasController(((qemuDomainObjPrivatePtr) vm->privateData= )->cgroup, @@ -5308,17 +5318,52 @@ qemuProcessSetupVcpus(virDomainObjPtr vm) return 0; } =20 + /* To monitor whole domain's cache occupancy information + * create mon group for un-covered VCPUs */ + if (!(vcpuleft =3D virBitmapNew(maxvcpus + 1))) + goto cleanup; + + virBitmapClearAll(vcpuleft); + for (i =3D 0; i < maxvcpus; i++) { vcpu =3D virDomainDefGetVcpu(vm->def, i); =20 if (!vcpu->online) continue; =20 + if ( virBitmapSetBit(vcpuleft, i) < 0) + goto cleanup; + if (qemuProcessSetupVcpu(vm, i) < 0) return -1; } =20 - return 0; + for (i =3D 0; i < vm->def->ncachetunes; i++) { + virDomainCachetuneDefPtr ct =3D vm->def->cachetunes[i]; + virBitmapSubtract(vcpuleft, ct->vcpus); + } + + + if (vm->def->ncachetunes && + !virBitmapIsAllClear(vcpuleft)){ + + if (virResctrlMonCreate(NULL, vm->def->resctrlmon_noalloc, priv->mach= ineName) < 0) + goto cleanup; + + for (i =3D 0; i < maxvcpus; i++) { + if (virBitmapIsBitSet(vcpuleft, i)){ + pid_t vcpupid =3D qemuDomainGetVcpuPid(vm, i); + + if (virResctrlMonAddPID(vm->def->resctrlmon_noalloc, vcpupid) < 0) + goto cleanup; + } + } + } + + ret =3D 0; +cleanup: + virBitmapFree(vcpuleft); + return ret; } =20 =20 @@ -6895,8 +6940,14 @@ void qemuProcessStop(virQEMUDriverPtr driver, /* Remove resctrl allocation after cgroups are cleaned up which makes = it * kind of safer (although removing the allocation should work even wi= th * pids in tasks file */ - for (i =3D 0; i < vm->def->ncachetunes; i++) + for (i =3D 0; i < vm->def->ncachetunes; i++){ virResctrlAllocRemove(vm->def->cachetunes[i]->alloc); + virResctrlMonRemove(vm->def->cachetunes[i]->mon); + } + + if(vm->def->resctrlmon_noalloc) + virResctrlMonRemove(vm->def->resctrlmon_noalloc); + =20 qemuProcessRemoveDomainStatus(driver, vm); =20 @@ -7620,8 +7671,18 @@ qemuProcessReconnect(void *opaque) if (virResctrlAllocDeterminePath(obj->def->cachetunes[i]->alloc, priv->machineName) < 0) goto error; + + if (virResctrlMonDeterminePath(obj->def->cachetunes[i]->mon, + priv->machineName) < 0) + goto error; + } =20 + if(obj->def->resctrlmon_noalloc && + virResctrlMonDeterminePath(obj->def->resctrlmon_noalloc, + priv->machineName) < 0) + goto error; + /* update domain state XML with possibly updated state in virDomainObj= */ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, obj, driver->ca= ps) < 0) goto error; diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index 81d0445..2ef0e5e 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -7107,3 +7107,48 @@ remoteSerializeDomainDiskErrors(virDomainDiskErrorPt= r errors, } return -1; } + +static int remoteDispatchDomainGetResctrlMonSts( + virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_resctrl_mon_sts_args *args, + remote_domain_get_resctrl_mon_sts_ret *ret) +{ + int rv =3D -1; + virDomainPtr dom =3D NULL; + char *sts =3D NULL; + char **sts_p =3D NULL; + struct daemonClientPrivate *priv =3D + virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not ope= n")); + goto cleanup; + } + + if (!(dom =3D get_nonnull_domain(priv->conn, args->dom))) + goto cleanup; + + if ((rv =3D virDomainGetResctrlMonSts(dom, &sts)) < 0) + goto cleanup; + + if (VIR_ALLOC(sts_p) < 0) + goto cleanup; + + if (VIR_STRDUP(*sts_p, sts) < 0) + goto cleanup; + + ret->sts =3D sts_p; + rv =3D 0; + +cleanup: + if (rv < 0) { + virNetMessageSaveError(rerr); + VIR_FREE(sts_p); + } + virObjectUnref(dom); + VIR_FREE(sts); + return rv; +} diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index c22993c..4a6b101 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8451,6 +8451,8 @@ static virHypervisorDriver hypervisor_driver =3D { .domainSetLifecycleAction =3D remoteDomainSetLifecycleAction, /* 3.9.0= */ .connectCompareHypervisorCPU =3D remoteConnectCompareHypervisorCPU, /*= 4.4.0 */ .connectBaselineHypervisorCPU =3D remoteConnectBaselineHypervisorCPU, = /* 4.4.0 */ + .domainSetResctrlMon =3D remoteDomainSetResctrlMon, /*FIXME: assign pr= oper ver string */ + .domainGetResctrlMonSts =3D remoteDomainGetResctrlMonSts, /*FIXME: ass= ign proper ver string */ }; =20 static virNetworkDriver network_driver =3D { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index a0ab7e9..9242a61 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3480,6 +3480,20 @@ struct remote_connect_baseline_hypervisor_cpu_ret { remote_nonnull_string cpu; }; =20 +struct remote_domain_set_resctrl_mon_args { + remote_nonnull_domain dom; + int enable; + int disable; +}; + +struct remote_domain_get_resctrl_mon_sts_args { + remote_nonnull_domain dom; +}; + +struct remote_domain_get_resctrl_mon_sts_ret { /* insert@1 */ + remote_string sts; +}; + /*----- Protocol. -----*/ =20 /* Define the program number, protocol version and procedure numbers here.= */ @@ -6187,5 +6201,17 @@ enum remote_procedure { * @generate: both * @acl: connect:write */ - REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU =3D 394 + REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU =3D 394, + + /** + * @generate: both + * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_SET_RESCTRL_MON =3D 395, + + /** + * @generate: client + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_GET_RESCTRL_MON_STS =3D 396 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 0c4cfc6..ed6a782 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2907,6 +2907,16 @@ struct remote_connect_baseline_hypervisor_cpu_args { struct remote_connect_baseline_hypervisor_cpu_ret { remote_nonnull_string cpu; }; +struct remote_domain_set_resctrl_mon_args { + remote_nonnull_domain dom; + int enable; + int disable; +} +struct remote_domain_get_resctrl_mon_sts_args { + remote_nonnull_domain dom; +}; +struct remote_domain_get_resctrl_mon_sts_ret { + remote_string sts; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN =3D 1, REMOTE_PROC_CONNECT_CLOSE =3D 2, @@ -3302,4 +3312,6 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_DETACH_DEVICE_ALIAS =3D 392, REMOTE_PROC_CONNECT_COMPARE_HYPERVISOR_CPU =3D 393, REMOTE_PROC_CONNECT_BASELINE_HYPERVISOR_CPU =3D 394, + REMOTE_PROC_DOMAIN_SET_RESCTRL_MON =3D 395, + REMOTE_PROC_DOMAIN_GET_RESCTRL_MON_STS =3D 396, }; diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 6aa79f1..4ae8ed2 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -7677,6 +7677,74 @@ cmdIOThreadDel(vshControl *ctl, const vshCmd *cmd) return ret; } =20 +static const vshCmdInfo info_resctrl[] =3D { + {.name =3D "help", + .data =3D N_("get or set hardware CPU resource monitoring functions") + }, + {.name =3D "desc", + .data =3D N_("Enable or disable resctrl monitoring for a guest domain= .\n" + " To get resctrl status use following" + " command: \n\n" + " virsh # resctrl ") + }, + {.name =3D NULL} +}; + +static const vshCmdOptDef opts_resctrl[] =3D { + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), + {.name =3D "enable", + .type =3D VSH_OT_BOOL, + .help =3D N_("Enable resctrl function such as monitoring cache occupa= ncy " + "or memory bandwidth.") + }, + {.name =3D "disable", + .type =3D VSH_OT_BOOL, + .help =3D N_("Disable hardware function such as monitoring cache occu= pancy " + "or memory bandwidth.") + }, + {.name =3D NULL} +}; + + +static bool +cmdResctrl(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret =3D false; + char *ressts =3D NULL; + + bool enable =3D vshCommandOptBool(cmd, "enable"); + bool disable=3D vshCommandOptBool(cmd, "disable"); + + if (!(dom =3D virshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if(!enable && !disable){ + if (virDomainGetResctrlMonSts(dom, &ressts) < 0) + goto cleanup; + + if (!ressts) + goto cleanup; + + } else { + if (virDomainSetResctrlMon(dom, enable, disable) < 0) + goto cleanup; + + if (virDomainGetResctrlMonSts(dom, &ressts) < 0) + goto cleanup; + + if (!ressts) + goto cleanup; + } + + vshPrint(ctl,"RDT Monitoring Status: %s\n", ressts); + ret =3D true; +cleanup: + VIR_FREE(ressts); + virshDomainFree(dom); + return ret; +} + /* * "cpu-stats" command */ @@ -13799,6 +13867,12 @@ const vshCmdDef domManagementCmds[] =3D { .flags =3D 0 }, #endif + {.name =3D "resctrl", + .handler =3D cmdResctrl, + .opts =3D opts_resctrl, + .info =3D info_resctrl, + .flags =3D 0 + }, {.name =3D "cpu-stats", .handler =3D cmdCPUStats, .opts =3D opts_cpu_stats, --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Tue Apr 16 11:15:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 152845039208726.32391676542761; Fri, 8 Jun 2018 02:33:12 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BD19E308A945; Fri, 8 Jun 2018 09:33:10 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8C351A1105; Fri, 8 Jun 2018 09:33:10 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 31A0F4CA83; Fri, 8 Jun 2018 09:33:10 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w589WsvL010299 for ; Fri, 8 Jun 2018 05:32:54 -0400 Received: by smtp.corp.redhat.com (Postfix) id 625561001F44; Fri, 8 Jun 2018 09:32:54 +0000 (UTC) Received: from mx1.redhat.com (ext-mx13.extmail.prod.ext.phx2.redhat.com [10.5.110.42]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5919210018FD for ; Fri, 8 Jun 2018 09:32:51 +0000 (UTC) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BD32F3082122 for ; Fri, 8 Jun 2018 09:32:50 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Jun 2018 02:32:50 -0700 Received: from david-unc.bj.intel.com ([10.238.145.77]) by fmsmga004.fm.intel.com with ESMTP; 08 Jun 2018 02:32:49 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,490,1520924400"; d="scan'208";a="61461062" From: Wang Huaqiang To: libvir-list@redhat.com Date: Fri, 8 Jun 2018 17:02:19 +0800 Message-Id: <1528448539-25588-4-git-send-email-huaqiang.wang@intel.com> In-Reply-To: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> References: <1528448539-25588-1-git-send-email-huaqiang.wang@intel.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 08 Jun 2018 09:32:50 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 08 Jun 2018 09:32:50 +0000 (UTC) for IP:'192.55.52.120' DOMAIN:'mga04.intel.com' HELO:'mga04.intel.com' FROM:'huaqiang.wang@intel.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 192.55.52.120 mga04.intel.com 192.55.52.120 mga04.intel.com X-Scanned-By: MIMEDefang 2.84 on 10.5.110.42 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Cc: shaohe.feng@intel.com, Wang Huaqiang , bing.niu@intel.com, jian-feng.ding@intel.com, rui.zang@intel.com Subject: [libvirt] [PATCH 3/3] tools: virsh domstats: show RDT CMT resource utilization information X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 08 Jun 2018 09:33:11 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" --- include/libvirt/libvirt-domain.h | 1 + src/libvirt-domain.c | 11 +++++++++ src/qemu/qemu_driver.c | 48 ++++++++++++++++++++++++++++++++++++= ++++ tools/virsh-domain-monitor.c | 7 ++++++ 4 files changed, 67 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index 598db28..696b686 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -2041,6 +2041,7 @@ typedef enum { VIR_DOMAIN_STATS_INTERFACE =3D (1 << 4), /* return domain interfaces i= nfo */ VIR_DOMAIN_STATS_BLOCK =3D (1 << 5), /* return domain block info */ VIR_DOMAIN_STATS_PERF =3D (1 << 6), /* return domain perf event info */ + VIR_DOMAIN_STATS_RESCTRL =3D (1<<7), /* return resctrlfs mornitoring = info */ } virDomainStatsTypes; =20 typedef enum { diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 07a19a6..3f1e156 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11486,6 +11486,17 @@ virConnectGetDomainCapabilities(virConnectPtr conn, * long long. It is produced by the * emulation_faults perf event * + * VIR_DOMAIN_STATS_RESCTRL + * "resctrl.cmt" - the usage of l3 cache (bytes) by applications runn= ing on + * the platform as unsigned long long. It is retrieved f= rom + * resctrl file system. + * "resctrl.mbmt" - the total system bandwidth (bytes/s) from one leve= l of + * cache to another as unsigned long long. Retrieved fr= om + * resctrl file system. + * "resctrl.mbml" - the amount of data (bytes/s) sent through the memo= ry + * controller on the socket as unsigned long long. Retr= ieved + * from resctrl file system. + * * Note that entire stats groups or individual stat fields may be missing = from * the output in case they are not supported by the given hypervisor, are = not * applicable for the current state of the guest domain, or their retrieval diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4075daa..8004e26 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -20313,6 +20313,53 @@ qemuDomainGetStatsPerf(virQEMUDriverPtr driver ATT= RIBUTE_UNUSED, return ret; } =20 +static int +qemuDomainGetStatsResctrl(virQEMUDriverPtr driver ATTRIBUTE_UNUSED, + virDomainObjPtr vm, + virDomainStatsRecordPtr record, + int *maxparams, + unsigned int privflags ATTRIBUTE_UNUSED) +{ + size_t i; + unsigned int llc_occu; + unsigned int llc_occu_total=3D 0; + int ret =3D -1; +#define DOMAIN_STATE_STR_RESCTRL "resctrl" + + for (i =3D 0; i < vm->def->ncachetunes; i++) { + virDomainCachetuneDefPtr ct =3D vm->def->cachetunes[i]; + + if (virResctrlMonIsRunning(ct->mon)) { + VIR_DEBUG("llc_occupancy: checking cachetune [%ld] ", i); + if (virResctrlMonGetCacheOccupancy(ct->mon, &llc_occu) < 0) + goto cleanup; + llc_occu_total +=3D llc_occu; + } + } + + if (vm->def->resctrlmon_noalloc && + virResctrlMonIsRunning(vm->def->resctrlmon_noalloc)) { + VIR_DEBUG("llc_occupancy: checking resctrl vcpu-rest"); + if (virResctrlMonGetCacheOccupancy( + vm->def->resctrlmon_noalloc, &llc_occu) < 0) + goto cleanup; + llc_occu_total +=3D llc_occu; + } + + if (virTypedParamsAddInt(&record->params, + &record->nparams, + maxparams, + DOMAIN_STATE_STR_RESCTRL + ".cmt", + llc_occu_total) < 0){ + goto cleanup; + } + + ret =3D 0; +cleanup: + return ret; +} + typedef int (*qemuDomainGetStatsFunc)(virQEMUDriverPtr driver, virDomainObjPtr dom, @@ -20334,6 +20381,7 @@ static struct qemuDomainGetStatsWorker qemuDomainGe= tStatsWorkers[] =3D { { qemuDomainGetStatsInterface, VIR_DOMAIN_STATS_INTERFACE, false }, { qemuDomainGetStatsBlock, VIR_DOMAIN_STATS_BLOCK, true }, { qemuDomainGetStatsPerf, VIR_DOMAIN_STATS_PERF, false }, + { qemuDomainGetStatsResctrl, VIR_DOMAIN_STATS_RESCTRL, false }, { NULL, 0, false } }; =20 diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 8cbb3db..b08d977 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1948,6 +1948,10 @@ static const vshCmdOptDef opts_domstats[] =3D { .type =3D VSH_OT_BOOL, .help =3D N_("report domain perf event statistics"), }, + {.name =3D "resctrl", + .type =3D VSH_OT_BOOL, + .help =3D N_("report resctrlfs mon group information"), + }, {.name =3D "list-active", .type =3D VSH_OT_BOOL, .help =3D N_("list only active domains"), @@ -2057,6 +2061,9 @@ cmdDomstats(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptBool(cmd, "perf")) stats |=3D VIR_DOMAIN_STATS_PERF; =20 + if (vshCommandOptBool(cmd, "resctrl")) + stats |=3D VIR_DOMAIN_STATS_RESCTRL; + if (vshCommandOptBool(cmd, "list-active")) flags |=3D VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE; =20 --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list