From nobody Mon Apr 29 02:56:37 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.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1492163960797924.6009971285755; Fri, 14 Apr 2017 02:59:20 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 099347E9D1; Fri, 14 Apr 2017 09:59:18 +0000 (UTC) Received: from colo-mx.corp.redhat.com (unknown [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CFDEA1836A; Fri, 14 Apr 2017 09:59:15 +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 218544E9BB; Fri, 14 Apr 2017 09:59:12 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v3E9x9tu026295 for ; Fri, 14 Apr 2017 05:59:09 -0400 Received: by smtp.corp.redhat.com (Postfix) id A816519E2C; Fri, 14 Apr 2017 09:59:09 +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 E19AB19CA4; Fri, 14 Apr 2017 09:59:07 +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 D3FC6C057FA5; Fri, 14 Apr 2017 09:59:03 +0000 (UTC) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Apr 2017 02:59:03 -0700 Received: from s2600wt.sh.intel.com ([10.239.48.158]) by fmsmga005.fm.intel.com with ESMTP; 14 Apr 2017 02:59:02 -0700 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 099347E9D1 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=intel.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 099347E9D1 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com D3FC6C057FA5 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=intel.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=liyong.qiao@intel.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com D3FC6C057FA5 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.37,197,1488873600"; d="scan'208";a="88950854" From: Eli Qiao To: libvir-list@redhat.com Date: Fri, 14 Apr 2017 18:01:46 +0800 Message-Id: <1492164106-27618-1-git-send-email-liyong.qiao@intel.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 203 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 14 Apr 2017 09:59:04 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 14 Apr 2017 09:59:04 +0000 (UTC) for IP:'192.55.52.120' DOMAIN:'mga04.intel.com' HELO:'mga04.intel.com' FROM:'liyong.qiao@intel.com' RCPT:'' X-RedHat-Spam-Score: -1.902 (BAYES_50, DCC_REPUT_00_12, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, 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.11 X-loop: libvir-list@redhat.com Cc: mkletzan@redhat.com, liyong.qiao@intel.com Subject: [libvirt] [PATCH RFC V2] RFC: Reimplement cache allocation for a VM 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 14 Apr 2017 09:59:19 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This is a RFC patch for the reimplement of `support cache tune(CAT) in libvirt`[1]. This patch defines some structs to represent data struct in linux resctrl fs which will be used later to do cache allocation. The patch expose a private interface `virResctrlFreeSchemata`, which will be used to query the cache allocation on the host. Also added unit test cases to test this interface can works well. There are already patch sets[2] to address it, and functional works, but people doesn't like it cause it has global variable, and missing unit test case for new added capabilites, etc. Martin has proposed a test infra to do vircaps2xmltest, and I extened it on top of it to extend resctrl control[3], this is kinds of new desiged apart from [2], so I propose this RFC patch to do some rework on it. [1] https://www.redhat.com/archives/libvir-list/2017-January/msg00683.html [2] https://www.redhat.com/archives/libvir-list/2017-March/msg00181.html [3] https://www.redhat.com/archives/libvir-list/2017-April/msg00516.html --- include/libvirt/virterror.h | 1 + src/Makefile.am | 1 + src/libvirt_private.syms | 6 + src/util/virerror.c | 1 + src/util/virresctrl.c | 423 ++++++++++++++++++++++++++= ++++ src/util/virresctrl.h | 86 ++++++ tests/Makefile.am | 7 +- tests/virresctrldata/L3-free.schemata | 1 + tests/virresctrldata/L3CODE-free.schemata | 1 + tests/virresctrldata/L3DATA-free.schemata | 1 + tests/virresctrltest.c | 117 +++++++++ 11 files changed, 644 insertions(+), 1 deletion(-) create mode 100644 src/util/virresctrl.c create mode 100644 src/util/virresctrl.h create mode 100644 tests/virresctrldata/L3-free.schemata create mode 100644 tests/virresctrldata/L3CODE-free.schemata create mode 100644 tests/virresctrldata/L3DATA-free.schemata create mode 100644 tests/virresctrltest.c diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 2efee8f..4bc0c74 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -132,6 +132,7 @@ typedef enum { VIR_FROM_PERF =3D 65, /* Error from perf */ VIR_FROM_LIBSSH =3D 66, /* Error from libssh connection transpor= t */ + VIR_FROM_RESCTRL =3D 67, /* Error from resctrl */ # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST diff --git a/src/Makefile.am b/src/Makefile.am index 60eba37..0ae2af5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -165,6 +165,7 @@ UTIL_SOURCES =3D \ util/virprocess.c util/virprocess.h \ util/virqemu.c util/virqemu.h \ util/virrandom.h util/virrandom.c \ + util/virresctrl.h util/virresctrl.c \ util/virrotatingfile.h util/virrotatingfile.c \ util/virscsi.c util/virscsi.h \ util/virscsihost.c util/virscsihost.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9d7760d..b7225fe 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2396,6 +2396,12 @@ virRandomGenerateWWN; virRandomInt; +# util/virresctrl.h +virResctrlFreeSchemata; +virResctrlGetFreeCache; +virResctrlTypeToString; + + # util/virrotatingfile.h virRotatingFileReaderConsume; virRotatingFileReaderFree; diff --git a/src/util/virerror.c b/src/util/virerror.c index ef17fb5..02fabcc 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -139,6 +139,7 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST, "Perf", /* 65 */ "Libssh transport layer", + "Resource Control", ) diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c new file mode 100644 index 0000000..778c2ec --- /dev/null +++ b/src/util/virresctrl.c @@ -0,0 +1,423 @@ +/* + * virresctrl.c: methods for managing resource control + * + * Copyright (C) 2017 Intel, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Authors: + * Eli Qiao + */ + +#include +#include +#include +#include +#include + +#include "virresctrl.h" +#include "virerror.h" +#include "virlog.h" +#include "viralloc.h" +#include "virstring.h" +#include "virfile.h" + +VIR_LOG_INIT("util.resctrl"); + +#define VIR_FROM_THIS VIR_FROM_RESCTRL +#define SYSFS_RESCTRL_PATH "/sys/fs/resctrl/" + +VIR_ENUM_IMPL(virResctrl, VIR_RESCTRL_TYPE_LAST, + "L3", + "L3CODE", + "L3DATA", + "L2") + +/** + * a virResctrlDomain represents a resource control group, it's a directory + * under /sys/fs/resctrl. + * eg: /sys/fs/resctrl/CG1 + * |-- cpus + * |-- schemata + * `-- tasks + * # cat schemata + * L3DATA:0=3Dfffff;1=3Dfffff + * L3CODE:0=3Dfffff;1=3Dfffff + * + * Besides, it can also represent the default resource control group of the + * host. + */ + +typedef struct _virResctrlGroup virResctrlGroup; +typedef virResctrlGroup *virResctrlGroupPtr; +struct _virResctrlGroup { + char *name; /* resource group name, eg: CG1. If it represent host's + default resource group name, should be a NULL pointer */ + size_t n_tasks; /* number of task assigned to the resource group */ + char **tasks; /* task list which contains task id eg: 77454 */ + + size_t n_schematas; /* number of schemata the resource group contains, + eg: 2 */ + virResctrlSchemataPtr *schematas; /* scheamta list */ +}; + +/* All resource control groups on this host, including default resource gr= oup */ +typedef struct _virResctrlDomain virResctrlDomain; +typedef virResctrlDomain *virResctrlDomainPtr; +struct _virResctrlDomain { + size_t n_groups; /* number of resource control group */ + virResctrlGroupPtr *groups; /* list of resource control group */ +}; + +void +virResctrlFreeSchemata(virResctrlSchemataPtr ptr) +{ + size_t i; + + if (!ptr) + return; + + for (i =3D 0; i < ptr->n_schemata_items; i++) + VIR_FREE(ptr->schemata_items[i]); +} + +static void +virResctrlFreeGroup(virResctrlGroupPtr ptr) +{ + size_t i; + + if (!ptr) + return; + + for (i =3D 0; i < ptr->n_tasks; i++) + VIR_FREE(ptr->tasks[i]); + + for (i =3D 0; i < ptr->n_schematas; i++) { + virResctrlFreeSchemata(ptr->schematas[i]); + VIR_FREE(ptr->schematas[i]); + } +} + +static void +virResctrlFreeDomain(virResctrlDomainPtr ptr) +{ + size_t i; + + if (!ptr) + return; + + for (i =3D 0; i < ptr->n_groups; i++) { + virResctrlFreeGroup(ptr->groups[i]); + VIR_FREE(ptr->groups[i]); + } +} + +static int +virResctrlCopySchemata(virResctrlSchemataPtr src, + virResctrlSchemataPtr *dst) +{ + size_t i; + virResctrlSchemataItemPtr schemataitem; + virResctrlSchemataPtr schemata; + + if (VIR_ALLOC(schemata) < 0) + return -1; + + schemata->type =3D src->type; + + for (i =3D 0; i < src->n_schemata_items; i++) { + if (VIR_ALLOC(schemataitem) < 0) + goto error; + + schemataitem->cache_id =3D src->schemata_items[i]->cache_id; + schemataitem->continuous_schemata =3D src->schemata_items[i]->cont= inuous_schemata; + schemataitem->schemata =3D src->schemata_items[i]->schemata; + schemataitem->size =3D src->schemata_items[i]->size; + + if (VIR_APPEND_ELEMENT(schemata->schemata_items, + schemata->n_schemata_items, + schemataitem) < 0) + goto error; + } + + *dst =3D schemata; + + return 0; + + error: + virResctrlFreeSchemata(schemata); + return -1; +} + +static int +virResctrlGetSchemataString(virResctrlType type, + const char *name, + char **schemata) +{ + int rc =3D -1; + char *tmp =3D NULL; + char *end =3D NULL; + char *buf =3D NULL; + char *type_suffix =3D NULL; + + if (virFileReadValueString(&buf, + SYSFS_RESCTRL_PATH "%s/schemata", + name ? name : "") < 0) + return -1; + + if (virAsprintf(&type_suffix, + "%s:", + virResctrlTypeToString(type)) < 0) + goto cleanup; + + tmp =3D strstr(buf, type_suffix); + + if (!tmp) + goto cleanup; + + end =3D strchr(tmp, '\n'); + if (end !=3D NULL) + *end =3D '\0'; + + if (VIR_STRDUP(*schemata, tmp) < 0) + goto cleanup; + + rc =3D 0; + + cleanup: + VIR_FREE(buf); + VIR_FREE(type_suffix); + return rc; +} + +static int +virResctrlLoadSchemata(const char* schemata_str, + virResctrlSchemataPtr schemata) +{ + VIR_DEBUG("%s, %p\n", schemata_str, schemata); + + int ret =3D -1; + char **lists =3D NULL; + char **sms =3D NULL; + char **sis =3D NULL; + size_t i; + virResctrlSchemataItemPtr si; + + /* parse L3:0=3Dfffff;1=3Df */ + lists =3D virStringSplit(schemata_str, ":", 2); + + if ((!lists) || (!lists[1])) + goto cleanup; + + /* parse 0=3Dfffff;1=3Df */ + sms =3D virStringSplit(lists[1], ";", 0); + if (!sms) + goto cleanup; + + for (i =3D 0; sms[i] !=3D NULL; i++) { + /* parse 0=3Dfffff */ + sis =3D virStringSplit(sms[i], "=3D", 2); + if (!sis) + goto cleanup; + + if (VIR_ALLOC(si) < 0) + goto cleanup; + + if (virStrToLong_ui(sis[0], NULL, 10, &si->cache_id) < 0) + goto cleanup; + + if (virStrToLong_ui(sis[1], NULL, 16, &si->continuous_schemata) < = 0) + goto cleanup; + + si->schemata =3D si->continuous_schemata; + + if (VIR_APPEND_ELEMENT(schemata->schemata_items, + schemata->n_schemata_items, + si) < 0) + goto cleanup; + + } + + ret =3D 0; + + cleanup: + VIR_FREE(si); + virStringListFree(lists); + virStringListFree(sms); + virStringListFree(sis); + return ret; +} + +static int +virResctrlLoadGroup(const char *name, + virResctrlDomainPtr dom) +{ + VIR_DEBUG("%s, %p\n", name, dom); + + int ret =3D -1; + char *path =3D NULL; + char *schemata_str; + virResctrlType i; + int rv; + virResctrlGroupPtr grp; + virResctrlSchemataPtr schemata; + + if ((virAsprintf(&path, "%s/%s", SYSFS_RESCTRL_PATH, name)) < 0) + return -1; + + if (!virFileExists(path)) + goto cleanup; + + if (VIR_ALLOC(grp) < 0) + goto cleanup; + + if (VIR_STRDUP(grp->name, name) < 0) + goto cleanup; + + for (i =3D 0; i < VIR_RESCTRL_TYPE_LAST; i++) { + rv =3D virResctrlGetSchemataString(i, name, &schemata_str); + if (rv < 0) + continue; + + if (VIR_ALLOC(schemata) < 0) + goto cleanup; + + schemata->type =3D i; + + if (virResctrlLoadSchemata(schemata_str, schemata) < 0) + goto cleanup; + + VIR_FREE(schemata_str); + + if (VIR_APPEND_ELEMENT(grp->schematas, + grp->n_schematas, + schemata) < 0) + goto cleanup; + + virResctrlFreeSchemata(schemata); + } + + if (VIR_APPEND_ELEMENT(dom->groups, + dom->n_groups, + grp) < 0) + goto cleanup; + + ret =3D 0; + + cleanup: + VIR_FREE(path); + virResctrlFreeGroup(grp); + return ret; +} + +static int +virResctrlLoadDomain(virResctrlDomainPtr dom) +{ + int ret =3D -1; + int rv =3D -1; + DIR *dirp =3D NULL; + char *path =3D NULL; + struct dirent *ent; + + VIR_DEBUG("%s, %p\n", "", dom); + + rv =3D virDirOpenIfExists(&dirp, SYSFS_RESCTRL_PATH); + + if (rv < 0) + goto cleanup; + + /* load default resctrl group */ + if (virResctrlLoadGroup("", dom) < 0) + goto cleanup; + + while ((rv =3D virDirRead(dirp, &ent, path)) > 0) { + /* only read directory in resctrl */ + if ((ent->d_type !=3D DT_DIR) || STREQ(ent->d_name, "info")) + continue; + + if (virResctrlLoadGroup(ent->d_name, dom) < 0) + goto cleanup; + } + + ret =3D 0; + + cleanup: + virDirClose(&dirp); + return ret; +} + +static void +virResctrlRefreshDom(virResctrlDomainPtr dom, virResctrlType type) +{ + size_t i; + size_t j; + size_t k; + + virResctrlGroupPtr default_grp =3D NULL; + virResctrlGroupPtr grp =3D NULL; + virResctrlSchemataPtr schemata =3D NULL; + virResctrlSchemataItemPtr schemataitem =3D NULL; + + default_grp =3D dom->groups[0]; + + /* We are sure that the first group is the default one */ + for (i =3D 1; i < dom->n_groups; i++) { + grp =3D dom->groups[i]; + for (j =3D 0; j < grp->n_schematas; j++) { + schemata =3D grp->schematas[j]; + /* we can only calculate one type of schemata */ + if (schemata->type !=3D type) + continue; + for (k =3D 0; k < schemata->n_schemata_items; k++) { + schemataitem =3D schemata->schemata_items[k]; + /* if the schemata =3D 1, ignore it */ + if (schemataitem->continuous_schemata > 1) + /* calculate default schemata, it can be non-continuou= s */ + default_grp->schematas[j]->schemata_items[k]->schemata= &=3D ~(schemataitem->continuous_schemata); + } + } + } +} + +int virResctrlGetFreeCache(virResctrlType type, + virResctrlSchemataPtr *schemata) +{ + VIR_DEBUG("%d, %p\n", type, schemata); + int ret =3D -1; + size_t i; + virResctrlDomainPtr dom =3D NULL; + virResctrlGroupPtr grp =3D NULL; + + if (VIR_ALLOC(dom) < 0) + return -1; + + if (virResctrlLoadDomain(dom) < 0) + goto cleanup; + + virResctrlRefreshDom(dom, type); + grp =3D dom->groups[0]; + + for (i =3D 0; i < grp->n_schematas; i ++) + if (grp->schematas[i]->type =3D=3D type) + if (virResctrlCopySchemata(grp->schematas[i], schemata) < 0) + goto cleanup; + + if (schemata !=3D NULL) + ret =3D 0; + + cleanup: + virResctrlFreeDomain(dom); + return ret; +} diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h new file mode 100644 index 0000000..1b040d4 --- /dev/null +++ b/src/util/virresctrl.h @@ -0,0 +1,86 @@ +/* + * virresctrl.h: header for managing resctrl control + * + * Copyright (C) 2017 Intel, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Authors: + * Eli Qiao + */ + +#ifndef __VIR_RESCTRL_H__ +# define __VIR_RESCTRL_H__ + +#include "virutil.h" + +typedef enum { + VIR_RESCTRL_TYPE_L3, + VIR_RESCTRL_TYPE_L3_CODE, + VIR_RESCTRL_TYPE_L3_DATA, + VIR_RESCTRL_TYPE_L2, + + VIR_RESCTRL_TYPE_LAST +} virResctrlType; + +VIR_ENUM_DECL(virResctrl); + +/* + * a virResctrlSchemataItem represents one of schemata object in a + * resource control group. + * eg: 0=3Df + */ +typedef struct _virResctrlSchemataItem virResctrlSchemataItem; +typedef virResctrlSchemataItem *virResctrlSchemataItemPtr; +struct _virResctrlSchemataItem { + unsigned int cache_id; /* cache resource id, eg: 0 */ + unsigned int continuous_schemata; /* schemata, should be a continuous = bits, + eg: f, this schemata can be persi= sted + to sysfs */ + unsigned int schemata; /* schemata eg: f0f, a schemata which is calcul= ated + at running time */ + unsigned long long size; /* the cache size schemata represented in B, + eg: (min * bits of continuous_schemata) */ +}; + +/* + * a virResctrlSchemata represents schemata objects of specific type of + * resource in a resource control group. + * eg: L3:0=3Df,1=3Dff + */ +typedef struct _virResctrlSchemata virResctrlSchemata; +typedef virResctrlSchemata *virResctrlSchemataPtr; +struct _virResctrlSchemata { + virResctrlType type; /* resource control type, eg: L3 */ + size_t n_schemata_items; /* number of schemata item, eg: 2 */ + virResctrlSchemataItemPtr *schemata_items; /* pointer list of schemata= item */ +}; + +/* Get free cache of the host, result saved in schemata */ +int virResctrlGetFreeCache(virResctrlType type, + virResctrlSchemataPtr *schemata); + + +/* TODO Need to first define virDomainCachetunePtr */ +/* Set cache allocation for a VM domain */ +// int virResctrlSetCacheBanks(virDomainCachetunePtr cachetune, +// unsigned char *group_name, +// size_t n_pids, +// pid_t *pids); +// +/* remove cache allocation for a VM domain */ +// int virResctrlRemoveCacheBanks(unsigned char *group_name); +void virResctrlFreeSchemata(virResctrlSchemataPtr ptr); +#endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 3cc828d..0e09e43 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -229,6 +229,7 @@ if WITH_LINUX test_programs +=3D fchosttest test_programs +=3D scsihosttest test_programs +=3D vircaps2xmltest +test_programs +=3D virresctrltest test_libraries +=3D virusbmock.la \ virnetdevbandwidthmock.la \ virnumamock.la \ @@ -1150,6 +1151,10 @@ vircaps2xmltest_SOURCES =3D \ vircaps2xmltest.c testutils.h testutils.c virfilemock.c vircaps2xmltest_LDADD =3D $(LDADDS) +virresctrltest_SOURCES =3D \ + virresctrltest.c testutils.h testutils.c virfilemock.c +virresctrltest_LDADD =3D $(LDADDS) + virnumamock_la_SOURCES =3D \ virnumamock.c virnumamock_la_CFLAGS =3D $(AM_CFLAGS) @@ -1157,7 +1162,7 @@ virnumamock_la_LDFLAGS =3D $(MOCKLIBS_LDFLAGS) virnumamock_la_LIBADD =3D $(MOCKLIBS_LIBS) else ! WITH_LINUX -EXTRA_DIST +=3D vircaps2xmltest.c virnumamock.c +EXTRA_DIST +=3D vircaps2xmltest.c virresctrltest.c virnumamock.c endif ! WITH_LINUX if WITH_NSS diff --git a/tests/virresctrldata/L3-free.schemata b/tests/virresctrldata/L= 3-free.schemata new file mode 100644 index 0000000..9b47d25 --- /dev/null +++ b/tests/virresctrldata/L3-free.schemata @@ -0,0 +1 @@ +L3:0=3D1ffff;1=3D1ffff diff --git a/tests/virresctrldata/L3CODE-free.schemata b/tests/virresctrlda= ta/L3CODE-free.schemata new file mode 100644 index 0000000..7039c45 --- /dev/null +++ b/tests/virresctrldata/L3CODE-free.schemata @@ -0,0 +1 @@ +L3CODE:0=3Dcffff;1=3Dcffff diff --git a/tests/virresctrldata/L3DATA-free.schemata b/tests/virresctrlda= ta/L3DATA-free.schemata new file mode 100644 index 0000000..30f1cbd --- /dev/null +++ b/tests/virresctrldata/L3DATA-free.schemata @@ -0,0 +1 @@ +L3DATA:0=3D3ffff;1=3D3ffff diff --git a/tests/virresctrltest.c b/tests/virresctrltest.c new file mode 100644 index 0000000..4926468 --- /dev/null +++ b/tests/virresctrltest.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) Intel, Inc. 2017 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Authors: + * Eli Qiao + */ + +#include +#include + +#include "testutils.h" +#include "virbitmap.h" +#include "virfilemock.h" +#include "virresctrl.h" + + +#define VIR_FROM_THIS VIR_FROM_NONE + +struct virResctrlData { + const char *filename; + virResctrlType type; +}; + +static void +GetSchemataStr(virResctrlSchemataPtr schemata, char **str) +{ + size_t i; + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + virBufferAsprintf(&buf, "%s:%u=3D%x", + virResctrlTypeToString(schemata->type), + schemata->schemata_items[0]->cache_id, + schemata->schemata_items[0]->schemata); + + for (i =3D 1; i < schemata->n_schemata_items; i ++) + virBufferAsprintf(&buf, ";%u=3D%x", + schemata->schemata_items[i]->cache_id, + schemata->schemata_items[i]->schemata); + + *str =3D virBufferContentAndReset(&buf); +} + +static int +test_virResctrl(const void *opaque) +{ + struct virResctrlData *data =3D (struct virResctrlData *) opaque; + char *dir =3D NULL; + char *resctrl =3D NULL; + int ret =3D -1; + virResctrlSchemataPtr schemata =3D NULL; + char *schemata_str; + char *schemata_file; + + if (virAsprintf(&resctrl, "%s/virresctrldata/linux-%s/resctrl", + abs_srcdir, data->filename) < 0) + goto cleanup; + + if (virAsprintf(&schemata_file, "%s/virresctrldata/%s-free.schemata", + abs_srcdir, virResctrlTypeToString(data->type)) < 0) + goto cleanup; + + virFileMockAddPrefix("/sys/fs/resctrl", resctrl); + + if (virResctrlGetFreeCache(data->type, &schemata) < 0) + goto cleanup; + + GetSchemataStr(schemata, &schemata_str); + + if (virTestCompareToFile(schemata_str, schemata_file) < 0) + goto cleanup; + + virFileMockClearPrefixes(); + + ret =3D 0; + + cleanup: + VIR_FREE(dir); + VIR_FREE(resctrl); + VIR_FREE(schemata_str); + virResctrlFreeSchemata(schemata); + return ret; +} + +static int +mymain(void) +{ + int ret =3D 0; + +#define DO_TEST_FULL(filename, type) \ + do { \ + struct virResctrlData data =3D {filename, \ + type}; \ + if (virTestRun(filename, test_virResctrl, &data) < 0) \ + ret =3D -1; \ + } while (0) + + DO_TEST_FULL("resctrl", VIR_RESCTRL_TYPE_L3); + DO_TEST_FULL("resctrl-cdp", VIR_RESCTRL_TYPE_L3_CODE); + DO_TEST_FULL("resctrl-cdp", VIR_RESCTRL_TYPE_L3_DATA); + + return ret; +} + +VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virnumamock.so") -- 1.9.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list