]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util, resctrl: using 64bit interface instead of 32bit for counters
authorWang Huaqiang <huaqiang.wang@intel.com>
Thu, 2 Jan 2020 10:45:04 +0000 (18:45 +0800)
committerDaniel P. Berrangé <berrange@redhat.com>
Mon, 6 Jan 2020 13:30:03 +0000 (13:30 +0000)
The underlying resctrl monitoring is actually using 64 bit counters,
not the 32bit one. Correct this by using 64bit data type for reading
hardware value.

To keep the interface consistent, the result of CPU last level cache
that occupied by vcpu processors of specific restrl monitor group is
still reported with a truncated 32bit data type. because, in silicon
world, CPU cache size will never exceed 4GB.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Wang Huaqiang <huaqiang.wang@intel.com>
src/libvirt_private.syms
src/qemu/qemu_driver.c
src/util/virfile.c
src/util/virfile.h
src/util/virresctrl.c
src/util/virresctrl.h

index 951ba7f0cae3eb17a5661d8b76be785c33748428..74e3479842be7318a55e6fe08239ad0950aa37ca 100644 (file)
@@ -2027,6 +2027,7 @@ virFileReadValueInt;
 virFileReadValueScaledInt;
 virFileReadValueString;
 virFileReadValueUint;
+virFileReadValueUllong;
 virFileRelLinkPointsTo;
 virFileRemove;
 virFileRemoveLastComponent;
index 540131eb41b9506d254b50fc1df090dc9eb5e982..e92e8b5318708311c17a22eb8e8c7cdfae08ff89 100644 (file)
@@ -20767,8 +20767,19 @@ qemuDomainGetStatsCpuCache(virQEMUDriverPtr driver,
                                          "cpu.cache.monitor.%zu.bank.%zu.id", i, j) < 0)
                 goto cleanup;
 
-            if (virTypedParamListAddUInt(params, resdata[i]->stats[j]->vals[0],
-                                         "cpu.cache.monitor.%zu.bank.%zu.bytes", i, j) < 0)
+            /* 'resdata[i]->stats[j]->vals[0]' keeps the value of how many last
+             * level cache in bank j currently occupied by the vcpus listed in
+             * resource monitor i, in bytes. This value is reported through a
+             * 64 bit hardware counter, so it is better to be arranged with
+             * data type in 64 bit width, but considering the fact that
+             * physical cache on a CPU could never be designed to be bigger
+             * than 4G bytes in size, to keep the 'domstats' interface
+             * historically consistent, it is safe to report the value with a
+             * truncated 'UInt' data type here. */
+            if (virTypedParamListAddUInt(params,
+                                         (unsigned int)resdata[i]->stats[j]->vals[0],
+                                         "cpu.cache.monitor.%zu.bank.%zu.bytes",
+                                         i, j) < 0)
                 goto cleanup;
         }
     }
index 4fc872ef1de4424e79f4af16fda2f5acca80864d..5acac85bb9ecb903e9cffe6cbaee5d8c0fe02af8 100644 (file)
@@ -4123,6 +4123,46 @@ virFileReadValueUint(unsigned int *value, const char *format, ...)
 }
 
 
+/**
+ * virFileReadValueUllong:
+ * @value: pointer to unsigned long long to be filled in with the value
+ * @format, ...: file to read from
+ *
+ * Read unsigned int from @format and put it into @value.
+ *
+ * Return -2 for non-existing file, -1 on other errors and 0 if everything went
+ * fine.
+ */
+int
+virFileReadValueUllong(unsigned long long *value, const char *format, ...)
+{
+    g_autofree char *str = NULL;
+    g_autofree char *path = NULL;
+    va_list ap;
+
+    va_start(ap, format);
+    path = g_strdup_vprintf(format, ap);
+    va_end(ap);
+
+    if (!virFileExists(path))
+        return -2;
+
+    if (virFileReadAll(path, INT_BUFSIZE_BOUND(*value), &str) < 0)
+        return -1;
+
+    virStringTrimOptionalNewline(str);
+
+    if (virStrToLong_ullp(str, NULL, 10, value) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Invalid unsigned long long value '%s' in file '%s'"),
+                       str, path);
+        return -1;
+    }
+
+    return 0;
+}
+
+
 /**
  * virFileReadValueScaledInt:
  * @value: pointer to unsigned long long int to be filled in with the value
index c73f5252e4961d09f55cfe71ffcb6a41afcb7e83..c805d87b3fb8f5eff583fc41875e0415324bc8d3 100644 (file)
@@ -338,6 +338,8 @@ int virFileReadValueInt(int *value, const char *format, ...)
  G_GNUC_PRINTF(2, 3);
 int virFileReadValueUint(unsigned int *value, const char *format, ...)
  G_GNUC_PRINTF(2, 3);
+int virFileReadValueUllong(unsigned long long *value, const char *format, ...)
+ G_GNUC_PRINTF(2, 3);
 int virFileReadValueBitmap(virBitmapPtr *value, const char *format, ...)
  G_GNUC_PRINTF(2, 3);
 int virFileReadValueScaledInt(unsigned long long *value, const char *format, ...)
index b78fded026d1cdc697bfd2cff2d434b208e1a3fa..684d2ce398191c3abbd35fdb572915b6944bac48 100644 (file)
@@ -2678,7 +2678,7 @@ virResctrlMonitorGetStats(virResctrlMonitorPtr monitor,
     int rv = -1;
     int ret = -1;
     size_t i = 0;
-    unsigned int val = 0;
+    unsigned long long val = 0;
     DIR *dirp = NULL;
     char *datapath = NULL;
     char *filepath = NULL;
@@ -2734,8 +2734,8 @@ virResctrlMonitorGetStats(virResctrlMonitorPtr monitor,
             goto cleanup;
 
         for (i = 0; resources[i]; i++) {
-            rv = virFileReadValueUint(&val, "%s/%s/%s", datapath,
-                                      ent->d_name, resources[i]);
+            rv = virFileReadValueUllong(&val, "%s/%s/%s", datapath,
+                                        ent->d_name, resources[i]);
             if (rv == -2) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("File '%s/%s/%s' does not exist."),
index 3dd7c9634825bf314960fc93c187b4b35614464b..11f275acf4edbd9fd10c1dfe5eca6d59d0a527e7 100644 (file)
@@ -204,7 +204,7 @@ struct _virResctrlMonitorStats {
     char **features;
     /* @vals store the statistical record values and @val[0] is the value for
      * @features[0], @val[1] for@features[1] ... respectively */
-    unsigned int *vals;
+    unsigned long long *vals;
     /* The length of @vals array */
     size_t nvals;
 };