From ec733f7eb1f88d9d030952c764c1ee635ab9060b Mon Sep 17 00:00:00 2001 Message-Id: From: Martin Kletzander Date: Fri, 16 Jun 2017 13:45:30 +0200 Subject: [PATCH] qemu: Allow live-updates of coalesce settings 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=1414627 Signed-off-by: Martin Kletzander (cherry picked from commit 307a205e25ad7db7c895c42ab2e8f59f3839c058) Signed-off-by: Martin Kletzander Conflicts: src/util/virnetdev.c - non-Linux stubs Signed-off-by: Jiri Denemark --- src/qemu/qemu_hotplug.c | 13 +++++++ src/util/virnetdev.c | 93 ++++++++++++++++++++++++++++++++----------------- src/util/virnetdev.h | 3 +- src/util/virnetdevtap.c | 2 +- 4 files changed, 77 insertions(+), 34 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index ab23a575d8..fbc9177669 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -3005,6 +3005,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, bool needLinkStateChange = false; bool needReplaceDevDef = false; bool needBandwidthSet = false; + bool needCoalesceChange = false; int ret = -1; int changeidx = -1; @@ -3293,6 +3294,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) { @@ -3328,6 +3335,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 eb97b705e2..2beb39bb60 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -3093,7 +3093,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. @@ -3101,40 +3102,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; @@ -3148,12 +3153,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: diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 97236c170d..c2c09af636 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 c8dacfe27b..175dc2bfaa 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