mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +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();
 | 
			
		||||
            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