[libvirt] [PATCH] qemu: Allow live-updates of coalesce settings

Martin Kletzander posted 1 patch 6 years, 9 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/0e1844b2881ea59f27b2a284f9d7653ea34c38c4.1497530642.git.mkletzan@redhat.com
src/qemu/qemu_hotplug.c |  13 ++++++
src/util/virnetdev.c    | 103 +++++++++++++++++++++++++++++++-----------------
src/util/virnetdev.h    |   3 +-
src/util/virnetdevtap.c |   2 +-
4 files changed, 83 insertions(+), 38 deletions(-)
[libvirt] [PATCH] qemu: Allow live-updates of coalesce settings
Posted by Martin Kletzander 6 years, 9 months ago
Change the settings from qemuDomainUpdateDeviceLive() as otherwise the
call would succeed even though nothing has changed.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1460862

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
---
 src/qemu/qemu_hotplug.c |  13 ++++++
 src/util/virnetdev.c    | 103 +++++++++++++++++++++++++++++++-----------------
 src/util/virnetdev.h    |   3 +-
 src/util/virnetdevtap.c |   2 +-
 4 files changed, 83 insertions(+), 38 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 0b8d3d80f173..244dd5e605e6 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2986,6 +2986,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
     bool needLinkStateChange = false;
     bool needReplaceDevDef = false;
     bool needBandwidthSet = false;
+    bool needCoalesceChange = false;
     int ret = -1;
     int changeidx = -1;

@@ -3280,6 +3281,12 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
                                  virDomainNetGetActualBandwidth(newdev)))
         needBandwidthSet = true;

+    if (!!olddev->coalesce != !!newdev->coalesce ||
+        (olddev->coalesce && newdev->coalesce &&
+         !memcmp(olddev->coalesce, newdev->coalesce,
+                 sizeof(*olddev->coalesce))))
+        needCoalesceChange = true;
+
     /* FINALLY - actually perform the required actions */

     if (needReconnect) {
@@ -3315,6 +3322,12 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
         needReplaceDevDef = true;
     }

+    if (needCoalesceChange) {
+        if (virNetDevSetCoalesce(newdev->ifname, newdev->coalesce, true) < 0)
+            goto cleanup;
+        needReplaceDevDef = true;
+    }
+
     if (needLinkStateChange &&
         qemuDomainChangeNetLinkState(driver, vm, olddev, newdev->linkstate) < 0) {
         goto cleanup;
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index e75a1c970505..90b7bee34ae7 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -3086,7 +3086,8 @@ virNetDevGetEthtoolGFeatures(virBitmapPtr bitmap ATTRIBUTE_UNUSED,
 /**
  * virNetDevSetCoalesce:
  * @ifname: interface name to modify
- * @coalesce: Coalesce settings to set and update
+ * @coalesce: Coalesce settings to set or update
+ * @update: Whether this is an update for existing settings or not
  *
  * This function sets the various coalesce settings for a given interface
  * @ifname and updates them back into @coalesce.
@@ -3094,40 +3095,44 @@ virNetDevGetEthtoolGFeatures(virBitmapPtr bitmap ATTRIBUTE_UNUSED,
  * Returns 0 in case of success or -1 on failure
  */
 int virNetDevSetCoalesce(const char *ifname,
-                         virNetDevCoalescePtr coalesce)
+                         virNetDevCoalescePtr coalesce,
+                         bool update)
 {
     int fd = -1;
     int ret = -1;
     struct ifreq ifr;
     struct ethtool_coalesce coal = {0};

-    if (!coalesce)
+    if (!coalesce && !update)
         return 0;

-    coal = (struct ethtool_coalesce) {
-        .cmd = ETHTOOL_SCOALESCE,
-        .rx_max_coalesced_frames = coalesce->rx_max_coalesced_frames,
-        .rx_coalesce_usecs_irq = coalesce->rx_coalesce_usecs_irq,
-        .rx_max_coalesced_frames_irq = coalesce->rx_max_coalesced_frames_irq,
-        .tx_coalesce_usecs = coalesce->tx_coalesce_usecs,
-        .tx_max_coalesced_frames = coalesce->tx_max_coalesced_frames,
-        .tx_coalesce_usecs_irq = coalesce->tx_coalesce_usecs_irq,
-        .tx_max_coalesced_frames_irq = coalesce->tx_max_coalesced_frames_irq,
-        .stats_block_coalesce_usecs = coalesce->stats_block_coalesce_usecs,
-        .use_adaptive_rx_coalesce = coalesce->use_adaptive_rx_coalesce,
-        .use_adaptive_tx_coalesce = coalesce->use_adaptive_tx_coalesce,
-        .pkt_rate_low = coalesce->pkt_rate_low,
-        .rx_coalesce_usecs_low = coalesce->rx_coalesce_usecs_low,
-        .rx_max_coalesced_frames_low = coalesce->rx_max_coalesced_frames_low,
-        .tx_coalesce_usecs_low = coalesce->tx_coalesce_usecs_low,
-        .tx_max_coalesced_frames_low = coalesce->tx_max_coalesced_frames_low,
-        .pkt_rate_high = coalesce->pkt_rate_high,
-        .rx_coalesce_usecs_high = coalesce->rx_coalesce_usecs_high,
-        .rx_max_coalesced_frames_high = coalesce->rx_max_coalesced_frames_high,
-        .tx_coalesce_usecs_high = coalesce->tx_coalesce_usecs_high,
-        .tx_max_coalesced_frames_high = coalesce->tx_max_coalesced_frames_high,
-        .rate_sample_interval = coalesce->rate_sample_interval,
-    };
+    if (coalesce) {
+        coal = (struct ethtool_coalesce) {
+            .rx_max_coalesced_frames = coalesce->rx_max_coalesced_frames,
+            .rx_coalesce_usecs_irq = coalesce->rx_coalesce_usecs_irq,
+            .rx_max_coalesced_frames_irq = coalesce->rx_max_coalesced_frames_irq,
+            .tx_coalesce_usecs = coalesce->tx_coalesce_usecs,
+            .tx_max_coalesced_frames = coalesce->tx_max_coalesced_frames,
+            .tx_coalesce_usecs_irq = coalesce->tx_coalesce_usecs_irq,
+            .tx_max_coalesced_frames_irq = coalesce->tx_max_coalesced_frames_irq,
+            .stats_block_coalesce_usecs = coalesce->stats_block_coalesce_usecs,
+            .use_adaptive_rx_coalesce = coalesce->use_adaptive_rx_coalesce,
+            .use_adaptive_tx_coalesce = coalesce->use_adaptive_tx_coalesce,
+            .pkt_rate_low = coalesce->pkt_rate_low,
+            .rx_coalesce_usecs_low = coalesce->rx_coalesce_usecs_low,
+            .rx_max_coalesced_frames_low = coalesce->rx_max_coalesced_frames_low,
+            .tx_coalesce_usecs_low = coalesce->tx_coalesce_usecs_low,
+            .tx_max_coalesced_frames_low = coalesce->tx_max_coalesced_frames_low,
+            .pkt_rate_high = coalesce->pkt_rate_high,
+            .rx_coalesce_usecs_high = coalesce->rx_coalesce_usecs_high,
+            .rx_max_coalesced_frames_high = coalesce->rx_max_coalesced_frames_high,
+            .tx_coalesce_usecs_high = coalesce->tx_coalesce_usecs_high,
+            .tx_max_coalesced_frames_high = coalesce->tx_max_coalesced_frames_high,
+            .rate_sample_interval = coalesce->rate_sample_interval,
+        };
+    }
+
+    coal.cmd = ETHTOOL_SCOALESCE;

     if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0)
         return -1;
@@ -3141,12 +3146,36 @@ int virNetDevSetCoalesce(const char *ifname,
         goto cleanup;
     }

-    coal = (struct ethtool_coalesce) {
-        .cmd = ETHTOOL_GCOALESCE,
-    };
+    if (coalesce) {
+        coal = (struct ethtool_coalesce) {
+            .cmd = ETHTOOL_GCOALESCE,
+        };

-    /* Don't fail if the update itself fails */
-    virNetDevSendEthtoolIoctl(fd, &ifr);
+        /* Don't fail if the update itself fails */
+        if (virNetDevSendEthtoolIoctl(fd, &ifr) == 0) {
+            coalesce->rx_max_coalesced_frames = coal.rx_max_coalesced_frames;
+            coalesce->rx_coalesce_usecs_irq = coal.rx_coalesce_usecs_irq;
+            coalesce->rx_max_coalesced_frames_irq = coal.rx_max_coalesced_frames_irq;
+            coalesce->tx_coalesce_usecs = coal.tx_coalesce_usecs;
+            coalesce->tx_max_coalesced_frames = coal.tx_max_coalesced_frames;
+            coalesce->tx_coalesce_usecs_irq = coal.tx_coalesce_usecs_irq;
+            coalesce->tx_max_coalesced_frames_irq = coal.tx_max_coalesced_frames_irq;
+            coalesce->stats_block_coalesce_usecs = coal.stats_block_coalesce_usecs;
+            coalesce->use_adaptive_rx_coalesce = coal.use_adaptive_rx_coalesce;
+            coalesce->use_adaptive_tx_coalesce = coal.use_adaptive_tx_coalesce;
+            coalesce->pkt_rate_low = coal.pkt_rate_low;
+            coalesce->rx_coalesce_usecs_low = coal.rx_coalesce_usecs_low;
+            coalesce->rx_max_coalesced_frames_low = coal.rx_max_coalesced_frames_low;
+            coalesce->tx_coalesce_usecs_low = coal.tx_coalesce_usecs_low;
+            coalesce->tx_max_coalesced_frames_low = coal.tx_max_coalesced_frames_low;
+            coalesce->pkt_rate_high = coal.pkt_rate_high;
+            coalesce->rx_coalesce_usecs_high = coal.rx_coalesce_usecs_high;
+            coalesce->rx_max_coalesced_frames_high = coal.rx_max_coalesced_frames_high;
+            coalesce->tx_coalesce_usecs_high = coal.tx_coalesce_usecs_high;
+            coalesce->tx_max_coalesced_frames_high = coal.tx_max_coalesced_frames_high;
+            coalesce->rate_sample_interval = coal.rate_sample_interval;
+        }
+    }

     ret = 0;
  cleanup:
@@ -3155,9 +3184,10 @@ int virNetDevSetCoalesce(const char *ifname,
 }
 # else
 int virNetDevSetCoalesce(const char *ifname,
-                         virNetDevCoalescePtr coalesce)
+                         virNetDevCoalescePtr coalesce,
+                         bool update)
 {
-    if (!coalesce)
+    if (!coalesce && !update)
         return 0;

     virReportSystemError(ENOSYS,
@@ -3216,9 +3246,10 @@ virNetDevGetFeatures(const char *ifname ATTRIBUTE_UNUSED,
 }

 int virNetDevSetCoalesce(const char *ifname,
-                         virNetDevCoalescePtr coalesce)
+                         virNetDevCoalescePtr coalesce,
+                         bool update)
 {
-    if (!coalesce)
+    if (!coalesce && !update)
         return 0;

     virReportSystemError(ENOSYS,
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index c7494cd608f3..51fcae544e89 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -180,7 +180,8 @@ int virNetDevRestoreMacAddress(const char *linkdev,
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;

 int virNetDevSetCoalesce(const char *ifname,
-                         virNetDevCoalescePtr coalesce)
+                         virNetDevCoalescePtr coalesce,
+                         bool update)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;

 int virNetDevSetMTU(const char *ifname,
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
index c8dacfe27b94..175dc2bfaae3 100644
--- a/src/util/virnetdevtap.c
+++ b/src/util/virnetdevtap.c
@@ -663,7 +663,7 @@ int virNetDevTapCreateInBridgePort(const char *brname,
     if (virNetDevSetOnline(*ifname, !!(flags & VIR_NETDEV_TAP_CREATE_IFUP)) < 0)
         goto error;

-    if (virNetDevSetCoalesce(*ifname, coalesce) < 0)
+    if (virNetDevSetCoalesce(*ifname, coalesce, false) < 0)
         goto error;

     return 0;
-- 
2.13.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Allow live-updates of coalesce settings
Posted by Martin Kletzander 6 years, 9 months ago
On Thu, Jun 15, 2017 at 02:44:02PM +0200, Martin Kletzander wrote:
>Change the settings from qemuDomainUpdateDeviceLive() as otherwise the
>call would succeed even though nothing has changed.
>
>Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1460862
>

Dang, this should be https://bugzilla.redhat.com/show_bug.cgi?id=1414627
and it's now fixed in my local branch.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list