[libvirt] [PATCH 3/5] Move resctrl-related code from conf/capabilities to util/virresctrl

Martin Kletzander mkletzan at redhat.com
Thu Aug 10 13:31:47 UTC 2017


It doesn't access anything from conf/ and ti will be needed to use
from other util/ places.  This split makes the separation clearer.

Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 include/libvirt/virterror.h |   1 +
 src/Makefile.am             |   1 +
 src/conf/capabilities.c     | 138 +++++----------------------------------
 src/conf/capabilities.h     |  26 +-------
 src/libvirt_private.syms    |   7 ++
 src/util/virerror.c         |   1 +
 src/util/virresctrl.c       | 153 ++++++++++++++++++++++++++++++++++++++++++++
 src/util/virresctrl.h       |  63 ++++++++++++++++++
 8 files changed, 245 insertions(+), 145 deletions(-)
 create mode 100644 src/util/virresctrl.c
 create mode 100644 src/util/virresctrl.h

diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 2efee8f0c086..3dd2d0822d6d 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -132,6 +132,7 @@ typedef enum {
 
     VIR_FROM_PERF = 65,         /* Error from perf */
     VIR_FROM_LIBSSH = 66,       /* Error from libssh connection transport */
+    VIR_FROM_RESCTRL = 67,      /* Error from resource control */
 
 # ifdef VIR_ENUM_SENTINELS
     VIR_ERR_DOMAIN_LAST
diff --git a/src/Makefile.am b/src/Makefile.am
index b8e875482969..c3c7a8f04d36 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -167,6 +167,7 @@ UTIL_SOURCES =							\
 		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/conf/capabilities.c b/src/conf/capabilities.c
index e851539bd677..18849adfcaec 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -31,8 +31,6 @@
 #include <unistd.h>
 
 #include "capabilities.h"
-#include "c-ctype.h"
-#include "count-one-bits.h"
 #include "cpu_conf.h"
 #include "domain_conf.h"
 #include "physmem.h"
@@ -52,7 +50,6 @@
 #define VIR_FROM_THIS VIR_FROM_CAPABILITIES
 
 #define SYSFS_SYSTEM_PATH "/sys/devices/system"
-#define SYSFS_RESCTRL_PATH "/sys/fs/resctrl"
 
 VIR_LOG_INIT("conf.capabilities")
 
@@ -1539,12 +1536,6 @@ VIR_ENUM_IMPL(virCacheKernel, VIR_CACHE_TYPE_LAST,
               "Instruction",
               "Data")
 
-/* Our naming for cache types and scopes */
-VIR_ENUM_IMPL(virCache, VIR_CACHE_TYPE_LAST,
-              "both",
-              "code",
-              "data")
-
 bool
 virCapsHostCacheBankEquals(virCapsHostCacheBankPtr a,
                            virCapsHostCacheBankPtr b)
@@ -1571,111 +1562,6 @@ virCapsHostCacheBankFree(virCapsHostCacheBankPtr ptr)
     VIR_FREE(ptr);
 }
 
-/*
- * This function tests which TYPE of cache control is supported
- * Return values are:
- *  -1: not supported
- *   0: CAT
- *   1: CDP
- */
-static int
-virCapabilitiesGetCacheControlType(virCapsHostCacheBankPtr bank)
-{
-    int ret = -1;
-    char *path = NULL;
-
-    if (virAsprintf(&path,
-                    SYSFS_RESCTRL_PATH "/info/L%u",
-                    bank->level) < 0)
-        return -1;
-
-    if (virFileExists(path)) {
-        ret = 0;
-    } else {
-        VIR_FREE(path);
-        /*
-         * If CDP is enabled, there will be both CODE and DATA, but it's enough
-         * to check one of those only.
-         */
-        if (virAsprintf(&path,
-                        SYSFS_RESCTRL_PATH "/info/L%uCODE",
-                        bank->level) < 0)
-            return -1;
-        if (virFileExists(path))
-            ret = 1;
-    }
-
-    VIR_FREE(path);
-    return ret;
-}
-
-static int
-virCapabilitiesGetCacheControl(virCapsHostCacheBankPtr bank,
-                               virCacheType scope)
-{
-    int ret = -1;
-    char *tmp = NULL;
-    char *path = NULL;
-    char *cbm_mask = NULL;
-    char *type_upper = NULL;
-    unsigned int bits = 0;
-    unsigned int min_cbm_bits = 0;
-    virCapsHostCacheControlPtr control;
-
-    if (VIR_ALLOC(control) < 0)
-        goto cleanup;
-
-    if (scope != VIR_CACHE_TYPE_BOTH &&
-        virStringToUpper(&type_upper, virCacheTypeToString(scope)) < 0)
-        goto cleanup;
-
-    if (virFileReadValueUint(&control->max_allocation,
-                             SYSFS_RESCTRL_PATH "/info/L%u%s/num_closids",
-                             bank->level,
-                             type_upper ? type_upper : "") < 0)
-        goto cleanup;
-
-    if (virFileReadValueString(&cbm_mask,
-                               SYSFS_RESCTRL_PATH
-                               "/info/L%u%s/cbm_mask",
-                               bank->level,
-                               type_upper ? type_upper: "") < 0)
-        goto cleanup;
-
-    if (virFileReadValueUint(&min_cbm_bits,
-                             SYSFS_RESCTRL_PATH "/info/L%u%s/min_cbm_bits",
-                             bank->level,
-                             type_upper ? type_upper : "") < 0)
-        goto cleanup;
-
-    virStringTrimOptionalNewline(cbm_mask);
-
-    for (tmp = cbm_mask; *tmp != '\0'; tmp++) {
-        if (c_isxdigit(*tmp))
-            bits += count_one_bits(virHexToBin(*tmp));
-    }
-
-    control->granularity = bank->size / bits;
-    if (min_cbm_bits != 1)
-        control->min = min_cbm_bits * control->granularity;
-
-    control->scope = scope;
-
-    if (VIR_APPEND_ELEMENT(bank->controls,
-                           bank->ncontrols,
-                           control) < 0)
-        goto cleanup;
-
-    ret = 0;
-
- cleanup:
-    VIR_FREE(path);
-    VIR_FREE(cbm_mask);
-    VIR_FREE(type_upper);
-    VIR_FREE(control);
-    return ret;
-}
-
 int
 virCapabilitiesInitCaches(virCapsPtr caps)
 {
@@ -1760,17 +1646,27 @@ virCapabilitiesInitCaches(virCapsPtr caps)
                                        SYSFS_SYSTEM_PATH, pos, ent->d_name) < 0)
                 goto cleanup;
 
-            typeret = virCapabilitiesGetCacheControlType(bank);
+            typeret = virResctrlGetCacheControlType(bank->level);
 
             if (typeret == 0) {
-                if (virCapabilitiesGetCacheControl(bank,
-                                                   VIR_CACHE_TYPE_BOTH) < 0)
+                if (virResctrlGetCacheInfo(bank->level,
+                                           bank->size,
+                                           VIR_CACHE_TYPE_BOTH,
+                                           &bank->controls,
+                                           &bank->ncontrols) < 0)
                     goto cleanup;
             } else if (typeret == 1) {
-                if (virCapabilitiesGetCacheControl(bank,
-                                                   VIR_CACHE_TYPE_CODE) < 0 ||
-                    virCapabilitiesGetCacheControl(bank,
-                                                   VIR_CACHE_TYPE_DATA) < 0)
+                if (virResctrlGetCacheInfo(bank->level,
+                                           bank->size,
+                                           VIR_CACHE_TYPE_CODE,
+                                           &bank->controls,
+                                           &bank->ncontrols) < 0)
+                    goto cleanup;
+                if (virResctrlGetCacheInfo(bank->level,
+                                           bank->size,
+                                           VIR_CACHE_TYPE_DATA,
+                                           &bank->controls,
+                                           &bank->ncontrols) < 0)
                     goto cleanup;
             }
 
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 39a9bc689279..bd64498d1c7c 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -30,6 +30,7 @@
 # include "virarch.h"
 # include "virmacaddr.h"
 # include "virobject.h"
+# include "virresctrl.h"
 
 # include <libxml/xpath.h>
 
@@ -138,29 +139,6 @@ struct _virCapsHostSecModel {
     virCapsHostSecModelLabelPtr labels;
 };
 
-typedef enum {
-    VIR_CACHE_TYPE_BOTH,
-    VIR_CACHE_TYPE_CODE,
-    VIR_CACHE_TYPE_DATA,
-
-    VIR_CACHE_TYPE_LAST
-} virCacheType;
-
-VIR_ENUM_DECL(virCache);
-
-typedef struct _virCapsHostCacheControl virCapsHostCacheControl;
-typedef virCapsHostCacheControl *virCapsHostCacheControlPtr;
-struct _virCapsHostCacheControl {
-    /* Smallest possible increase of the allocation size in bytes */
-    unsigned long long granularity;
-    /* Minimal allocatable size in bytes (if different from granularity) */
-    unsigned long long min;
-    /* Type of the allocation */
-    virCacheType scope;
-    /* Maximum number of simultaneous allocations */
-    unsigned int max_allocation;
-};
-
 typedef struct _virCapsHostCacheBank virCapsHostCacheBank;
 typedef virCapsHostCacheBank *virCapsHostCacheBankPtr;
 struct _virCapsHostCacheBank {
@@ -170,7 +148,7 @@ struct _virCapsHostCacheBank {
     virCacheType type;  /* Data, Instruction or Unified */
     virBitmapPtr cpus;  /* All CPUs that share this bank */
     size_t ncontrols;
-    virCapsHostCacheControlPtr *controls;
+    virResctrlPtr *controls;
 };
 
 typedef struct _virCapsHost virCapsHost;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 183a9194d766..9de19628d480 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2464,6 +2464,13 @@ virRandomGenerateWWN;
 virRandomInt;
 
 
+# util/virresctrl.h
+virCacheTypeFromString;
+virCacheTypeToString;
+virResctrlGetCacheControlType;
+virResctrlGetCacheInfo;
+
+
 # util/virrotatingfile.h
 virRotatingFileReaderConsume;
 virRotatingFileReaderFree;
diff --git a/src/util/virerror.c b/src/util/virerror.c
index ef17fb5e6e74..a5a2d6ed10f3 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 000000000000..dfc062c2a0f8
--- /dev/null
+++ b/src/util/virresctrl.c
@@ -0,0 +1,153 @@
+/*
+ * virresctrl.c:
+ *
+ * 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
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "virresctrl.h"
+
+#include "c-ctype.h"
+#include "count-one-bits.h"
+#include "viralloc.h"
+#include "virfile.h"
+#include "virlog.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_RESCTRL
+
+VIR_LOG_INIT("util.virresctrl")
+
+#define SYSFS_RESCTRL_PATH "/sys/fs/resctrl"
+
+/* Resctrl is short for Resource Control.  It might be implemented for various
+ * resources, but at the time of this writing this is only supported for cache
+ * allocation technology (aka CAT).  Hence the reson for leaving 'Cache' out of
+ * all the structure and function names for now (can be added later if needed.
+ */
+
+/* Our naming for cache types and scopes */
+VIR_ENUM_IMPL(virCache, VIR_CACHE_TYPE_LAST,
+              "both",
+              "code",
+              "data")
+
+int
+virResctrlGetCacheInfo(unsigned int level,
+                       unsigned long long size,
+                       virCacheType scope,
+                       virResctrlPtr **controls,
+                       size_t *ncontrols)
+{
+    int ret = -1;
+    char *tmp = NULL;
+    char *path = NULL;
+    char *cbm_mask = NULL;
+    char *type_upper = NULL;
+    unsigned int bits = 0;
+    unsigned int min_cbm_bits = 0;
+    virResctrlPtr control;
+
+    if (VIR_ALLOC(control) < 0)
+        goto cleanup;
+
+    if (scope != VIR_CACHE_TYPE_BOTH &&
+        virStringToUpper(&type_upper, virCacheTypeToString(scope)) < 0)
+        goto cleanup;
+
+    if (virFileReadValueUint(&control->max_allocation,
+                             SYSFS_RESCTRL_PATH "/info/L%u%s/num_closids",
+                             level,
+                             type_upper ? type_upper : "") < 0)
+        goto cleanup;
+
+    if (virFileReadValueString(&cbm_mask,
+                               SYSFS_RESCTRL_PATH
+                               "/info/L%u%s/cbm_mask",
+                               level,
+                               type_upper ? type_upper: "") < 0)
+        goto cleanup;
+
+    if (virFileReadValueUint(&min_cbm_bits,
+                             SYSFS_RESCTRL_PATH "/info/L%u%s/min_cbm_bits",
+                             level,
+                             type_upper ? type_upper : "") < 0)
+        goto cleanup;
+
+    virStringTrimOptionalNewline(cbm_mask);
+
+    for (tmp = cbm_mask; *tmp != '\0'; tmp++) {
+        if (c_isxdigit(*tmp))
+            bits += count_one_bits(virHexToBin(*tmp));
+    }
+
+    control->granularity = size / bits;
+    if (min_cbm_bits != 1)
+        control->min = min_cbm_bits * control->granularity;
+
+    control->scope = scope;
+
+    if (VIR_APPEND_ELEMENT(*controls, *ncontrols, control) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(path);
+    VIR_FREE(cbm_mask);
+    VIR_FREE(type_upper);
+    VIR_FREE(control);
+    return ret;
+}
+
+
+/*
+ * This function tests which TYPE of cache control is supported
+ * Return values are:
+ *  -1: not supported
+ *   0: CAT
+ *   1: CDP
+ */
+int
+virResctrlGetCacheControlType(unsigned int level)
+{
+    int ret = -1;
+    char *path = NULL;
+
+    if (virAsprintf(&path,
+                    SYSFS_RESCTRL_PATH "/info/L%u",
+                    level) < 0)
+        return -1;
+
+    if (virFileExists(path)) {
+        ret = 0;
+    } else {
+        VIR_FREE(path);
+        /*
+         * If CDP is enabled, there will be both CODE and DATA, but it's enough
+         * to check one of those only.
+         */
+        if (virAsprintf(&path,
+                        SYSFS_RESCTRL_PATH "/info/L%uCODE",
+                        level) < 0)
+            return -1;
+        if (virFileExists(path))
+            ret = 1;
+    }
+
+    VIR_FREE(path);
+    return ret;
+}
diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h
new file mode 100644
index 000000000000..ee219cbb9261
--- /dev/null
+++ b/src/util/virresctrl.h
@@ -0,0 +1,63 @@
+/*
+ * virresctrl.h:
+ *
+ * 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
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VIR_RESCTRL_H__
+# define __VIR_RESCTRL_H__
+
+# include "internal.h"
+
+# include "virbitmap.h"
+# include "virutil.h"
+
+
+typedef enum {
+    VIR_CACHE_TYPE_BOTH,
+    VIR_CACHE_TYPE_CODE,
+    VIR_CACHE_TYPE_DATA,
+
+    VIR_CACHE_TYPE_LAST
+} virCacheType;
+
+VIR_ENUM_DECL(virCache);
+
+
+typedef struct _virResctrl virResctrl;
+typedef virResctrl *virResctrlPtr;
+struct _virResctrl {
+    /* Smallest possible increase of the allocation size in bytes */
+    unsigned long long granularity;
+    /* Minimal allocatable size in bytes (if different from granularity) */
+    unsigned long long min;
+    /* Type of the allocation */
+    virCacheType scope;
+    /* Maximum number of simultaneous allocations */
+    unsigned int max_allocation;
+};
+
+
+int
+virResctrlGetCacheInfo(unsigned int level,
+                       unsigned long long size,
+                       virCacheType scope,
+                       virResctrlPtr **controls,
+                       size_t *ncontrols);
+
+int
+virResctrlGetCacheControlType(unsigned int level);
+
+#endif /*  __VIR_RESCTRL_H__ */
-- 
2.14.0




More information about the libvir-list mailing list