Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py

Issue 578123002: [telemetry] Read MSRs from a separate privileged process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add pre-Vista check and increase server launch timeout. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py
diff --git a/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py b/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py
index 80b9f5f26838a4f67e879d172f7c0f0a2fbb27c1..038346dfebad4fa71614f4f346a388ca514833f9 100644
--- a/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py
+++ b/tools/telemetry/telemetry/core/platform/power_monitor/msr_power_monitor.py
@@ -2,19 +2,12 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import atexit
-import ctypes
import logging
-import os
import platform
import re
-import sys
-import zipfile
from telemetry import decorators
from telemetry.core.platform import power_monitor
-from telemetry.util import cloud_storage
-from telemetry.util import path
MSR_RAPL_POWER_UNIT = 0x606
@@ -26,100 +19,6 @@ IA32_PACKAGE_THERM_STATUS = 0x1b1
IA32_TEMPERATURE_TARGET = 0x1a2
-WINRING0_STATUS_MESSAGES = (
- 'No error',
- 'Unsupported platform',
- 'Driver not loaded. You may need to run as Administrator',
- 'Driver not found',
- 'Driver unloaded by other process',
- 'Driver not loaded because of executing on Network Drive',
- 'Unknown error',
-)
-
-
-# The DLL initialization is global, so put it in a global variable.
-_winring0 = None
-
-
-class WinRing0Error(OSError):
- pass
-
-
-@decorators.Cache
-def WinRing0Path():
- python_is_64_bit = sys.maxsize > 2 ** 32
- win_binary_dir = os.path.join(path.GetTelemetryDir(), 'bin', 'win')
- dll_file_name = 'WinRing0x64.dll' if python_is_64_bit else 'WinRing0.dll'
- dll_path = os.path.join(win_binary_dir, dll_file_name)
-
- os_is_64_bit = 'PROGRAMFILES(X86)' in os.environ
- executable_dir = os.path.dirname(sys.executable)
- driver_file_name = 'WinRing0x64.sys' if os_is_64_bit else 'WinRing0.sys'
- driver_path = os.path.join(executable_dir, driver_file_name)
-
- # Check for WinRing0 and download if needed.
- if not (os.path.exists(dll_path) and os.path.exists(driver_path)):
- zip_path = os.path.join(win_binary_dir, 'winring0.zip')
- cloud_storage.GetIfChanged(zip_path, bucket=cloud_storage.PUBLIC_BUCKET)
- try:
- with zipfile.ZipFile(zip_path, 'r') as zip_file:
- # Install DLL.
- if not os.path.exists(dll_path):
- zip_file.extract(dll_file_name, win_binary_dir)
- # Install kernel driver.
- if not os.path.exists(driver_path):
- zip_file.extract(driver_file_name, executable_dir)
- finally:
- os.remove(zip_path)
-
- return dll_path
-
-
-def _Initialize():
- global _winring0
- if not _winring0:
- winring0 = ctypes.WinDLL(WinRing0Path())
- if not winring0.InitializeOls():
- winring0_status = winring0.GetDllStatus()
- raise WinRing0Error(winring0_status,
- 'Unable to initialize WinRing0: %s' %
- WINRING0_STATUS_MESSAGES[winring0_status])
- _winring0 = winring0
- atexit.register(_Deinitialize)
-
-
-def _Deinitialize():
- global _winring0
- if _winring0:
- _winring0.DeinitializeOls()
- _winring0 = None
-
-
-def _ReadMsr(msr_number):
- low = ctypes.c_uint()
- high = ctypes.c_uint()
- _winring0.Rdmsr(ctypes.c_uint(msr_number),
- ctypes.byref(low), ctypes.byref(high))
- return high.value << 32 | low.value
-
-
-@decorators.Cache
-def _EnergyMultiplier():
- return 0.5 ** ((_ReadMsr(MSR_RAPL_POWER_UNIT) >> 8) & 0x1f)
-
-
-def _PackageEnergyJoules():
- return _ReadMsr(MSR_PKG_ENERGY_STATUS) * _EnergyMultiplier()
-
-
-def _TemperatureCelsius():
- tcc_activation_temp = _ReadMsr(IA32_TEMPERATURE_TARGET) >> 16 & 0x7f
- if tcc_activation_temp <= 0:
- tcc_activation_temp = 105
- package_temp_headroom = _ReadMsr(IA32_PACKAGE_THERM_STATUS) >> 16 & 0x7f
- return tcc_activation_temp - package_temp_headroom
-
-
def _JoulesToMilliwattHours(value_joules):
return value_joules * 1000 / 3600.
@@ -149,16 +48,15 @@ class MsrPowerMonitor(power_monitor.PowerMonitor):
return False
try:
- _Initialize()
- except OSError:
- return False
-
- if _PackageEnergyJoules() <= 0:
- logging.info('Cannot monitor power: no energy readings.')
- return False
-
- if _TemperatureCelsius() <= 0:
- logging.info('Cannot monitor power: no temperature readings.')
+ if self._PackageEnergyJoules() <= 0:
+ logging.info('Cannot monitor power: no energy readings.')
+ return False
+
+ if self._TemperatureCelsius() <= 0:
+ logging.info('Cannot monitor power: no temperature readings.')
+ return False
+ except OSError as e:
+ logging.info('Cannot monitor power: %s' % e)
return False
return True
@@ -166,16 +64,15 @@ class MsrPowerMonitor(power_monitor.PowerMonitor):
def StartMonitoringPower(self, browser):
assert self._start_energy_j is None and self._start_temp_c is None, (
'Called StartMonitoringPower() twice.')
- _Initialize()
- self._start_energy_j = _PackageEnergyJoules()
- self._start_temp_c = _TemperatureCelsius()
+ self._start_energy_j = self._PackageEnergyJoules()
+ self._start_temp_c = self._TemperatureCelsius()
def StopMonitoringPower(self):
assert not(self._start_energy_j is None or self._start_temp_c is None), (
'Called StopMonitoringPower() before StartMonitoringPower().')
- energy_consumption_j = _PackageEnergyJoules() - self._start_energy_j
- average_temp_c = (_TemperatureCelsius() + self._start_temp_c) / 2.
+ energy_consumption_j = self._PackageEnergyJoules() - self._start_energy_j
+ average_temp_c = (self._TemperatureCelsius() + self._start_temp_c) / 2.
assert energy_consumption_j >= 0, ('Negative energy consumption. (Starting '
'energy was %s.)' % self._start_energy_j)
@@ -191,3 +88,20 @@ class MsrPowerMonitor(power_monitor.PowerMonitor):
},
},
}
+
+ @decorators.Cache
+ def _EnergyMultiplier(self):
+ return 0.5 ** ((self._backend.ReadMsr(MSR_RAPL_POWER_UNIT) >> 8) & 0x1f)
+
+ def _PackageEnergyJoules(self):
+ return (self._backend.ReadMsr(MSR_PKG_ENERGY_STATUS) *
+ self._EnergyMultiplier())
+
+ def _TemperatureCelsius(self):
+ tcc_activation_temp = (
+ self._backend.ReadMsr(IA32_TEMPERATURE_TARGET) >> 16 & 0x7f)
+ if tcc_activation_temp <= 0:
+ tcc_activation_temp = 105
+ package_temp_headroom = (
+ self._backend.ReadMsr(IA32_PACKAGE_THERM_STATUS) >> 16 & 0x7f)
+ return tcc_activation_temp - package_temp_headroom

Powered by Google App Engine
This is Rietveld 408576698