219 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2021 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #define LOG_TAG "pixelstats: PowerMitigationStats"
 | |
| 
 | |
| #include <aidl/android/frameworks/stats/IStats.h>
 | |
| #include <android-base/file.h>
 | |
| #include <android-base/parseint.h>
 | |
| #include <android-base/properties.h>
 | |
| #include <android-base/stringprintf.h>
 | |
| #include <android-base/strings.h>
 | |
| #include <android/binder_manager.h>
 | |
| #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
 | |
| #include <pixelstats/MitigationStatsReporter.h>
 | |
| #include <utils/Log.h>
 | |
| 
 | |
| namespace android {
 | |
| namespace hardware {
 | |
| namespace google {
 | |
| namespace pixel {
 | |
| 
 | |
| using aidl::android::frameworks::stats::IStats;
 | |
| using aidl::android::frameworks::stats::VendorAtom;
 | |
| using aidl::android::frameworks::stats::VendorAtomValue;
 | |
| using android::base::ReadFileToString;
 | |
| using android::hardware::google::pixel::PixelAtoms::PowerMitigationStats;
 | |
| 
 | |
| MitigationStatsReporter::MitigationStatsReporter() {}
 | |
| 
 | |
| bool MitigationStatsReporter::ReadFileToInt(const std::string &path, int *val) {
 | |
|     std::string file_contents;
 | |
| 
 | |
|     if (!ReadFileToString(path.c_str(), &file_contents)) {
 | |
|         ALOGI("Unable to read %s - %s", path.c_str(), strerror(errno));
 | |
|         return false;
 | |
|     } else {
 | |
|         file_contents = android::base::Trim(file_contents);
 | |
|         if (!android::base::ParseInt(file_contents, val)) {
 | |
|             ALOGI("Unable to convert %s to int - %s", path.c_str(), strerror(errno));
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| void MitigationStatsReporter::logMitigationStatsPerHour(const std::shared_ptr<IStats> &stats_client,
 | |
|                                                         const std::string &path) {
 | |
|     struct MitigationCount last_count = {};
 | |
|     struct MitigationCap last_cap = {};
 | |
| 
 | |
|     if (!logMitigationCount(path, &last_count))
 | |
|         return;
 | |
|     logMitigationCap(path, &last_cap);
 | |
| 
 | |
|     VendorAtomValue tmp;
 | |
|     std::vector<VendorAtomValue> values(24);
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.batoilo_count - prev_count.batoilo_count);
 | |
|     values[PowerMitigationStats::kBatoiloCountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.vdroop1_count - prev_count.vdroop1_count);
 | |
|     values[PowerMitigationStats::kVdroop1CountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.vdroop2_count - prev_count.vdroop2_count);
 | |
|     values[PowerMitigationStats::kVdroop2CountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.smpl_warn_count - prev_count.smpl_warn_count);
 | |
|     values[PowerMitigationStats::kSmplWarnCountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.ocp_cpu1_count - prev_count.ocp_cpu1_count);
 | |
|     values[PowerMitigationStats::kOcpCpu1CountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.ocp_cpu2_count - prev_count.ocp_cpu2_count);
 | |
|     values[PowerMitigationStats::kOcpCpu2CountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.ocp_gpu_count - prev_count.ocp_gpu_count);
 | |
|     values[PowerMitigationStats::kOcpGpuCountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.ocp_tpu_count - prev_count.ocp_tpu_count);
 | |
|     values[PowerMitigationStats::kOcpTpuCountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_cpu1_count -
 | |
|                                        prev_count.soft_ocp_cpu1_count);
 | |
|     values[PowerMitigationStats::kSoftOcpCpu1CountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_cpu2_count -
 | |
|                                        prev_count.soft_ocp_cpu2_count);
 | |
|     values[PowerMitigationStats::kSoftOcpCpu2CountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_gpu_count -
 | |
|                                        prev_count.soft_ocp_gpu_count);
 | |
|     values[PowerMitigationStats::kSoftOcpGpuCountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_count.soft_ocp_tpu_count -
 | |
|                                        prev_count.soft_ocp_tpu_count);
 | |
|     values[PowerMitigationStats::kSoftOcpTpuCountFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.batoilo_cap);
 | |
|     values[PowerMitigationStats::kBatoiloCapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.vdroop1_cap);
 | |
|     values[PowerMitigationStats::kVdroop1CapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.vdroop2_cap);
 | |
|     values[PowerMitigationStats::kVdroop2CapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.smpl_warn_cap);
 | |
|     values[PowerMitigationStats::kSmplWarnCapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.ocp_cpu1_cap);
 | |
|     values[PowerMitigationStats::kOcpCpu1CapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.ocp_cpu2_cap);
 | |
|     values[PowerMitigationStats::kOcpCpu2CapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.ocp_gpu_cap);
 | |
|     values[PowerMitigationStats::kOcpGpuCapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.ocp_tpu_cap);
 | |
|     values[PowerMitigationStats::kOcpTpuCapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_cpu1_cap);
 | |
|     values[PowerMitigationStats::kSoftOcpCpu1CapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_cpu2_cap);
 | |
|     values[PowerMitigationStats::kSoftOcpCpu2CapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_gpu_cap);
 | |
|     values[PowerMitigationStats::kSoftOcpGpuCapFieldNumber - kVendorAtomOffset] = tmp;
 | |
|     tmp.set<VendorAtomValue::intValue>(last_cap.soft_ocp_tpu_cap);
 | |
|     values[PowerMitigationStats::kSoftOcpTpuCapFieldNumber - kVendorAtomOffset] = tmp;
 | |
| 
 | |
|     prev_count = last_count;
 | |
|     // Send vendor atom to IStats HAL
 | |
|     VendorAtom event = {.reverseDomainName = "",
 | |
|                         .atomId = PixelAtoms::Atom::kMitigationStats,
 | |
|                         .values = std::move(values)};
 | |
|     const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
 | |
|     if (!ret.isOk())
 | |
|         ALOGE("Unable to report to Stats service");
 | |
| }
 | |
| 
 | |
| void MitigationStatsReporter::logMitigationCap(const std::string kMitigationDir,
 | |
|                                                struct MitigationCap *last_cap) {
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/batoilo_cap",
 | |
|                   &(last_cap->batoilo_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_cpu1_cap",
 | |
|                   &(last_cap->ocp_cpu1_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_cpu2_cap",
 | |
|                   &(last_cap->ocp_cpu2_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_gpu_cap",
 | |
|                   &(last_cap->ocp_gpu_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/ocp_tpu_cap",
 | |
|                   &(last_cap->ocp_tpu_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/smpl_warn_cap",
 | |
|                   &(last_cap->smpl_warn_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_cpu1_cap",
 | |
|                   &(last_cap->soft_ocp_cpu1_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_cpu2_cap",
 | |
|                   &(last_cap->soft_ocp_cpu2_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_gpu_cap",
 | |
|                   &(last_cap->soft_ocp_gpu_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/soft_ocp_tpu_cap",
 | |
|                   &(last_cap->soft_ocp_tpu_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/vdroop1_cap",
 | |
|                   &(last_cap->vdroop1_cap));
 | |
|     ReadFileToInt(kMitigationDir + "/last_triggered_capacity/vdroop2_cap",
 | |
|                   &(last_cap->vdroop2_cap));
 | |
| }
 | |
| 
 | |
| bool MitigationStatsReporter::logMitigationCount(const std::string kMitigationDir,
 | |
|                                                  struct MitigationCount *last_count) {
 | |
|     bool send_stats = false;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/batoilo_count",
 | |
|                        &(last_count->batoilo_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->batoilo_count - prev_count.batoilo_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_cpu1_count",
 | |
|                        &(last_count->ocp_cpu1_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->ocp_cpu1_count - prev_count.ocp_cpu1_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_cpu2_count",
 | |
|                        &(last_count->ocp_cpu2_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->ocp_cpu2_count - prev_count.ocp_cpu2_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_gpu_count",
 | |
|                        &(last_count->ocp_gpu_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->ocp_gpu_count - prev_count.ocp_gpu_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/ocp_tpu_count",
 | |
|                        &(last_count->ocp_tpu_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->ocp_tpu_count - prev_count.ocp_tpu_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/smpl_warn_count",
 | |
|                        &(last_count->smpl_warn_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->smpl_warn_count - prev_count.smpl_warn_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_cpu1_count",
 | |
|                        &(last_count->soft_ocp_cpu1_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->soft_ocp_cpu1_count - prev_count.soft_ocp_cpu1_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_cpu2_count",
 | |
|                        &(last_count->soft_ocp_cpu2_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->soft_ocp_cpu2_count - prev_count.soft_ocp_cpu2_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_gpu_count",
 | |
|                        &(last_count->soft_ocp_gpu_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->soft_ocp_gpu_count - prev_count.soft_ocp_gpu_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/soft_ocp_tpu_count",
 | |
|                        &(last_count->soft_ocp_tpu_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->soft_ocp_tpu_count - prev_count.soft_ocp_tpu_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/vdroop1_count",
 | |
|                        &(last_count->vdroop1_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->vdroop1_count - prev_count.vdroop1_count) > 0;
 | |
|     if (!ReadFileToInt(kMitigationDir + "/last_triggered_count/vdroop2_count",
 | |
|                        &(last_count->vdroop2_count)))
 | |
|         return false;
 | |
|     send_stats |= (last_count->vdroop2_count - prev_count.vdroop2_count) > 0;
 | |
|     return send_stats;
 | |
| }
 | |
| 
 | |
| }  // namespace pixel
 | |
| }  // namespace google
 | |
| }  // namespace hardware
 | |
| }  // namespace android
 |