[power_sampler] Add sampling of CPU temperature via SMC.
Bug: 1254332 Change-Id: I182e694672048cf8d4fa78f40baebd47dd8ec2ae Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3312177 Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org> Commit-Queue: Francois Pierre Doray <fdoray@chromium.org> Cr-Commit-Position: refs/heads/main@{#947662}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
46a1f0a64e
commit
04f941779f
chrome/browser/metrics/power
components/power_metrics
tools/mac/power/power_sampler
@ -9,12 +9,17 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// List of known SMC key identifiers.
|
||||
//
|
||||
// This is a good reference: https://logi.wiki/index.php/SMC_Sensor_Codes
|
||||
// Additional keys can be discovered with
|
||||
// https://github.com/theopolis/smc-fuzzer
|
||||
enum class SMCKeyIdentifier : uint32_t {
|
||||
TotalPower = 'PSTR', // Power: System Total Rail (watts)
|
||||
CPUPower = 'PCPC', // Power: CPU Package CPU (watts)
|
||||
iGPUPower = 'PCPG', // Power: CPU Package GPU (watts)
|
||||
GPU0Power = 'PG0R', // Power: GPU 0 Rail (watts)
|
||||
GPU1Power = 'PG1R', // Power: GPU 1 Rail (watts)
|
||||
TotalPower = 'PSTR', // Power: System Total Rail (watts)
|
||||
CPUPower = 'PCPC', // Power: CPU Package CPU (watts)
|
||||
iGPUPower = 'PCPG', // Power: CPU Package GPU (watts)
|
||||
GPU0Power = 'PG0R', // Power: GPU 0 Rail (watts)
|
||||
GPU1Power = 'PG1R', // Power: GPU 1 Rail (watts)
|
||||
CPUTemperature = 'TC0F', // Temperature: CPU Die PECI (Celsius)
|
||||
};
|
||||
|
||||
// Types from PowerManagement/pmconfigd/PrivateLib.c
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/mac/scoped_ioobject.h"
|
||||
#include "components/power_metrics/smc_internal_types_mac.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
@ -26,13 +27,9 @@ class SMCReader {
|
||||
|
||||
virtual ~SMCReader();
|
||||
|
||||
// Returns the power consumption of various hardware components in watts.
|
||||
// Returns the value of a key, or nullopt if not available.
|
||||
// Virtual for testing.
|
||||
virtual absl::optional<double> ReadTotalPowerW();
|
||||
virtual absl::optional<double> ReadCPUPackageCPUPowerW();
|
||||
virtual absl::optional<double> ReadCPUPackageGPUPowerW();
|
||||
virtual absl::optional<double> ReadGPU0PowerW();
|
||||
virtual absl::optional<double> ReadGPU1PowerW();
|
||||
virtual absl::optional<double> ReadKey(SMCKeyIdentifier identifier);
|
||||
|
||||
protected:
|
||||
explicit SMCReader(base::mac::ScopedIOObject<io_object_t> connect);
|
||||
@ -42,6 +39,8 @@ class SMCReader {
|
||||
public:
|
||||
SMCKey(base::mac::ScopedIOObject<io_object_t> connect,
|
||||
SMCKeyIdentifier key_identifier);
|
||||
SMCKey(SMCKey&&);
|
||||
SMCKey& operator=(SMCKey&&);
|
||||
~SMCKey();
|
||||
|
||||
bool Exists() const;
|
||||
@ -51,15 +50,12 @@ class SMCReader {
|
||||
bool CallSMCFunction(uint8_t function, SMCParamStruct* out);
|
||||
|
||||
base::mac::ScopedIOObject<io_object_t> connect_;
|
||||
const SMCKeyIdentifier key_identifier_;
|
||||
SMCKeyIdentifier key_identifier_;
|
||||
SMCKeyInfoData key_info_;
|
||||
};
|
||||
|
||||
SMCKey total_power_key_;
|
||||
SMCKey cpu_package_cpu_power_key_;
|
||||
SMCKey cpu_package_gpu_power_key_;
|
||||
SMCKey gpu0_power_key_;
|
||||
SMCKey gpu1_power_key_;
|
||||
base::mac::ScopedIOObject<io_object_t> connect_;
|
||||
base::flat_map<SMCKeyIdentifier, SMCKey> keys_;
|
||||
};
|
||||
|
||||
} // namespace power_metrics
|
||||
|
@ -35,24 +35,14 @@ std::unique_ptr<SMCReader> SMCReader::Create() {
|
||||
|
||||
SMCReader::~SMCReader() = default;
|
||||
|
||||
absl::optional<double> SMCReader::ReadTotalPowerW() {
|
||||
return total_power_key_.Read();
|
||||
}
|
||||
absl::optional<double> SMCReader::ReadKey(SMCKeyIdentifier identifier) {
|
||||
auto it = keys_.find(identifier);
|
||||
if (it == keys_.end()) {
|
||||
auto result = keys_.emplace(identifier, SMCKey(connect_, identifier));
|
||||
it = result.first;
|
||||
}
|
||||
|
||||
absl::optional<double> SMCReader::ReadCPUPackageCPUPowerW() {
|
||||
return cpu_package_cpu_power_key_.Read();
|
||||
}
|
||||
|
||||
absl::optional<double> SMCReader::ReadCPUPackageGPUPowerW() {
|
||||
return cpu_package_gpu_power_key_.Read();
|
||||
}
|
||||
|
||||
absl::optional<double> SMCReader::ReadGPU0PowerW() {
|
||||
return gpu0_power_key_.Read();
|
||||
}
|
||||
|
||||
absl::optional<double> SMCReader::ReadGPU1PowerW() {
|
||||
return gpu1_power_key_.Read();
|
||||
return it->second.Read();
|
||||
}
|
||||
|
||||
SMCReader::SMCKey::SMCKey(base::mac::ScopedIOObject<io_object_t> connect,
|
||||
@ -64,6 +54,9 @@ SMCReader::SMCKey::SMCKey(base::mac::ScopedIOObject<io_object_t> connect,
|
||||
key_info_ = out.keyInfo;
|
||||
}
|
||||
|
||||
SMCReader::SMCKey::SMCKey(SMCKey&&) = default;
|
||||
SMCReader::SMCKey& SMCReader::SMCKey::operator=(SMCKey&&) = default;
|
||||
|
||||
SMCReader::SMCKey::~SMCKey() = default;
|
||||
|
||||
bool SMCReader::SMCKey::Exists() const {
|
||||
@ -125,10 +118,6 @@ bool SMCReader::SMCKey::CallSMCFunction(uint8_t function, SMCParamStruct* out) {
|
||||
}
|
||||
|
||||
SMCReader::SMCReader(base::mac::ScopedIOObject<io_object_t> connect)
|
||||
: total_power_key_(connect, SMCKeyIdentifier::TotalPower),
|
||||
cpu_package_cpu_power_key_(connect, SMCKeyIdentifier::CPUPower),
|
||||
cpu_package_gpu_power_key_(connect, SMCKeyIdentifier::iGPUPower),
|
||||
gpu0_power_key_(connect, SMCKeyIdentifier::GPU0Power),
|
||||
gpu1_power_key_(connect, SMCKeyIdentifier::GPU1Power) {}
|
||||
: connect_(std::move(connect)) {}
|
||||
|
||||
} // namespace power_metrics
|
||||
|
Reference in New Issue
Block a user