pixelstats: Add a listener for GPU uevents
The GPU driver (mali) can send uevents with GPU_UEVENT_TYPE and
GPU_UEVENT_INFO env. Report these from pixelstats.
Bug: 275367216
Bug: 276704984
Change-Id: I550ab58f426fe2961c3b3f5935df2c420005fde8
Signed-off-by: Varad Gautam <varadgautam@google.com>
Test: b/276704984
diff --git a/pixelstats/UeventListener.cpp b/pixelstats/UeventListener.cpp
index 07c8c95..8af43a0 100644
--- a/pixelstats/UeventListener.cpp
+++ b/pixelstats/UeventListener.cpp
@@ -66,6 +66,7 @@
using android::sp;
using android::base::ReadFileToString;
using android::base::WriteStringToFile;
+using android::hardware::google::pixel::PixelAtoms::GpuEvent;
using android::hardware::google::pixel::PixelAtoms::PdVidPid;
using android::hardware::google::pixel::PixelAtoms::VendorHardwareFailed;
using android::hardware::google::pixel::PixelAtoms::VendorUsbPortOverheat;
@@ -271,6 +272,34 @@
}
}
+void UeventListener::ReportGpuEvent(const std::shared_ptr<IStats> &stats_client, const char *driver,
+ const char *gpu_event_type, const char *gpu_event_info) {
+ if (!stats_client || !driver || strncmp(driver, "DRIVER=mali", strlen("DRIVER=mali")) ||
+ !gpu_event_type || !gpu_event_info)
+ return;
+
+ std::vector<std::string> type = android::base::Split(gpu_event_type, "=");
+ std::vector<std::string> info = android::base::Split(gpu_event_info, "=");
+
+ if (type.size() != 2 || info.size() != 2)
+ return;
+
+ if (type[0] != "GPU_UEVENT_TYPE" || info[0] != "GPU_UEVENT_INFO")
+ return;
+
+ auto event_type = kGpuEventTypeStrToEnum.find(type[1]);
+ auto event_info = kGpuEventInfoStrToEnum.find(info[1]);
+ if (event_type == kGpuEventTypeStrToEnum.end() || event_info == kGpuEventInfoStrToEnum.end())
+ return;
+
+ VendorAtom event = {.reverseDomainName = "",
+ .atomId = PixelAtoms::Atom::kGpuEvent,
+ .values = {event_type->second, event_info->second}};
+ const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
+ if (!ret.isOk())
+ ALOGE("Unable to report GPU event.");
+}
+
bool UeventListener::ProcessUevent() {
char msg[UEVENT_MSG_LEN + 2];
char *cp;
@@ -278,6 +307,7 @@
const char *mic_break_status, *mic_degrade_status;
const char *devpath;
bool collect_partner_id = false;
+ const char *gpu_event_type = nullptr, *gpu_event_info = nullptr;
int n;
if (uevent_fd_ < 0) {
@@ -333,6 +363,10 @@
subsystem = cp;
} else if (!strncmp(cp, kTypeCPartnerUevent.c_str(), kTypeCPartnerUevent.size())) {
collect_partner_id = true;
+ } else if (!strncmp(cp, "GPU_UEVENT_TYPE=", strlen("GPU_UEVENT_TYPE="))) {
+ gpu_event_type = cp;
+ } else if (!strncmp(cp, "GPU_UEVENT_INFO=", strlen("GPU_UEVENT_INFO="))) {
+ gpu_event_info = cp;
}
/* advance to after the next \0 */
while (*cp++) {
@@ -352,6 +386,7 @@
if (collect_partner_id) {
ReportTypeCPartnerId(stats_client);
}
+ ReportGpuEvent(stats_client, driver, gpu_event_type, gpu_event_info);
}
if (log_fd_ > 0) {
diff --git a/pixelstats/include/pixelstats/UeventListener.h b/pixelstats/include/pixelstats/UeventListener.h
index 5316afa..352beb8 100644
--- a/pixelstats/include/pixelstats/UeventListener.h
+++ b/pixelstats/include/pixelstats/UeventListener.h
@@ -88,6 +88,8 @@
void ReportBatteryCapacityFGEvent(const std::shared_ptr<IStats> &stats_client,
const char *subsystem);
void ReportTypeCPartnerId(const std::shared_ptr<IStats> &stats_client);
+ void ReportGpuEvent(const std::shared_ptr<IStats> &stats_client, const char *driver,
+ const char *gpu_event_type, const char *gpu_event_info);
const std::string kAudioUevent;
const std::string kBatterySSOCPath;
@@ -97,6 +99,47 @@
const std::string kTypeCPartnerVidPath;
const std::string kTypeCPartnerPidPath;
+ const std::unordered_map<std::string, PixelAtoms::GpuEvent::GpuEventType>
+ kGpuEventTypeStrToEnum{
+ {"KMD_ERROR",
+ PixelAtoms::GpuEvent::GpuEventType::GpuEvent_GpuEventType_MALI_KMD_ERROR},
+ {"GPU_RESET",
+ PixelAtoms::GpuEvent::GpuEventType::GpuEvent_GpuEventType_MALI_GPU_RESET}};
+
+ const std::unordered_map<std::string, PixelAtoms::GpuEvent::GpuEventInfo>
+ kGpuEventInfoStrToEnum{
+ {"CSG_REQ_STATUS_UPDATE",
+ PixelAtoms::GpuEvent::GpuEventInfo::
+ GpuEvent_GpuEventInfo_MALI_CSG_REQ_STATUS_UPDATE},
+ {"CSG_SUSPEND",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_CSG_SUSPEND},
+ {"CSG_SLOTS_SUSPEND", PixelAtoms::GpuEvent::GpuEventInfo::
+ GpuEvent_GpuEventInfo_MALI_CSG_SLOTS_SUSPEND},
+ {"CSG_GROUP_SUSPEND", PixelAtoms::GpuEvent::GpuEventInfo::
+ GpuEvent_GpuEventInfo_MALI_CSG_GROUP_SUSPEND},
+ {"CSG_EP_CFG",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_CSG_EP_CFG},
+ {"CSG_SLOTS_START", PixelAtoms::GpuEvent::GpuEventInfo::
+ GpuEvent_GpuEventInfo_MALI_CSG_SLOTS_START},
+ {"GROUP_TERM",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_GROUP_TERM},
+ {"QUEUE_START",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_QUEUE_START},
+ {"QUEUE_STOP",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_QUEUE_STOP},
+ {"QUEUE_STOP_ACK",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_QUEUE_STOP_ACK},
+ {"CSG_SLOT_READY",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_CSG_SLOT_READY},
+ {"L2_PM_TIMEOUT",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_L2_PM_TIMEOUT},
+ {"PM_TIMEOUT",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_PM_TIMEOUT},
+ {"CSF_RESET_OK",
+ PixelAtoms::GpuEvent::GpuEventInfo::GpuEvent_GpuEventInfo_MALI_CSF_RESET_OK},
+ {"CSF_RESET_FAILED", PixelAtoms::GpuEvent::GpuEventInfo::
+ GpuEvent_GpuEventInfo_MALI_CSF_RESET_FAILED}};
+
BatteryCapacityReporter battery_capacity_reporter_;
ChargeStatsReporter charge_stats_reporter_;