diff options
author | TeYuan Wang <kamewang@google.com> | 2022-03-14 17:33:15 +0800 |
---|---|---|
committer | TeYuan Wang <kamewang@google.com> | 2022-04-01 17:13:19 +0800 |
commit | 2ec4c035928b20042a19aecfde252261526676aa (patch) | |
tree | fc63a81780ffa290306317d463ca8b7b01c147ef | |
parent | 90d879de7c822455afaf48a76c6e309aca2dc022 (diff) |
thermal: enhance thermal config parsing
1. Trigger FATAL crash for invalid thermal config
2. Add boundary check for thermal threshold
Bug: 223856015
Bug: 124822954
Bug: 221077673
Test: Side load thermal config with overlapped thresholds and confirm thermHAL can trigger crash
Change-Id: I58221455f7e893bcd2c753e98d1b625ba36cdc75
-rw-r--r-- | thermal/thermal-helper.cpp | 59 | ||||
-rw-r--r-- | thermal/utils/config_parser.cpp | 282 | ||||
-rw-r--r-- | thermal/utils/config_parser.h | 9 | ||||
-rw-r--r-- | thermal/utils/power_files.cpp | 15 |
4 files changed, 206 insertions, 159 deletions
diff --git a/thermal/thermal-helper.cpp b/thermal/thermal-helper.cpp index 81beb55..cbf42b0 100644 --- a/thermal/thermal-helper.cpp +++ b/thermal/thermal-helper.cpp @@ -274,13 +274,26 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) const std::string config_path = "/vendor/etc/" + android::base::GetProperty(kConfigProperty.data(), kConfigDefaultFileName.data()); - cooling_device_info_map_ = ParseCoolingDevice(config_path); - sensor_info_map_ = ParseSensorInfo(config_path); - power_rail_info_map_ = ParsePowerRailInfo(config_path); + bool thermal_throttling_disabled = + android::base::GetBoolProperty(kThermalDisabledProperty.data(), false); + + is_initialized_ = ParseCoolingDevice(config_path, &cooling_device_info_map_) && + ParseSensorInfo(config_path, &sensor_info_map_) && + ParsePowerRailInfo(config_path, &power_rail_info_map_); + + if (thermal_throttling_disabled) { + return; + } + + if (!is_initialized_) { + LOG(FATAL) << "Failed to parse thermal configs"; + } + 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."; } @@ -297,12 +310,10 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) .prev_err = NAN, }; - bool invalid_binded_cdev = false; for (auto &binded_cdev_pair : name_status_pair.second.throttling_info->binded_cdev_info_map) { if (!cooling_device_info_map_.count(binded_cdev_pair.first)) { - invalid_binded_cdev = true; - LOG(ERROR) << "Could not find " << binded_cdev_pair.first + LOG(FATAL) << "Could not find " << binded_cdev_pair.first << " in cooling device info map"; } @@ -343,45 +354,26 @@ ThermalHelper::ThermalHelper(const NotificationCallback &cb) if (!power_files_.registerPowerRailsToWatch( name_status_pair.first, binded_cdev_pair.first, binded_cdev_pair.second, cdev_info, power_rail_info)) { - invalid_binded_cdev = true; - LOG(ERROR) << "Could not find " << binded_cdev_pair.first + LOG(FATAL) << "Could not register " << binded_cdev_pair.first << "'s power energy source: " << binded_cdev_pair.second.power_rail; } } } - if (invalid_binded_cdev) { - name_status_pair.second.throttling_info->binded_cdev_info_map.clear(); - sensor_status_map_[name_status_pair.first].hard_limit_request_map.clear(); - sensor_status_map_[name_status_pair.first].pid_request_map.clear(); - } - if (name_status_pair.second.virtual_sensor_info != nullptr && + !name_status_pair.second.virtual_sensor_info->trigger_sensor.empty() && name_status_pair.second.is_monitor) { if (sensor_info_map_.count( name_status_pair.second.virtual_sensor_info->trigger_sensor)) { sensor_info_map_[name_status_pair.second.virtual_sensor_info->trigger_sensor] .is_monitor = true; } else { - LOG(FATAL) << name_status_pair.first << " does not have trigger sensor: " + LOG(FATAL) << "Could not find " << name_status_pair.first << "'s trigger sensor: " << name_status_pair.second.virtual_sensor_info->trigger_sensor; } } } - const bool thermal_throttling_disabled = - android::base::GetBoolProperty(kThermalDisabledProperty.data(), false); - - if (thermal_throttling_disabled) { - LOG(INFO) << kThermalDisabledProperty.data() << " is true"; - for (const auto &cdev_pair : cooling_device_info_map_) { - if (cooling_devices_.writeCdevFile(cdev_pair.first, std::to_string(0))) { - LOG(INFO) << "Successfully clear cdev " << cdev_pair.first << " to 0"; - } - } - return; - } - const bool thermal_genl_enabled = android::base::GetBoolProperty(kThermalGenlProperty.data(), false); @@ -813,7 +805,7 @@ bool ThermalHelper::initializeCoolingDevices( 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"; - continue; + return false; } // Add cooling device path for thermalHAL to get current state std::string_view path = path_map.at(cooling_device_name); @@ -827,7 +819,7 @@ bool ThermalHelper::initializeCoolingDevices( if (!cooling_devices_.addThermalFile(cooling_device_name, read_path)) { LOG(ERROR) << "Could not add " << cooling_device_name << " read path to cooling device map"; - continue; + return false; } std::string state2power_path = android::base::StringPrintf( @@ -871,6 +863,7 @@ bool ThermalHelper::initializeCoolingDevices( << cooling_device_info_pair.second.state2power.size() << ", number should be " << cooling_device_info_pair.second.max_state + 1 << " (max_state + 1)"; + return false; } } @@ -888,13 +881,9 @@ bool ThermalHelper::initializeCoolingDevices( if (!cooling_devices_.addThermalFile(cooling_device_name, write_path)) { LOG(ERROR) << "Could not add " << cooling_device_name << " write path to cooling device map"; - continue; + return false; } } - - if (cooling_device_info_map_.size() * 2 != cooling_devices_.getNumThermalFiles()) { - LOG(ERROR) << "Some cooling device can not be initialized"; - } return true; } diff --git a/thermal/utils/config_parser.cpp b/thermal/utils/config_parser.cpp index 4971c87..5c81041 100644 --- a/thermal/utils/config_parser.cpp +++ b/thermal/utils/config_parser.cpp @@ -136,14 +136,13 @@ bool getFloatFromJsonValues(const Json::Value &values, ThrottlingArray *out, boo } } // namespace -std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path) { +bool ParseSensorInfo(std::string_view config_path, + std::unordered_map<std::string, SensorInfo> *sensors_parsed) { std::string json_doc; - std::unordered_map<std::string, SensorInfo> sensors_parsed; if (!android::base::ReadFileToString(config_path.data(), &json_doc)) { LOG(ERROR) << "Failed to read JSON config from " << config_path; - return sensors_parsed; + return false; } - Json::Value root; Json::CharReaderBuilder builder; std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); @@ -151,7 +150,7 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) { LOG(ERROR) << "Failed to parse JSON config: " << errorMessage; - return sensors_parsed; + return false; } Json::Value sensors = root["Sensors"]; @@ -164,15 +163,15 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con if (name.empty()) { LOG(ERROR) << "Failed to read " << "Sensor[" << i << "]'s Name"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } auto result = sensors_name_parsed.insert(name); if (!result.second) { LOG(ERROR) << "Duplicate Sensor[" << i << "]'s Name"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } std::string sensor_type_str = sensors[i]["Type"].asString(); @@ -182,8 +181,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con if (!getTypeFromString(sensor_type_str, &sensor_type)) { LOG(ERROR) << "Invalid " << "Sensor[" << name << "]'s Type: " << sensor_type_str; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } bool send_cb = false; @@ -225,11 +224,13 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con is_virtual_sensor = sensors[i]["VirtualSensor"].asBool(); } Json::Value values = sensors[i]["HotThreshold"]; - if (values.size() != kThrottlingSeverityCount) { + if (!values.size()) { + LOG(INFO) << "Sensor[" << name << "]'s HotThreshold, default all to NAN"; + } else if (values.size() != kThrottlingSeverityCount) { LOG(ERROR) << "Invalid " - << "Sensor[" << name << "]'s HotThreshold count" << values.size(); - sensors_parsed.clear(); - return sensors_parsed; + << "Sensor[" << name << "]'s HotThreshold count:" << values.size(); + sensors_parsed->clear(); + return false; } else { float min = std::numeric_limits<float>::min(); for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { @@ -239,8 +240,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con LOG(ERROR) << "Invalid " << "Sensor[" << name << "]'s HotThreshold[j" << j << "]: " << hot_thresholds[j] << " < " << min; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } min = hot_thresholds[j]; } @@ -250,27 +251,53 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con } values = sensors[i]["HotHysteresis"]; - if (values.size() != kThrottlingSeverityCount) { - LOG(INFO) << "Cannot find valid " - << "Sensor[" << name << "]'s HotHysteresis, default all to 0.0"; + if (!values.size()) { + LOG(INFO) << "Sensor[" << name << "]'s HotHysteresis, default all to 0.0"; + } else if (values.size() != kThrottlingSeverityCount) { + LOG(ERROR) << "Invalid " + << "Sensor[" << name << "]'s HotHysteresis, count:" << values.size(); + sensors_parsed->clear(); + return false; } else { for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { hot_hysteresis[j] = getFloatFromValue(values[j]); if (std::isnan(hot_hysteresis[j])) { LOG(ERROR) << "Invalid " << "Sensor[" << name << "]'s HotHysteresis: " << hot_hysteresis[j]; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Sensor[" << name << "]'s HotHysteresis[" << j << "]: " << hot_hysteresis[j]; } } + for (Json::Value::ArrayIndex j = 0; j < (kThrottlingSeverityCount - 1); ++j) { + if (std::isnan(hot_thresholds[j])) { + continue; + } + for (auto k = j + 1; k < kThrottlingSeverityCount; ++k) { + if (std::isnan(hot_thresholds[k])) { + continue; + } else if (hot_thresholds[j] > (hot_thresholds[k] - hot_hysteresis[k])) { + LOG(ERROR) << "Sensor[" << name << "]'s hot threshold " << j + << " is overlapped"; + sensors_parsed->clear(); + return false; + } else { + break; + } + } + } + values = sensors[i]["ColdThreshold"]; - if (values.size() != kThrottlingSeverityCount) { - LOG(INFO) << "Cannot find valid " - << "Sensor[" << name << "]'s ColdThreshold, default all to NAN"; + if (!values.size()) { + LOG(INFO) << "Sensor[" << name << "]'s ColdThreshold, default all to NAN"; + } else if (values.size() != kThrottlingSeverityCount) { + LOG(ERROR) << "Invalid " + << "Sensor[" << name << "]'s ColdThreshold count:" << values.size(); + sensors_parsed->clear(); + return false; } else { float max = std::numeric_limits<float>::max(); for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { @@ -280,8 +307,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con LOG(ERROR) << "Invalid " << "Sensor[" << name << "]'s ColdThreshold[j" << j << "]: " << cold_thresholds[j] << " > " << max; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } max = cold_thresholds[j]; } @@ -291,26 +318,46 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con } values = sensors[i]["ColdHysteresis"]; - if (values.size() != kThrottlingSeverityCount) { - LOG(INFO) << "Cannot find valid " - << "Sensor[" << name << "]'s ColdHysteresis, default all to 0.0"; + if (!values.size()) { + LOG(INFO) << "Sensor[" << name << "]'s ColdHysteresis, default all to 0.0"; + } else if (values.size() != kThrottlingSeverityCount) { + LOG(ERROR) << "Invalid " + << "Sensor[" << name << "]'s ColdHysteresis count:" << values.size(); + sensors_parsed->clear(); + return false; } else { for (Json::Value::ArrayIndex j = 0; j < kThrottlingSeverityCount; ++j) { cold_hysteresis[j] = getFloatFromValue(values[j]); if (std::isnan(cold_hysteresis[j])) { LOG(ERROR) << "Invalid " - << "Sensor[" << name - << "]'s ColdHysteresis: " << cold_hysteresis[j]; - sensors_parsed.clear(); - return sensors_parsed; + << "Sensor[" << name << "]'s ColdHysteresis: " << cold_hysteresis[j]; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Sensor[" << name << "]'s ColdHysteresis[" << j << "]: " << cold_hysteresis[j]; } } + for (Json::Value::ArrayIndex j = 0; j < (kThrottlingSeverityCount - 1); ++j) { + if (std::isnan(cold_thresholds[j])) { + continue; + } + for (auto k = j + 1; k < kThrottlingSeverityCount; ++k) { + if (std::isnan(cold_thresholds[k])) { + continue; + } else if (cold_thresholds[j] < (cold_thresholds[k] + cold_hysteresis[k])) { + LOG(ERROR) << "Sensor[" << name << "]'s cold threshold " << j + << " is overlapped"; + sensors_parsed->clear(); + return false; + } else { + break; + } + } + } + if (is_virtual_sensor) { - bool ret = true; values = sensors[i]["Combination"]; if (values.size()) { linked_sensors.reserve(values.size()); @@ -320,7 +367,9 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con << "]: " << linked_sensors[j]; } } else { - ret = false; + LOG(ERROR) << "Sensor[" << name << "] has no combination setting"; + sensors_parsed->clear(); + return false; } values = sensors[i]["Coefficient"]; @@ -332,21 +381,22 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con << "]: " << coefficients[j]; } } else { - ret = false; + LOG(ERROR) << "Sensor[" << name << "] has no coefficient setting"; + sensors_parsed->clear(); + return false; } if (linked_sensors.size() != coefficients.size()) { - ret = false; + LOG(ERROR) << "Sensor[" << name + << "]'s combination size is not matched with coefficient size"; + sensors_parsed->clear(); + return false; } if (!sensors[i]["Offset"].empty()) { offset = sensors[i]["Offset"].asFloat(); } - if (linked_sensors.size() != coefficients.size()) { - ret = false; - } - trigger_sensor = sensors[i]["TriggerSensor"].asString(); if (sensors[i]["Formula"].asString().compare("COUNT_THRESHOLD") == 0) { formula = FormulaOption::COUNT_THRESHOLD; @@ -357,11 +407,9 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con } else if (sensors[i]["Formula"].asString().compare("MINIMUM") == 0) { formula = FormulaOption::MINIMUM; } else { - ret = false; - } - if (!ret) { - sensors_parsed.clear(); - return sensors_parsed; + LOG(ERROR) << "Sensor[" << name << "]'s Formula is invalid"; + sensors_parsed->clear(); + return false; } } @@ -430,40 +478,40 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con if (sensors[i]["PIDInfo"]["K_Po"].empty() || !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_Po"], &k_po, false, false)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse K_Po"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s K_Pu"; if (sensors[i]["PIDInfo"]["K_Pu"].empty() || !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_Pu"], &k_pu, false, false)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse K_Pu"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s K_I"; if (sensors[i]["PIDInfo"]["K_I"].empty() || !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_I"], &k_i, false, false)) { - LOG(INFO) << "Sensor[" << name << "]: Failed to parse K_I"; - sensors_parsed.clear(); - return sensors_parsed; + LOG(ERROR) << "Sensor[" << name << "]: Failed to parse K_I"; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s K_D"; if (sensors[i]["PIDInfo"]["K_D"].empty() || !getFloatFromJsonValues(sensors[i]["PIDInfo"]["K_D"], &k_d, false, false)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse K_D"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s I_Max"; if (sensors[i]["PIDInfo"]["I_Max"].empty() || !getFloatFromJsonValues(sensors[i]["PIDInfo"]["I_Max"], &i_max, false, false)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse I_Max"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s MaxAllocPower"; @@ -471,8 +519,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con !getFloatFromJsonValues(sensors[i]["PIDInfo"]["MaxAllocPower"], &max_alloc_power, false, true)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse MaxAllocPower"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s MinAllocPower"; @@ -480,16 +528,16 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con !getFloatFromJsonValues(sensors[i]["PIDInfo"]["MinAllocPower"], &min_alloc_power, false, true)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse MinAllocPower"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s S_Power"; if (sensors[i]["PIDInfo"]["S_Power"].empty() || !getFloatFromJsonValues(sensors[i]["PIDInfo"]["S_Power"], &s_power, false, true)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse S_Power"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } LOG(INFO) << "Start to parse" << " Sensor[" << name << "]'s I_Cutoff"; @@ -497,8 +545,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con !getFloatFromJsonValues(sensors[i]["PIDInfo"]["I_Cutoff"], &i_cutoff, false, false)) { LOG(ERROR) << "Sensor[" << name << "]: Failed to parse I_Cutoff"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } // Confirm we have at least one valid PID combination bool valid_pid_combination = false; @@ -517,8 +565,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con } if (!valid_pid_combination) { LOG(ERROR) << "Sensor[" << name << "]: Invalid PID parameters combinations"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } else { support_pid = true; } @@ -542,8 +590,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con if (!getFloatFromJsonValues(values[j]["CdevWeightForPID"], &cdev_weight_for_pid, false, false)) { LOG(ERROR) << "Failed to parse CdevWeightForPID"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } } if (!values[j]["CdevCeiling"].empty()) { @@ -552,8 +600,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con if (!getIntFromJsonValues(values[j]["CdevCeiling"], &cdev_ceiling, false, false)) { LOG(ERROR) << "Failed to parse CdevCeiling"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } } } @@ -569,14 +617,13 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con LOG(INFO) << "Sensor[" << name << "]: Start to parse LimitInfo: " << cdev_name; if (!getIntFromJsonValues(sub_values, &limit_info, false, false)) { LOG(ERROR) << "Failed to parse LimitInfo"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } support_hard_limit = true; } // Parse linked power info - bool is_power_data_invalid = false; std::string power_rail; bool high_power_check = false; bool throttling_with_power_link = false; @@ -606,7 +653,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con if (!getIntFromJsonValues(sub_values, &cdev_floor_with_power_link, false, false)) { LOG(ERROR) << "Failed to parse CdevFloor"; - is_power_data_invalid = true; + sensors_parsed->clear(); + return false; } } sub_values = values[j]["PowerThreshold"]; @@ -615,7 +663,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con << "'s PowerThreshold"; if (!getFloatFromJsonValues(sub_values, &power_thresholds, false, false)) { LOG(ERROR) << "Failed to parse power thresholds"; - is_power_data_invalid = true; + sensors_parsed->clear(); + return false; } if (values[j]["ReleaseLogic"].asString() == "INCREASE") { @@ -632,13 +681,8 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con LOG(INFO) << "Release logic: RELEASE_TO_FLOOR"; } else { LOG(ERROR) << "Release logic is invalid"; - is_power_data_invalid = true; - } - - if (is_power_data_invalid) { - LOG(ERROR) << cdev_name << "'s power rail " << power_rail << " is invalid"; - sensors_parsed.clear(); - return sensors_parsed; + sensors_parsed->clear(); + return false; } } } @@ -669,7 +713,7 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con new ThrottlingInfo{k_po, k_pu, k_i, k_d, i_max, max_alloc_power, min_alloc_power, s_power, i_cutoff, binded_cdev_info_map}); - sensors_parsed[name] = { + (*sensors_parsed)[name] = { .type = sensor_type, .hot_thresholds = hot_thresholds, .cold_thresholds = cold_thresholds, @@ -690,19 +734,17 @@ std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view con ++total_parsed; } - LOG(INFO) << total_parsed << " Sensors parsed successfully"; - return sensors_parsed; + return true; } -std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view config_path) { +bool ParseCoolingDevice(std::string_view config_path, + std::unordered_map<std::string, CdevInfo> *cooling_devices_parsed) { std::string json_doc; - std::unordered_map<std::string, CdevInfo> cooling_devices_parsed; if (!android::base::ReadFileToString(config_path.data(), &json_doc)) { LOG(ERROR) << "Failed to read JSON config from " << config_path; - return cooling_devices_parsed; + return false; } - Json::Value root; Json::CharReaderBuilder builder; std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); @@ -710,7 +752,7 @@ std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view co if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) { LOG(ERROR) << "Failed to parse JSON config"; - return cooling_devices_parsed; + return false; } Json::Value cooling_devices = root["CoolingDevices"]; @@ -723,15 +765,15 @@ std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view co if (name.empty()) { LOG(ERROR) << "Failed to read " << "CoolingDevice[" << i << "]'s Name"; - cooling_devices_parsed.clear(); - return cooling_devices_parsed; + cooling_devices_parsed->clear(); + return false; } auto result = cooling_devices_name_parsed.insert(name.data()); if (!result.second) { LOG(ERROR) << "Duplicate CoolingDevice[" << i << "]'s Name"; - cooling_devices_parsed.clear(); - return cooling_devices_parsed; + cooling_devices_parsed->clear(); + return false; } std::string cooling_device_type_str = cooling_devices[i]["Type"].asString(); @@ -741,8 +783,8 @@ std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view co if (!getTypeFromString(cooling_device_type_str, &cooling_device_type)) { LOG(ERROR) << "Invalid " << "CoolingDevice[" << name << "]'s Type: " << cooling_device_type_str; - cooling_devices_parsed.clear(); - return cooling_devices_parsed; + cooling_devices_parsed->clear(); + return false; } const std::string &read_path = cooling_devices[i]["ReadPath"].asString(); @@ -768,7 +810,7 @@ std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view co const std::string &power_rail = cooling_devices[i]["PowerRail"].asString(); LOG(INFO) << "Cooling device power rail : " << power_rail; - cooling_devices_parsed[name] = { + (*cooling_devices_parsed)[name] = { .type = cooling_device_type, .read_path = read_path, .write_path = write_path, @@ -776,19 +818,17 @@ std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view co }; ++total_parsed; } - LOG(INFO) << total_parsed << " CoolingDevices parsed successfully"; - return cooling_devices_parsed; + return true; } -std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_view config_path) { +bool ParsePowerRailInfo(std::string_view config_path, + std::unordered_map<std::string, PowerRailInfo> *power_rails_parsed) { std::string json_doc; - std::unordered_map<std::string, PowerRailInfo> power_rails_parsed; if (!android::base::ReadFileToString(config_path.data(), &json_doc)) { LOG(ERROR) << "Failed to read JSON config from " << config_path; - return power_rails_parsed; + return false; } - Json::Value root; Json::CharReaderBuilder builder; std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); @@ -796,7 +836,7 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi if (!reader->parse(&*json_doc.begin(), &*json_doc.end(), &root, &errorMessage)) { LOG(ERROR) << "Failed to parse JSON config"; - return power_rails_parsed; + return false; } Json::Value power_rails = root["PowerRails"]; @@ -809,8 +849,8 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi if (name.empty()) { LOG(ERROR) << "Failed to read " << "PowerRail[" << i << "]'s Name"; - power_rails_parsed.clear(); - return power_rails_parsed; + power_rails_parsed->clear(); + return false; } std::string rail; @@ -845,8 +885,9 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi << "]: " << linked_power_rails[j]; } } else { - power_rails_parsed.clear(); - return power_rails_parsed; + LOG(ERROR) << "PowerRails[" << name << "] has no combination for VirtualRail"; + power_rails_parsed->clear(); + return false; } values = power_rails[i]["Coefficient"]; @@ -858,8 +899,9 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi << "]: " << coefficients[j]; } } else { - power_rails_parsed.clear(); - return power_rails_parsed; + LOG(ERROR) << "PowerRails[" << name << "] has no coefficient for VirtualRail"; + power_rails_parsed->clear(); + return false; } if (!power_rails[i]["Offset"].empty()) { @@ -867,8 +909,10 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi } if (linked_power_rails.size() != coefficients.size()) { - power_rails_parsed.clear(); - return power_rails_parsed; + LOG(ERROR) << "PowerRails[" << name + << "]'s combination size is not matched with coefficient size"; + power_rails_parsed->clear(); + return false; } if (power_rails[i]["Formula"].asString().compare("COUNT_THRESHOLD") == 0) { @@ -880,8 +924,9 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi } else if (power_rails[i]["Formula"].asString().compare("MINIMUM") == 0) { formula = FormulaOption::MINIMUM; } else { - power_rails_parsed.clear(); - return power_rails_parsed; + LOG(ERROR) << "PowerRails[" << name << "]'s Formula is invalid"; + power_rails_parsed->clear(); + return false; } } @@ -901,7 +946,7 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi std::chrono::milliseconds(getIntFromValue(power_rails[i]["PowerSampleDelay"])); } - power_rails_parsed[name] = { + (*power_rails_parsed)[name] = { .rail = rail, .power_sample_count = power_sample_count, .power_sample_delay = power_sample_delay, @@ -909,9 +954,8 @@ std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_vi }; ++total_parsed; } - LOG(INFO) << total_parsed << " PowerRails parsed successfully"; - return power_rails_parsed; + return true; } } // namespace implementation diff --git a/thermal/utils/config_parser.h b/thermal/utils/config_parser.h index f52475f..cb27297 100644 --- a/thermal/utils/config_parser.h +++ b/thermal/utils/config_parser.h @@ -129,9 +129,12 @@ struct PowerRailInfo { std::unique_ptr<VirtualPowerRailInfo> virtual_power_rail_info; }; -std::unordered_map<std::string, SensorInfo> ParseSensorInfo(std::string_view config_path); -std::unordered_map<std::string, CdevInfo> ParseCoolingDevice(std::string_view config_path); -std::unordered_map<std::string, PowerRailInfo> ParsePowerRailInfo(std::string_view config_path); +bool ParseSensorInfo(std::string_view config_path, + std::unordered_map<std::string, SensorInfo> *sensors_parsed); +bool ParseCoolingDevice(std::string_view config_path, + std::unordered_map<std::string, CdevInfo> *cooling_device_parsed); +bool ParsePowerRailInfo(std::string_view config_path, + std::unordered_map<std::string, PowerRailInfo> *power_rail_parsed); } // namespace implementation } // namespace V2_0 diff --git a/thermal/utils/power_files.cpp b/thermal/utils/power_files.cpp index e0eb3ff..a559454 100644 --- a/thermal/utils/power_files.cpp +++ b/thermal/utils/power_files.cpp @@ -106,6 +106,10 @@ bool PowerFiles::registerPowerRailsToWatch(std::string_view sensor_name, std::st for (int j = 0; j < power_rail_info.power_sample_count; j++) { power_history[i].emplace(power_sample); } + } else { + LOG(ERROR) << "Could not find power rail " + << power_rail_info.virtual_power_rail_info->linked_power_rails[i]; + return false; } } } else { @@ -114,6 +118,9 @@ bool PowerFiles::registerPowerRailsToWatch(std::string_view sensor_name, std::st for (int j = 0; j < power_rail_info.power_sample_count; j++) { power_history[0].emplace(power_sample); } + } else { + LOG(ERROR) << "Could not find power rail " << power_rail_info.rail; + return false; } } @@ -237,10 +244,14 @@ bool PowerFiles::updateEnergyValues(void) { bool PowerFiles::getAveragePower(std::string_view power_rail, std::queue<PowerSample> *power_history, bool power_sample_update, float *avg_power) { - const auto curr_sample = energy_info_map_.at(power_rail.data()); bool ret = true; - const auto last_sample = power_history->front(); + + if (!energy_info_map_.count(power_rail.data())) { + LOG(ERROR) << " Could not find power rail " << power_rail.data(); + return false; + } + const auto curr_sample = energy_info_map_.at(power_rail.data()); const auto duration = curr_sample.duration - last_sample.duration; const auto deltaEnergy = curr_sample.energy_counter - last_sample.energy_counter; |