[RFC PATCH 10/16] Expose qemu storage request limits via bulk stats API

Peter Krempa via Devel posted 16 patches 2 weeks, 4 days ago
[RFC PATCH 10/16] Expose qemu storage request limits via bulk stats API
Posted by Peter Krempa via Devel 2 weeks, 4 days ago
From: Peter Krempa <pkrempa@redhat.com>

Management applications can use the detected limits to cross reference
with configuration within the VM to ensure optimal performance.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
 docs/manpages/virsh.rst          |  21 +++++
 include/libvirt/libvirt-domain.h | 148 +++++++++++++++++++++++++++++++
 src/qemu/qemu_driver.c           |  61 +++++++++++++
 3 files changed, 230 insertions(+)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index bcb5495ed9..5b4eb236a4 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2751,6 +2751,27 @@ Information listed includes:
 * ``block.<num>.physical`` - physical size of source file in bytes
 * ``block.<num>.threshold`` - threshold (in bytes) for delivering the
   VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD event. See domblkthreshold.
+* ``block.<num>.limits.request_alignment`` - Alignment requirement for requests
+  in bytes
+* ``block.<num>.limits.discard_max`` - Maximum number of bytes that can be
+  discarded at once
+* ``block.<num>.limits.discard_alignment`` - Optimal alignment for discard
+  requests in bytes
+* ``block.<num>.limits.write_zeroes_max`` - Maximum number of bytes that can be
+  zeroed out at once
+* ``block.<num>.limits.write_zeroes_alignment`` - Optimal alignment for
+  write_zeroes requests in bytes
+* ``block.<num>.limits.transfer_optimal`` - Optimal transfer length in bytes
+* ``block.<num>.limits.transfer_max`` - Maximal transfer length in bytes
+* ``block.<num>.limits.transfer_hw_max`` - Maximal hardware transfer length of
+  requests bypassing kernel IO scheduler in bytes
+* ``block.<num>.limits.iov_max`` - Maximum number of scatter/gather elements
+* ``block.<num>.limits.iov_hw_max`` - Maximal number of scatter/gather elements
+  of requests bypassing kernel IO scheduler
+* ``block.<num>.limits.memory_alignment_minimal`` - memory alignment in bytes so
+  that no bounce buffer is needed
+* ``block.<num>.limits.memory_alignment_optimal`` - memory alignment in bytes
+  that is used for bounce buffers


 *--iothread* returns information about IOThreads on the running guest
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 71bb49fe6c..90c37a575c 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -3488,6 +3488,154 @@ struct _virDomainStatsRecord {
  */
 # define VIR_DOMAIN_STATS_BLOCK_SUFFIX_THRESHOLD ".threshold"

+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_REQUEST_ALIGNMENT:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Alignment requirement, in bytes, for offset/length of I/O requests, as
+ * unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_REQUEST_ALIGNMENT ".limits.request_alignment"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_MAX:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Maximum number of bytes that can be discarded at once, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_MAX ".limits.discard_max"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_ALIGNMENT:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Optimal alignment for discard requests in bytes, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_ALIGNMENT ".limits.discard_alignment"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_MAX:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Maximum number of bytes that can be zeroed out at once, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_MAX ".limits.write_zeroes_max"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_ALIGNMENT:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Optimal alignment for write_zeroes requests in bytes, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_ALIGNMENT ".limits.write_zeroes_alignment"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_OPTIMAL:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Optimal transfer length in bytes, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_OPTIMAL ".limits.transfer_optimal"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_MAX:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Maximal transfer length in bytes, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_MAX ".limits.transfer_max"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_HW_MAX:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Maximal hardware transfer length of requests bypassing kernel IO scheduler
+ * in bytes, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_HW_MAX ".limits.transfer_hw_max"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_MAX:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Maximum number of scatter/gather elements, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_MAX ".limits.iov_max"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_HW_MAX:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * Maximal number of scatter/gather elements of requests bypassing kernel IO
+ * scheduler, as unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_HW_MAX ".limits.iov_hw_max"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_MINIMAL:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * memory alignment in bytes so that no bounce buffer is needed, as
+ * unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_MINIMAL ".limits.memory_alignment_minimal"
+
+/**
+ * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_OPTIMAL:
+ *
+ * limits represent constraints on individual operations as imposed by the
+ * backing file storage technology.
+ *
+ * memory alignment in bytes that is used for bounce buffers, as
+ * unsigned long long.
+ *
+ * Since: 11.9.0
+ */
+# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_OPTIMAL ".limits.memory_alignment_optimal"

 /**
  * VIR_DOMAIN_STATS_PERF_CMT:
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 806408115f..4e5e2fed0f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17510,6 +17510,67 @@ qemuDomainGetStatsBlockExportBackendStorage(const char *entryname,
     if (entry->write_threshold)
         virTypedParamListAddULLong(params, entry->write_threshold,
                                    VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_THRESHOLD, recordnr);
+
+    if (entry->limits) {
+        if (entry->limits->request_alignment > 0)
+            virTypedParamListAddULLong(params, entry->limits->request_alignment,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_REQUEST_ALIGNMENT,
+                                       recordnr);
+
+        if (entry->limits->discard_max > 0)
+            virTypedParamListAddULLong(params, entry->limits->discard_max,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_MAX,
+                                       recordnr);
+
+        if (entry->limits->discard_alignment > 0)
+            virTypedParamListAddULLong(params, entry->limits->discard_alignment,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_ALIGNMENT,
+                                       recordnr);
+
+        if (entry->limits->write_zeroes_max > 0)
+            virTypedParamListAddULLong(params, entry->limits->write_zeroes_max,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_MAX,
+                                       recordnr);
+        if (entry->limits->write_zeroes_alignment > 0)
+            virTypedParamListAddULLong(params, entry->limits->write_zeroes_alignment,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_ALIGNMENT,
+                                       recordnr);
+
+        if (entry->limits->transfer_optimal > 0)
+            virTypedParamListAddULLong(params, entry->limits->transfer_optimal,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_OPTIMAL,
+                                       recordnr);
+
+        if (entry->limits->transfer_max > 0)
+            virTypedParamListAddULLong(params, entry->limits->transfer_max,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_MAX,
+                                       recordnr);
+
+        if (entry->limits->transfer_hw_max > 0)
+            virTypedParamListAddULLong(params, entry->limits->transfer_hw_max,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_HW_MAX,
+                                       recordnr);
+
+        if (entry->limits->iov_max > 0)
+            virTypedParamListAddULLong(params, entry->limits->iov_max,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_MAX,
+                                       recordnr);
+
+        if (entry->limits->iov_hw_max > 0)
+            virTypedParamListAddULLong(params, entry->limits->iov_hw_max,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_HW_MAX,
+                                       recordnr);
+
+        if (entry->limits->memory_alignment_minimal > 0)
+            virTypedParamListAddULLong(params, entry->limits->memory_alignment_minimal,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_MINIMAL,
+                                       recordnr);
+
+        if (entry->limits->memory_alignment_optimal > 0)
+            virTypedParamListAddULLong(params, entry->limits->memory_alignment_optimal,
+                                       VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_OPTIMAL,
+                                       recordnr);
+    }
 }


-- 
2.51.0