summaryrefslogtreecommitdiff
path: root/thermal
diff options
context:
space:
mode:
authorTeYuan Wang <kamewang@google.com>2021-04-27 15:11:44 +0800
committerTeYuan Wang <kamewang@google.com>2021-05-04 14:57:20 +0800
commitc618626b4fbb2c018d5e5d046d5914b661a91e6c (patch)
treee10928a02754ca3ec10cd435e70a97417dca9bed /thermal
parent3e85c9ed25a4bb0be412dd21ae55d8dbffcc54e7 (diff)
downloadpixel-c618626b4fbb2c018d5e5d046d5914b661a91e6c.tar.gz
thermal: Enhance thermal debugging
1. Add throttling request state dump 2. Add power history dump 3. Add virtual sesnor info dump 4. Refer max_state from thermal sysfs 5. Support power link disabled property Bug: 170653634 Bug: 184608718 Test: adb shell lshal debug android.hardware.thermal@2.0::IThermal/default Test: boot to home with "fastboot oem cmdline set maxcpus=4" Change-Id: I36e81af297f5522265e56752418e0c66751c1c78 Signed-off-by: TeYuan Wang <kamewang@google.com>
Diffstat (limited to 'thermal')
-rw-r--r--thermal/Thermal.cpp283
-rw-r--r--thermal/Thermal.h3
-rw-r--r--thermal/thermal-helper.cpp56
-rw-r--r--thermal/thermal-helper.h21
-rw-r--r--thermal/utils/config_parser.cpp74
-rw-r--r--thermal/utils/config_parser.h1
-rw-r--r--thermal/utils/power_files.cpp24
-rw-r--r--thermal/utils/power_files.h12
8 files changed, 329 insertions, 145 deletions
diff --git a/thermal/Thermal.cpp b/thermal/Thermal.cpp
index 1b9cca71..4e58fb7c 100644
--- a/thermal/Thermal.cpp
+++ b/thermal/Thermal.cpp
@@ -255,6 +255,195 @@ void Thermal::sendThermalChangedCallback(const Temperature_2_0 &t) {
callbacks_.end());
}
+void Thermal::dumpVirtualSensorInfo(std::ostringstream *dump_buf) {
+ *dump_buf << "VirtualSensorInfo:" << std::endl;
+ const auto &map = thermal_helper_.GetSensorInfoMap();
+ for (const auto &sensor_info_pair : map) {
+ if (sensor_info_pair.second.virtual_sensor_info != nullptr) {
+ *dump_buf << " Name: " << sensor_info_pair.first << std::endl;
+ *dump_buf << " LinkedSensorName: [";
+ for (size_t i = 0;
+ i < sensor_info_pair.second.virtual_sensor_info->linked_sensors.size(); i++) {
+ *dump_buf << sensor_info_pair.second.virtual_sensor_info->linked_sensors[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " LinkedSensorCoefficient: [";
+ for (size_t i = 0; i < sensor_info_pair.second.virtual_sensor_info->coefficients.size();
+ i++) {
+ *dump_buf << sensor_info_pair.second.virtual_sensor_info->coefficients[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " Offset: " << sensor_info_pair.second.virtual_sensor_info->offset
+ << std::endl;
+ *dump_buf << " Trigger Sensor: "
+ << (sensor_info_pair.second.virtual_sensor_info->trigger_sensor.empty()
+ ? "N/A"
+ : sensor_info_pair.second.virtual_sensor_info->trigger_sensor)
+ << std::endl;
+ *dump_buf << " Formula: ";
+ switch (sensor_info_pair.second.virtual_sensor_info->formula) {
+ case FormulaOption::COUNT_THRESHOLD:
+ *dump_buf << "COUNT_THRESHOLD";
+ break;
+ case FormulaOption::MAXIMUM:
+ *dump_buf << "MAXIMUM";
+ break;
+ case FormulaOption::MINIMUM:
+ *dump_buf << "MINIMUM";
+ break;
+ default:
+ *dump_buf << "None";
+ break;
+ }
+
+ *dump_buf << std::endl;
+ }
+ }
+}
+
+void Thermal::dumpThrottlingInfo(std::ostringstream *dump_buf) {
+ *dump_buf << "Throttling Info:" << std::endl;
+ const auto &map = thermal_helper_.GetSensorInfoMap();
+ for (const auto &name_info_pair : map) {
+ if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
+ *dump_buf << " Name: " << name_info_pair.first << std::endl;
+ *dump_buf << " PID Info:" << std::endl;
+ *dump_buf << " K_po: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->k_po[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " K_pu: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->k_pu[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " K_i: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->k_i[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " K_d: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->k_d[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " i_max: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->i_max[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " max_alloc_power: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->max_alloc_power[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " min_alloc_power: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->min_alloc_power[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " s_power: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->s_power[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " i_cutoff: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << name_info_pair.second.throttling_info->i_cutoff[i] << " ";
+ }
+ *dump_buf << "]" << std::endl;
+ *dump_buf << " Binded CDEV Info:" << std::endl;
+ if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
+ for (const auto &binded_cdev_info_pair :
+ name_info_pair.second.throttling_info->binded_cdev_info_map) {
+ *dump_buf << " Cooling device name: " << binded_cdev_info_pair.first
+ << std::endl;
+ *dump_buf << " Hard limit: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << binded_cdev_info_pair.second.limit_info[i] << " ";
+ }
+ *dump_buf << "]";
+ *dump_buf << " Power threshold: [";
+ for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
+ *dump_buf << binded_cdev_info_pair.second.power_thresholds[i] << " ";
+ }
+ *dump_buf << "]";
+ *dump_buf << " Release logic: ";
+ switch (binded_cdev_info_pair.second.release_logic) {
+ case ReleaseLogic::DECREASE:
+ *dump_buf << "DECREASE";
+ break;
+ case ReleaseLogic::BYPASS:
+ *dump_buf << "BYPASS";
+ break;
+ default:
+ *dump_buf << "None";
+ break;
+ }
+ *dump_buf << std::endl;
+ *dump_buf << " Weight: " << binded_cdev_info_pair.second.cdev_weight;
+ *dump_buf << " Cdev_ceiling: " << binded_cdev_info_pair.second.cdev_ceiling;
+ *dump_buf << " Power_sample_count: "
+ << binded_cdev_info_pair.second.power_sample_count;
+ *dump_buf << " Power_sample_delay: "
+ << binded_cdev_info_pair.second.power_sample_delay.count();
+ *dump_buf << " Power_reversly_check: "
+ << binded_cdev_info_pair.second.power_reversly_check << std::endl;
+ }
+ }
+ }
+ }
+}
+
+void Thermal::dumpThrottlingRequestStatus(std::ostringstream *dump_buf) {
+ const auto &sensor_status_map = thermal_helper_.GetSensorStatusMap();
+ const auto &cdev_status_map = thermal_helper_.GetCdevStatusMap();
+ const auto &release_map = thermal_helper_.GetThrottlingReleaseMap();
+ const auto &cdev_info_map = thermal_helper_.GetCdevInfoMap();
+ *dump_buf << "Throttling Request Status " << std::endl;
+ for (const auto &cdev_status_pair : cdev_status_map) {
+ *dump_buf << " Name: " << cdev_status_pair.first << std::endl;
+ for (const auto &request_pair : cdev_status_pair.second) {
+ *dump_buf << " Request Sensor: " << request_pair.first << std::endl;
+ *dump_buf << " Request Throttling State: " << request_pair.second << std::endl;
+ if (sensor_status_map.at(request_pair.first).pid_request_map.size() &&
+ sensor_status_map.at(request_pair.first)
+ .pid_request_map.count(cdev_status_pair.first)) {
+ *dump_buf << " PID Request State: "
+ << sensor_status_map.at(request_pair.first)
+ .pid_request_map.at(cdev_status_pair.first)
+ << std::endl;
+ }
+ if (sensor_status_map.at(request_pair.first).hard_limit_request_map.size() &&
+ sensor_status_map.at(request_pair.first)
+ .hard_limit_request_map.count(cdev_status_pair.first)) {
+ *dump_buf << " Hard Limit Request State: "
+ << sensor_status_map.at(request_pair.first)
+ .hard_limit_request_map.at(cdev_status_pair.first)
+ << std::endl;
+ }
+ if (release_map.count(request_pair.first) &&
+ release_map.at(request_pair.first)
+ .count(cdev_info_map.at(cdev_status_pair.first).power_rail)) {
+ const auto &cdev_release_info =
+ release_map.at(request_pair.first)
+ .at(cdev_info_map.at(cdev_status_pair.first).power_rail);
+ *dump_buf << " Release Step: " << cdev_release_info.release_step << std::endl;
+ *dump_buf << " Power History: ";
+ auto power_history = cdev_release_info.power_history;
+ while (power_history.size() > 0) {
+ const auto power_sample = power_history.front();
+ power_history.pop();
+ *dump_buf << "(T=" << power_sample.duration
+ << ", uWs=" << power_sample.energy_counter << ") ";
+ }
+ *dump_buf << std::endl;
+ }
+ }
+ }
+}
+
Return<void> Thermal::debug(const hidl_handle &handle, const hidl_vec<hidl_string> &) {
if (handle != nullptr && handle->numFds >= 1) {
int fd = handle->data[0];
@@ -368,24 +557,30 @@ Return<void> Thermal::debug(const hidl_handle &handle, const hidl_vec<hidl_strin
}
}
{
- dump_buf << "SendCallback:" << std::endl;
+ dump_buf << "SendCallback" << std::endl;
+ dump_buf << " Enabled List: ";
const auto &map = thermal_helper_.GetSensorInfoMap();
for (const auto &name_info_pair : map) {
- dump_buf << " Name: " << name_info_pair.first;
- dump_buf << " SendCallback: " << std::boolalpha << name_info_pair.second.send_cb
- << std::noboolalpha << std::endl;
+ if (name_info_pair.second.send_cb) {
+ dump_buf << name_info_pair.first << " ";
+ }
}
+ dump_buf << std::endl;
}
{
- dump_buf << "SendPowerHint:" << std::endl;
+ dump_buf << "SendPowerHint" << std::endl;
+ dump_buf << " Enabled List: ";
const auto &map = thermal_helper_.GetSensorInfoMap();
for (const auto &name_info_pair : map) {
- dump_buf << " Name: " << name_info_pair.first;
- dump_buf << " SendPowerHint: " << std::boolalpha
- << name_info_pair.second.send_powerhint << std::noboolalpha
- << std::endl;
+ if (name_info_pair.second.send_powerhint) {
+ dump_buf << name_info_pair.first << " ";
+ }
}
+ dump_buf << std::endl;
}
+ dumpVirtualSensorInfo(&dump_buf);
+ dumpThrottlingInfo(&dump_buf);
+ dumpThrottlingRequestStatus(&dump_buf);
{
dump_buf << "AIDL Power Hal exist: " << std::boolalpha
<< thermal_helper_.isAidlPowerHalExist() << std::endl;
@@ -394,76 +589,6 @@ Return<void> Thermal::debug(const hidl_handle &handle, const hidl_vec<hidl_strin
dump_buf << "AIDL Power Hal Ext connected: " << std::boolalpha
<< thermal_helper_.isPowerHalExtConnected() << std::endl;
}
- {
- dump_buf << "Throttling Info:" << std::endl;
- const auto &map = thermal_helper_.GetSensorInfoMap();
- for (const auto &name_info_pair : map) {
- if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
- dump_buf << " Name: " << name_info_pair.first << std::endl;
- dump_buf << " PID Info:" << std::endl;
- dump_buf << " K_po: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->k_po[i] << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " K_pu: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->k_pu[i] << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " K_i: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->k_i[i] << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " K_d: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->k_d[i] << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " i_max: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->i_max[i] << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " max_alloc_power: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->max_alloc_power[i]
- << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " min_alloc_power: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->min_alloc_power[i]
- << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " s_power: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->s_power[i] << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " i_cutoff: [";
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << name_info_pair.second.throttling_info->i_cutoff[i] << " ";
- }
- dump_buf << "]" << std::endl;
- dump_buf << " Hard Limit Info:" << std::endl;
- if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
- for (const auto &binded_cdev_info_pair :
- name_info_pair.second.throttling_info->binded_cdev_info_map) {
- dump_buf << " Cdev limit " << binded_cdev_info_pair.first
- << ": [";
-
- for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
- dump_buf << binded_cdev_info_pair.second.limit_info[i] << " ";
- }
- dump_buf << "]" << std::endl;
- }
- }
- }
- }
- }
}
std::string buf = dump_buf.str();
if (!android::base::WriteStringToFd(buf, fd)) {
diff --git a/thermal/Thermal.h b/thermal/Thermal.h
index fde746d2..53a826d7 100644
--- a/thermal/Thermal.h
+++ b/thermal/Thermal.h
@@ -82,6 +82,9 @@ class Thermal : public IThermal {
private:
ThermalHelper thermal_helper_;
+ void dumpVirtualSensorInfo(std::ostringstream *dump_buf);
+ void dumpThrottlingInfo(std::ostringstream *dump_buf);
+ void dumpThrottlingRequestStatus(std::ostringstream *dump_buf);
std::mutex thermal_callback_mutex_;
std::vector<CallbackSetting> callbacks_;
};
diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp
index 2fd86d0f..2b94517b 100644
--- a/thermal/thermal-helper.cpp
+++ b/thermal/thermal-helper.cpp
@@ -50,6 +50,7 @@ constexpr std::string_view kSensorTripPointTempZeroFile("trip_point_0_temp");
constexpr std::string_view kSensorTripPointHystZeroFile("trip_point_0_hyst");
constexpr std::string_view kUserSpaceSuffix("user_space");
constexpr std::string_view kCoolingDeviceCurStateSuffix("cur_state");
+constexpr std::string_view kCoolingDeviceMaxStateSuffix("max_state");
constexpr std::string_view kConfigProperty("vendor.thermal.config");
constexpr std::string_view kConfigDefaultFileName("thermal_info_config.json");
constexpr std::string_view kThermalGenlProperty("persist.vendor.enable.thermal.genl");
@@ -273,6 +274,14 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb)
sensor_info_map_(ParseSensorInfo(
"/vendor/etc/" +
android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()))) {
+ auto tz_map = parseThermalPathMap(kSensorPrefix.data());
+ auto cdev_map = parseThermalPathMap(kCoolingDevicePrefix.data());
+
+ is_initialized_ = initializeSensorMap(tz_map) && initializeCoolingDevices(cdev_map);
+ if (!is_initialized_) {
+ LOG(FATAL) << "ThermalHAL could not be initialized properly.";
+ }
+
for (auto const &name_status_pair : sensor_info_map_) {
sensor_status_map_[name_status_pair.first] = {
.severity = ThrottlingSeverity::NONE,
@@ -306,8 +315,9 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb)
power_files_.findEnergySourceToWatch()) {
const auto power_rail =
cooling_device_info_map_.at(binded_cdev_pair.first).power_rail;
- if (!power_files_.registerPowerRailsToWatch(name_status_pair.first, power_rail,
- binded_cdev_pair.second)) {
+ if (!power_files_.registerPowerRailsToWatch(
+ name_status_pair.first, power_rail, binded_cdev_pair.second,
+ cooling_device_info_map_.at(binded_cdev_pair.first))) {
invalid_binded_cdev = true;
LOG(ERROR) << "Could not find " << binded_cdev_pair.first
<< "'s power energy source: " << power_rail;
@@ -334,14 +344,6 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb)
}
}
- auto tz_map = parseThermalPathMap(kSensorPrefix.data());
- auto cdev_map = parseThermalPathMap(kCoolingDevicePrefix.data());
-
- is_initialized_ = initializeSensorMap(tz_map) && initializeCoolingDevices(cdev_map);
- if (!is_initialized_) {
- LOG(FATAL) << "ThermalHAL could not be initialized properly.";
- }
-
const bool thermal_throttling_disabled =
android::base::GetBoolProperty(kThermalDisabledProperty.data(), false);
@@ -654,19 +656,24 @@ void ThermalHelper::computeCoolingDevicesRequest(
std::vector<std::string> *cooling_devices_to_update) {
unsigned int release_step = 0;
+ std::unique_lock<std::shared_mutex> _lock(cdev_status_map_mutex_);
for (auto &cdev_request_pair : cdev_status_map_) {
- unsigned int pid_max = 0;
- unsigned int limit_max = 0;
+ unsigned int pid_request = 0;
+ unsigned int hard_limit_request = 0;
+ const auto max_state = cooling_device_info_map_.at(cdev_request_pair.first).max_state;
release_step = 0;
if (sensor_status.pid_request_map.count(cdev_request_pair.first)) {
- pid_max = sensor_status.pid_request_map.at(cdev_request_pair.first);
+ pid_request =
+ std::min(sensor_status.pid_request_map.at(cdev_request_pair.first), max_state);
}
+
if (sensor_status.hard_limit_request_map.count(cdev_request_pair.first)) {
- limit_max = sensor_status.hard_limit_request_map.at(cdev_request_pair.first);
+ hard_limit_request = std::min(
+ sensor_status.hard_limit_request_map.at(cdev_request_pair.first), max_state);
}
- auto request_state = fmax(pid_max, limit_max);
+ auto request_state = std::max(pid_request, hard_limit_request);
release_step = power_files_.getReleaseStep(
sensor_name, cooling_device_info_map_.at(cdev_request_pair.first).power_rail);
@@ -770,7 +777,7 @@ bool ThermalHelper::initializeSensorMap(
bool ThermalHelper::initializeCoolingDevices(
const std::unordered_map<std::string, std::string> &path_map) {
- for (const auto &cooling_device_info_pair : cooling_device_info_map_) {
+ for (auto &cooling_device_info_pair : cooling_device_info_map_) {
std::string cooling_device_name = cooling_device_info_pair.first;
if (!path_map.count(cooling_device_name)) {
LOG(ERROR) << "Could not find " << cooling_device_name << " in sysfs";
@@ -791,6 +798,20 @@ bool ThermalHelper::initializeCoolingDevices(
continue;
}
+ // Get max cooling device request state
+ std::string max_state;
+ std::string max_state_path = android::base::StringPrintf(
+ "%s/%s", path.data(), kCoolingDeviceMaxStateSuffix.data());
+ if (!android::base::ReadFileToString(max_state_path, &max_state)) {
+ LOG(ERROR) << cooling_device_info_pair.first
+ << " could not open max state file:" << max_state_path;
+ cooling_device_info_pair.second.max_state = std::numeric_limits<unsigned int>::max();
+ } else {
+ cooling_device_info_pair.second.max_state = std::stoi(android::base::Trim(max_state));
+ LOG(INFO) << "Cooling device " << cooling_device_info_pair.first
+ << " max state: " << cooling_device_info_pair.second.max_state;
+ }
+
// Add cooling device path for thermalHAL to request state
cooling_device_name =
android::base::StringPrintf("%s_%s", cooling_device_name.c_str(), "w");
@@ -1207,9 +1228,6 @@ void ThermalHelper::updateSupportedPowerHints() {
}
ThrottlingSeverity current_severity = ThrottlingSeverity::NONE;
for (const auto &severity : hidl_enum_range<ThrottlingSeverity>()) {
- LOG(ERROR) << "sensor: " << name_status_pair.first
- << " current_severity :" << toString(current_severity) << " severity "
- << toString(severity);
if (severity == ThrottlingSeverity::NONE) {
supported_powerhint_map_[name_status_pair.first][ThrottlingSeverity::NONE] =
ThrottlingSeverity::NONE;
diff --git a/thermal/thermal-helper.h b/thermal/thermal-helper.h
index 129b5dfd..f5618fe3 100644
--- a/thermal/thermal-helper.h
+++ b/thermal/thermal-helper.h
@@ -140,9 +140,25 @@ class ThermalHelper {
const std::unordered_map<std::string, SensorInfo> &GetSensorInfoMap() const {
return sensor_info_map_;
}
-
+ // Get CdevInfo Map
+ const std::unordered_map<std::string, CdevInfo> &GetCdevInfoMap() const {
+ return cooling_device_info_map_;
+ }
+ // Get SensorStatus Map
+ const std::unordered_map<std::string, SensorStatus> &GetSensorStatusMap() const {
+ std::shared_lock<std::shared_mutex> _lock(sensor_status_map_mutex_);
+ return sensor_status_map_;
+ }
+ // Get CdevStatus Map
+ const std::unordered_map<std::string, CdevRequestStatus> &GetCdevStatusMap() const {
+ std::shared_lock<std::shared_mutex> _lock(cdev_status_map_mutex_);
+ return cdev_status_map_;
+ }
+ // Get throttling release Map
+ const std::unordered_map<std::string, CdevReleaseStatus> &GetThrottlingReleaseMap() const {
+ return power_files_.GetThrottlingReleaseMap();
+ }
void sendPowerExtHint(const Temperature_2_0 &t);
-
bool isAidlPowerHalExist() { return power_hal_service_.isAidlPowerHalExist(); }
bool isPowerHalConnected() { return power_hal_service_.isPowerHalConnected(); }
bool isPowerHalExtConnected() { return power_hal_service_.isPowerHalExtConnected(); }
@@ -192,6 +208,7 @@ class ThermalHelper {
mutable std::shared_mutex sensor_status_map_mutex_;
std::unordered_map<std::string, SensorStatus> sensor_status_map_;
+ mutable std::shared_mutex cdev_status_map_mutex_;
std::unordered_map<std::string, CdevRequestStatus> cdev_status_map_;
};
diff --git a/thermal/utils/config_parser.cpp b/thermal/utils/config_parser.cpp
index 19197615..72572aa6 100644
--- a/thermal/utils/config_parser.cpp
+++ b/thermal/utils/config_parser.cpp
@@ -15,6 +15,7 @@
*/
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android-base/strings.h>
#include <cmath>
#include <unordered_set>
@@ -30,6 +31,8 @@ namespace thermal {
namespace V2_0 {
namespace implementation {
+constexpr std::string_view kPowerLinkDisabledProperty("vendor.disable.thermal.powerlink");
+
using ::android::hardware::hidl_enum_range;
using ::android::hardware::thermal::V2_0::toString;
using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType;
@@ -489,45 +492,50 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con
bool is_power_data_invalid = false;
bool power_reversly_check = false;
int power_sample_count = 0;
-
std::chrono::milliseconds power_sample_delay;
- if (!values[j]["PowerSampleDelay"]) {
- power_sample_delay = std::chrono::milliseconds::max();
- } else {
- power_sample_delay =
- std::chrono::milliseconds(getIntFromValue(values[j]["PowerSampleDelay"]));
- }
- LOG(INFO) << "Power sample delay: " << power_sample_delay.count();
-
- if (values[j]["PowerReverslyCheck"].asBool()) {
- power_reversly_check = true;
- }
- LOG(INFO) << "Power reversly check: " << power_reversly_check;
-
- power_sample_count = values[j]["PowerSampleCount"].asInt();
- LOG(INFO) << "Power sample Count: " << power_sample_count;
- sub_values = values[j]["PowerThreshold"];
- if (sub_values.size()) {
- LOG(INFO) << "Sensor[" << name << "]: Parse " << cdev_name << "'s Power threshold";
- if (!getFloatFromJsonValues(sub_values, &power_thresholds, false, false)) {
- LOG(ERROR) << "Sensor[" << name << "]: failed to parse power thresholds";
- is_power_data_invalid = true;
+ const bool power_link_disabled =
+ android::base::GetBoolProperty(kPowerLinkDisabledProperty.data(), false);
+ if (!power_link_disabled) {
+ if (!values[j]["PowerSampleDelay"]) {
+ power_sample_delay = std::chrono::milliseconds::max();
+ } else {
+ power_sample_delay = std::chrono::milliseconds(
+ getIntFromValue(values[j]["PowerSampleDelay"]));
}
+ LOG(INFO) << "Power sample delay: " << power_sample_delay.count();
- if (values[j]["ReleaseLogic"].asString() == "DECREASE") {
- release_logic = ReleaseLogic::DECREASE;
- LOG(INFO) << "Release logic: DECREASE";
- } else if (values[j]["ReleaseLogic"].asString() == "BYPASS") {
- release_logic = ReleaseLogic::BYPASS;
- LOG(INFO) << "Release logic: BYPASS";
- } else {
- is_power_data_invalid = true;
+ if (values[j]["PowerReverslyCheck"].asBool()) {
+ power_reversly_check = true;
}
+ LOG(INFO) << "Power reversly check: " << power_reversly_check;
+
+ power_sample_count = values[j]["PowerSampleCount"].asInt();
+ LOG(INFO) << "Power sample Count: " << power_sample_count;
+
+ sub_values = values[j]["PowerThreshold"];
+ if (sub_values.size()) {
+ LOG(INFO) << "Sensor[" << name << "]: Parse " << cdev_name
+ << "'s Power threshold";
+ if (!getFloatFromJsonValues(sub_values, &power_thresholds, false, false)) {
+ LOG(ERROR) << "Sensor[" << name << "]: failed to parse power thresholds";
+ is_power_data_invalid = true;
+ }
- if (is_power_data_invalid) {
- sensors_parsed.clear();
- return sensors_parsed;
+ if (values[j]["ReleaseLogic"].asString() == "DECREASE") {
+ release_logic = ReleaseLogic::DECREASE;
+ LOG(INFO) << "Release logic: DECREASE";
+ } else if (values[j]["ReleaseLogic"].asString() == "BYPASS") {
+ release_logic = ReleaseLogic::BYPASS;
+ LOG(INFO) << "Release logic: BYPASS";
+ } else {
+ is_power_data_invalid = true;
+ }
+
+ if (is_power_data_invalid) {
+ sensors_parsed.clear();
+ return sensors_parsed;
+ }
}
}
diff --git a/thermal/utils/config_parser.h b/thermal/utils/config_parser.h
index 9238093c..6d4bab49 100644
--- a/thermal/utils/config_parser.h
+++ b/thermal/utils/config_parser.h
@@ -109,6 +109,7 @@ struct CdevInfo {
std::string power_rail;
std::chrono::milliseconds power_sample_rate;
int power_sample_count;
+ unsigned int max_state;
};
std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path);
diff --git a/thermal/utils/power_files.cpp b/thermal/utils/power_files.cpp
index 16d663c1..cfa31027 100644
--- a/thermal/utils/power_files.cpp
+++ b/thermal/utils/power_files.cpp
@@ -36,6 +36,7 @@ using android::base::ReadFileToString;
using android::base::StringPrintf;
void PowerFiles::setPowerDataToDefault(std::string_view sensor_name) {
+ std::unique_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
if (!throttling_release_map_.count(sensor_name.data())) {
return;
}
@@ -55,6 +56,7 @@ void PowerFiles::setPowerDataToDefault(std::string_view sensor_name) {
unsigned int PowerFiles::getReleaseStep(std::string_view sensor_name, std::string_view power_rail) {
unsigned int release_step = 0;
+ std::shared_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
if (throttling_release_map_.count(sensor_name.data()) &&
throttling_release_map_[sensor_name.data()].count(power_rail.data())) {
@@ -66,7 +68,8 @@ unsigned int PowerFiles::getReleaseStep(std::string_view sensor_name, std::strin
bool PowerFiles::registerPowerRailsToWatch(std::string_view sensor_name,
std::string_view power_rail,
- const BindedCdevInfo &binded_cdev_info) {
+ const BindedCdevInfo &binded_cdev_info,
+ const CdevInfo &cdev_info) {
std::queue<PowerSample> power_history;
PowerSample power_sample = {
.energy_counter = 0,
@@ -78,16 +81,14 @@ bool PowerFiles::registerPowerRailsToWatch(std::string_view sensor_name,
return false;
}
- for (int i = 0; i < binded_cdev_info.power_sample_count; i++) {
- if (energy_info_map_.count(power_rail.data())) {
+ if (energy_info_map_.count(power_rail.data())) {
+ for (int i = 0; i < binded_cdev_info.power_sample_count; i++) {
power_history.emplace(power_sample);
}
- }
-
- if (energy_info_map_.count(power_rail.data())) {
throttling_release_map_[sensor_name.data()][power_rail.data()] = {
.power_history = power_history,
.release_step = 0,
+ .max_release_step = cdev_info.max_state,
.time_remaining = binded_cdev_info.power_sample_delay,
};
} else {
@@ -199,6 +200,7 @@ void PowerFiles::throttlingReleaseUpdate(std::string_view sensor_name,
const std::chrono::milliseconds time_elapsed_ms,
const BindedCdevInfo &binded_cdev_info,
std::string_view power_rail) {
+ std::unique_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
if (!throttling_release_map_.count(sensor_name.data()) ||
!throttling_release_map_[sensor_name.data()].count(power_rail.data())) {
return;
@@ -254,16 +256,16 @@ void PowerFiles::throttlingReleaseUpdate(std::string_view sensor_name,
is_over_budget = false;
}
}
- LOG(VERBOSE) << "Power rail " << power_rail << ": power threshold = "
- << binded_cdev_info.power_thresholds[static_cast<int>(severity)]
- << ", avg power = " << avg_power << ", duration = " << duration
- << ", deltaEnergy = " << deltaEnergy;
+ LOG(INFO) << "Power rail " << power_rail << ": power threshold = "
+ << binded_cdev_info.power_thresholds[static_cast<int>(severity)]
+ << ", avg power = " << avg_power << ", duration = " << duration
+ << ", deltaEnergy = " << deltaEnergy;
}
switch (binded_cdev_info.release_logic) {
case ReleaseLogic::DECREASE:
if (!is_over_budget) {
- if (cdev_release_status.release_step < std::numeric_limits<int>::max()) {
+ if (cdev_release_status.release_step < cdev_release_status.max_release_step) {
cdev_release_status.release_step++;
}
} else {
diff --git a/thermal/utils/power_files.h b/thermal/utils/power_files.h
index 814badf4..b76e028a 100644
--- a/thermal/utils/power_files.h
+++ b/thermal/utils/power_files.h
@@ -17,6 +17,7 @@
#pragma once
#include <queue>
+#include <shared_mutex>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -39,6 +40,7 @@ struct ReleaseStatus {
// A queue to record ODPM info pair (timestamp, mWs)
std::queue<PowerSample> power_history;
unsigned int release_step;
+ unsigned int max_release_step;
};
using CdevReleaseStatus = std::unordered_map<std::string, ReleaseStatus>;
@@ -55,7 +57,8 @@ class PowerFiles {
// Register a map for the throttling release decision of target power rail
// Return false if the power_rail is not supported.
bool registerPowerRailsToWatch(std::string_view sensor_name, std::string_view power_rail,
- const BindedCdevInfo &binded_cdev_info);
+ const BindedCdevInfo &binded_cdev_info,
+ const CdevInfo &cdev_info);
// Find the energy source path, return false if no energy source found.
bool findEnergySourceToWatch(void);
@@ -79,11 +82,18 @@ class PowerFiles {
// Clear the data of throttling_release_map_.
void setPowerDataToDefault(std::string_view sensor_name);
+ // Get throttling release status map
+ const std::unordered_map<std::string, CdevReleaseStatus> &GetThrottlingReleaseMap() const {
+ std::shared_lock<std::shared_mutex> _lock(throttling_release_map_mutex_);
+ return throttling_release_map_;
+ }
+
private:
// The map to record the energy info for each power rail.
std::unordered_map<std::string, PowerSample> energy_info_map_;
// The map to record the throttling release status for each thermal sensor.
std::unordered_map<std::string, CdevReleaseStatus> throttling_release_map_;
+ mutable std::shared_mutex throttling_release_map_mutex_;
// The set to store the energy source paths
std::unordered_set<std::string> energy_path_set_;
};