diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 0b8d3d80f17396906a8abad708b005c1fcfb1ed0..244dd5e605e65b3813e4eea2aee01f06552acb5c 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 e75a1c9705053b8931a51bff05a3b485a160b92f..90b7bee34ae707d81b0e975bb3510b878128f8fb 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 c7494cd608f374b695f49f91a3d30db35ec8e39d..51fcae544e89421fffccc1e34dd745698f247be0 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 c8dacfe27b94cdf1bbf96c26b2d3cfe21b0f645f..175dc2bfaae389258275808847c91b527a42857e 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;