Add CPU frequency to host stats
This change set builds on the prior function and includes a function to gather the CPU frequency from the system. This change completes the functions needed to get the proper CPU Host Stats from within Nova for the PowerVM hypervisor. Change-Id: I7a2e9d76d22d3d857b14a9f378e24d6d73423ecc
This commit is contained in:
@@ -107,10 +107,13 @@ class TestHostCPUStats(test.TestCase):
|
|||||||
return lpar
|
return lpar
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@mock.patch('nova_powervm.virt.powervm.host.HostCPUStats._get_cpu_freq')
|
||||||
@mock.patch('pypowervm.tasks.monitor.util.MetricCache._refresh_if_needed')
|
@mock.patch('pypowervm.tasks.monitor.util.MetricCache._refresh_if_needed')
|
||||||
@mock.patch('pypowervm.tasks.monitor.util.ensure_ltm_monitors')
|
@mock.patch('pypowervm.tasks.monitor.util.ensure_ltm_monitors')
|
||||||
def test_update_internal_metric(self, mock_ensure_ltm, mock_refresh):
|
def test_update_internal_metric(self, mock_ensure_ltm, mock_refresh,
|
||||||
|
mock_cpu_freq):
|
||||||
host_stats = pvm_host.HostCPUStats(self.adpt, 'host_uuid')
|
host_stats = pvm_host.HostCPUStats(self.adpt, 'host_uuid')
|
||||||
|
mock_cpu_freq.return_value = 4116.0
|
||||||
|
|
||||||
# Make sure None is returned if there is no data.
|
# Make sure None is returned if there is no data.
|
||||||
host_stats.cur_phyp = None
|
host_stats.cur_phyp = None
|
||||||
@@ -124,7 +127,8 @@ class TestHostCPUStats(test.TestCase):
|
|||||||
|
|
||||||
# Validate the dictionary...
|
# Validate the dictionary...
|
||||||
expect = {'iowait': 0, 'idle': 1.6125096675799704e+16,
|
expect = {'iowait': 0, 'idle': 1.6125096675799704e+16,
|
||||||
'kernel': 58599310268, 'user': 789903553028}
|
'kernel': 58599310268, 'user': 789903553028,
|
||||||
|
'frequency': 4116.0}
|
||||||
self.assertEqual(expect, host_stats.cur_data)
|
self.assertEqual(expect, host_stats.cur_data)
|
||||||
|
|
||||||
# Now 'increment' it with a new current/previous
|
# Now 'increment' it with a new current/previous
|
||||||
@@ -135,9 +139,18 @@ class TestHostCPUStats(test.TestCase):
|
|||||||
# Validate this dictionary. Note that the values are still higher
|
# Validate this dictionary. Note that the values are still higher
|
||||||
# overall, even though we add the 'deltas' from each VM.
|
# overall, even though we add the 'deltas' from each VM.
|
||||||
expect = {'iowait': 0, 'idle': 1.6125066665694504e+16,
|
expect = {'iowait': 0, 'idle': 1.6125066665694504e+16,
|
||||||
'kernel': 58599310268, 'user': 819913658228}
|
'kernel': 58599310268, 'user': 819913658228,
|
||||||
|
'frequency': 4116.0}
|
||||||
self.assertEqual(expect, host_stats.cur_data)
|
self.assertEqual(expect, host_stats.cur_data)
|
||||||
|
|
||||||
|
@mock.patch('subprocess.check_output')
|
||||||
|
@mock.patch('pypowervm.tasks.monitor.util.MetricCache._refresh_if_needed')
|
||||||
|
@mock.patch('pypowervm.tasks.monitor.util.ensure_ltm_monitors')
|
||||||
|
def test_get_cpu_freq(self, mock_ensure_ltm, mock_refresh, mock_cmd):
|
||||||
|
host_stats = pvm_host.HostCPUStats(self.adpt, 'host_uuid')
|
||||||
|
mock_cmd.return_value = '4116.000000MHz\n'
|
||||||
|
self.assertEqual(4116.0, host_stats._get_cpu_freq())
|
||||||
|
|
||||||
@mock.patch('pypowervm.tasks.monitor.util.MetricCache._refresh_if_needed')
|
@mock.patch('pypowervm.tasks.monitor.util.MetricCache._refresh_if_needed')
|
||||||
@mock.patch('pypowervm.tasks.monitor.util.ensure_ltm_monitors')
|
@mock.patch('pypowervm.tasks.monitor.util.ensure_ltm_monitors')
|
||||||
def test_gather_user_cycles(self, mock_ensure_ltm, mock_refresh):
|
def test_gather_user_cycles(self, mock_ensure_ltm, mock_refresh):
|
||||||
|
|||||||
@@ -172,12 +172,7 @@ class PowerVMDriver(driver.ComputeDriver):
|
|||||||
|
|
||||||
def get_host_cpu_stats(self):
|
def get_host_cpu_stats(self):
|
||||||
"""Return the current CPU state of the host."""
|
"""Return the current CPU state of the host."""
|
||||||
host_stats = self.host_cpu_stats.get_host_cpu_stats()
|
return self.host_cpu_stats.get_host_cpu_stats()
|
||||||
|
|
||||||
# TODO(thorst) Implement a frequency check.
|
|
||||||
host_stats['frequency'] = 3500
|
|
||||||
|
|
||||||
return host_stats
|
|
||||||
|
|
||||||
def spawn(self, context, instance, image_meta, injected_files,
|
def spawn(self, context, instance, image_meta, injected_files,
|
||||||
admin_password, network_info=None, block_device_info=None,
|
admin_password, network_info=None, block_device_info=None,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import math
|
|||||||
from nova.compute import arch
|
from nova.compute import arch
|
||||||
from nova.compute import hv_type
|
from nova.compute import hv_type
|
||||||
from nova.compute import vm_mode
|
from nova.compute import vm_mode
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from oslo_concurrency import lockutils
|
from oslo_concurrency import lockutils
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
@@ -159,9 +160,12 @@ class HostCPUStats(pcm_util.MetricCache):
|
|||||||
# Idle is the subtraction of all.
|
# Idle is the subtraction of all.
|
||||||
idle_cycles = tot_cycles - user_cycles - fw_cycles
|
idle_cycles = tot_cycles - user_cycles - fw_cycles
|
||||||
|
|
||||||
|
# Get the processor frequency.
|
||||||
|
freq = self._get_cpu_freq()
|
||||||
|
|
||||||
# Now save these cycles to the internal data structure.
|
# Now save these cycles to the internal data structure.
|
||||||
self.cur_data = {'idle': idle_cycles, 'kernel': fw_cycles,
|
self.cur_data = {'idle': idle_cycles, 'kernel': fw_cycles,
|
||||||
'user': user_cycles, 'iowait': 0}
|
'user': user_cycles, 'iowait': 0, 'frequency': freq}
|
||||||
|
|
||||||
def _gather_user_cycles(self):
|
def _gather_user_cycles(self):
|
||||||
"""The estimated total user cycles.
|
"""The estimated total user cycles.
|
||||||
@@ -205,6 +209,12 @@ class HostCPUStats(pcm_util.MetricCache):
|
|||||||
else self.prev_data['user'])
|
else self.prev_data['user'])
|
||||||
return prev_user_cycles + vm_delta_cycles + vios_delta_cycles
|
return prev_user_cycles + vm_delta_cycles + vios_delta_cycles
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_cpu_freq():
|
||||||
|
# The output will be similar to '4116.000000MHz' on a POWER system.
|
||||||
|
cmd = ['/usr/bin/awk', '/clock/ {print $3; exit}', '/proc/cpuinfo']
|
||||||
|
return float(subprocess.check_output(cmd).rstrip("MHz\n"))
|
||||||
|
|
||||||
def _delta_proc_cycles(self, samples, prev_samples):
|
def _delta_proc_cycles(self, samples, prev_samples):
|
||||||
"""Sums all the processor delta cycles for a set of VM/VIOS samples.
|
"""Sums all the processor delta cycles for a set of VM/VIOS samples.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user