You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by nv...@apache.org on 2022/04/01 15:13:20 UTC
[cloudstack] branch main updated: KVM: Enhance CPU speed detection on hosts (#6175)
This is an automated email from the ASF dual-hosted git repository.
nvazquez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new 2f2d6cb KVM: Enhance CPU speed detection on hosts (#6175)
2f2d6cb is described below
commit 2f2d6cbe38975edce02fe04ee4eb4d25b45aeb16
Author: Nicolas Vazquez <ni...@gmail.com>
AuthorDate: Fri Apr 1 12:12:34 2022 -0300
KVM: Enhance CPU speed detection on hosts (#6175)
* KVM: Enhance CPU speed detection on hosts
* Update agent/conf/agent.properties
Co-authored-by: dahn <da...@gmail.com>
Co-authored-by: dahn <da...@gmail.com>
---
agent/conf/agent.properties | 3 +++
.../kvm/resource/LibvirtComputingResource.java | 6 ++++-
.../apache/cloudstack/utils/linux/KVMHostInfo.java | 23 +++++++++++-------
.../cloudstack/utils/linux/KVMHostInfoTest.java | 28 ++++++++++++++++++++++
4 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties
index 5859a98..ce9c9c1 100644
--- a/agent/conf/agent.properties
+++ b/agent/conf/agent.properties
@@ -285,3 +285,6 @@ iscsi.session.cleanup.enabled=false
# Enable manually setting CPU's topology on KVM's VM.
# enable.manually.setting.cpu.topology.on.kvm.vm=true
+
+# Manually set the host CPU MHz, in cases where CPU scaling support detected value is wrong
+# host.cpu.manual.speed.mhz=0
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 4d5d560..b7f8c33 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -371,6 +371,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected String _rngPath = "/dev/random";
protected int _rngRatePeriod = 1000;
protected int _rngRateBytes = 2048;
+ protected int _manualCpuSpeed = 0;
protected String _agentHooksBasedir = "/etc/cloudstack/agent/hooks";
protected String _agentHooksLibvirtXmlScript = "libvirt-vm-xml-transformer.groovy";
@@ -1034,6 +1035,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
_noMemBalloon = true;
}
+ value = (String)params.get("host.cpu.manual.speed.mhz");
+ _manualCpuSpeed = NumbersUtil.parseInt(value, 0);
+
_videoHw = (String) params.get("vm.video.hardware");
value = (String) params.get("vm.video.ram");
_videoRam = NumbersUtil.parseInt(value, 0);
@@ -3294,7 +3298,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
@Override
public StartupCommand[] initialize() {
- final KVMHostInfo info = new KVMHostInfo(_dom0MinMem, _dom0OvercommitMem);
+ final KVMHostInfo info = new KVMHostInfo(_dom0MinMem, _dom0OvercommitMem, _manualCpuSpeed);
String capabilities = String.join(",", info.getCapabilities());
if (dpdkSupport) {
diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
index 8f21cce..e34f39f 100644
--- a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
+++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java
@@ -44,9 +44,10 @@ public class KVMHostInfo {
private long overCommitMemory;
private List<String> capabilities = new ArrayList<>();
- private static String cpuInfoMaxFreqFileName = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";
+ private static String cpuInfoFreqFileName = "/sys/devices/system/cpu/cpu0/cpufreq/base_frequency";
- public KVMHostInfo(long reservedMemory, long overCommitMemory) {
+ public KVMHostInfo(long reservedMemory, long overCommitMemory, long manualSpeed) {
+ this.cpuSpeed = manualSpeed;
this.reservedMemory = reservedMemory;
this.overCommitMemory = overCommitMemory;
this.getHostInfoFromLibvirt();
@@ -113,13 +114,13 @@ public class KVMHostInfo {
}
private static long getCpuSpeedFromFile() {
- LOGGER.info(String.format("Fetching CPU speed from file [%s].", cpuInfoMaxFreqFileName));
- try (Reader reader = new FileReader(cpuInfoMaxFreqFileName)) {
- Long cpuInfoMaxFreq = Long.parseLong(IOUtils.toString(reader).trim());
- LOGGER.info(String.format("Retrieved value [%s] from file [%s]. This corresponds to a CPU speed of [%s] MHz.", cpuInfoMaxFreq, cpuInfoMaxFreqFileName, cpuInfoMaxFreq / 1000));
- return cpuInfoMaxFreq / 1000;
+ LOGGER.info(String.format("Fetching CPU speed from file [%s].", cpuInfoFreqFileName));
+ try (Reader reader = new FileReader(cpuInfoFreqFileName)) {
+ Long cpuInfoFreq = Long.parseLong(IOUtils.toString(reader).trim());
+ LOGGER.info(String.format("Retrieved value [%s] from file [%s]. This corresponds to a CPU speed of [%s] MHz.", cpuInfoFreq, cpuInfoFreqFileName, cpuInfoFreq / 1000));
+ return cpuInfoFreq / 1000;
} catch (IOException | NumberFormatException e) {
- LOGGER.error(String.format("Unable to retrieve the CPU speed from file [%s]", cpuInfoMaxFreqFileName), e);
+ LOGGER.error(String.format("Unable to retrieve the CPU speed from file [%s]", cpuInfoFreqFileName), e);
return 0L;
}
}
@@ -128,7 +129,11 @@ public class KVMHostInfo {
try {
final Connect conn = LibvirtConnection.getConnection();
final NodeInfo hosts = conn.nodeInfo();
- this.cpuSpeed = getCpuSpeed(hosts);
+ if (this.cpuSpeed == 0) {
+ this.cpuSpeed = getCpuSpeed(hosts);
+ } else {
+ LOGGER.debug(String.format("Using existing configured CPU frequency %s", this.cpuSpeed));
+ }
/*
* Some CPUs report a single socket and multiple NUMA cells.
diff --git a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java
index bc6b01c..34e1546 100644
--- a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java
+++ b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java
@@ -16,16 +16,26 @@
// under the License.
package org.apache.cloudstack.utils.linux;
+import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
import org.apache.commons.lang.SystemUtils;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.Assume;
import org.junit.Assert;
+import org.junit.runner.RunWith;
+import org.libvirt.Connect;
import org.mockito.Mockito;
import org.libvirt.NodeInfo;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(value = {LibvirtConnection.class})
+@PowerMockIgnore({"javax.xml.*", "org.w3c.dom.*", "org.apache.xerces.*", "org.xml.*"})
public class KVMHostInfoTest {
@Test
public void getCpuSpeed() {
@@ -34,4 +44,22 @@ public class KVMHostInfoTest {
nodeInfo.mhz = 1000;
Assert.assertThat(KVMHostInfo.getCpuSpeed(nodeInfo), Matchers.greaterThan(0l));
}
+
+ @Test
+ public void manualCpuSpeedTest() throws Exception {
+ PowerMockito.mockStatic(LibvirtConnection.class);
+ Connect conn = Mockito.mock(Connect.class);
+ NodeInfo nodeInfo = Mockito.mock(NodeInfo.class);
+ nodeInfo.mhz = 1000;
+ String capabilitiesXml = "<capabilities></capabilities>";
+
+ PowerMockito.doReturn(conn).when(LibvirtConnection.class, "getConnection");
+ PowerMockito.when(conn.nodeInfo()).thenReturn(nodeInfo);
+ PowerMockito.when(conn.getCapabilities()).thenReturn(capabilitiesXml);
+ PowerMockito.when(conn.close()).thenReturn(0);
+ int manualSpeed = 500;
+
+ KVMHostInfo kvmHostInfo = new KVMHostInfo(10, 10, manualSpeed);
+ Assert.assertEquals(kvmHostInfo.getCpuSpeed(), manualSpeed);
+ }
}
\ No newline at end of file