mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
Use base clock when detecting host CPU speed from file, to match lscpu (#131)
* Use base clock when detecting host CPU speed from file, to match lscpu Allow for manually setting the CPU speed via agent.properties if all else fails Signed-off-by: Marcus Sorensen <mls@apple.com> * Update agent/conf/agent.properties Co-authored-by: dahn <daan.hoogland@gmail.com> Co-authored-by: Marcus Sorensen <mls@apple.com> Co-authored-by: Nicolas Vazquez <nicovazquez90@gmail.com> Co-authored-by: dahn <daan.hoogland@gmail.com>
This commit is contained in:
parent
dfc1f26762
commit
58ed95376c
@ -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
|
||||
|
||||
@ -370,6 +370,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";
|
||||
@ -1037,6 +1038,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);
|
||||
@ -3260,7 +3264,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) {
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user