summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rafal Slawik <rslawik@google.com> 2021-01-29 12:25:56 +0000
committer Rafal Slawik <rslawik@google.com> 2021-01-29 12:25:56 +0000
commit45caa84d2d7d55e6fa74f66cfe30c0169a8cc38d (patch)
treeb88c20dac6112e2736c6afebe691d5325e375edc
parent21474550bc37ccb8524dc49c702b1f735376f5eb (diff)
Check if CPU time tracking is expected to work
This check will allow statsd to decide whether it should add a puller for total CPU time tracking. Reading total CPU time on devices that does not support CPU time tracking is wasteful, passing all zero times around and recording "no data" state. Bug: 174245730 Test: atest libtimeinstate_test Test: cmd stats pull-source 10095 Change-Id: Ib6155af4cbd6c639d356118934237d7dfd76b3a8
-rw-r--r--libs/cputimeinstate/cputimeinstate.cpp19
-rw-r--r--libs/cputimeinstate/cputimeinstate.h1
-rw-r--r--libs/cputimeinstate/testtimeinstate.cpp5
3 files changed, 23 insertions, 2 deletions
diff --git a/libs/cputimeinstate/cputimeinstate.cpp b/libs/cputimeinstate/cputimeinstate.cpp
index 462f0db97b..7e9bb7d468 100644
--- a/libs/cputimeinstate/cputimeinstate.cpp
+++ b/libs/cputimeinstate/cputimeinstate.cpp
@@ -155,10 +155,14 @@ static bool initGlobals() {
return true;
}
-static bool attachTracepointProgram(const std::string &eventType, const std::string &eventName) {
+static int retrieveProgramFd(const std::string &eventType, const std::string &eventName) {
std::string path = StringPrintf(BPF_FS_PATH "prog_time_in_state_tracepoint_%s_%s",
eventType.c_str(), eventName.c_str());
- int prog_fd = retrieveProgram(path.c_str());
+ return retrieveProgram(path.c_str());
+}
+
+static bool attachTracepointProgram(const std::string &eventType, const std::string &eventName) {
+ int prog_fd = retrieveProgramFd(eventType, eventName);
if (prog_fd < 0) return false;
return bpf_attach_tracepoint(prog_fd, eventType.c_str(), eventName.c_str()) >= 0;
}
@@ -174,6 +178,17 @@ static std::optional<uint32_t> getPolicyFreqIdx(uint32_t policy) {
return {};
}
+// Check if tracking is expected to work without activating it.
+bool isTrackingUidTimesSupported() {
+ auto freqs = getCpuFreqs();
+ if (!freqs || freqs->empty()) return false;
+ if (gTracking) return true;
+ if (retrieveProgramFd("sched", "sched_switch") < 0) return false;
+ if (retrieveProgramFd("power", "cpu_frequency") < 0) return false;
+ if (retrieveProgramFd("sched", "sched_process_free") < 0) return false;
+ return true;
+}
+
// Start tracking and aggregating data to be reported by getUidCpuFreqTimes and getUidsCpuFreqTimes.
// Returns true on success, false otherwise.
// Tracking is active only once a live process has successfully called this function; if the calling
diff --git a/libs/cputimeinstate/cputimeinstate.h b/libs/cputimeinstate/cputimeinstate.h
index 46de66936a..41453745a0 100644
--- a/libs/cputimeinstate/cputimeinstate.h
+++ b/libs/cputimeinstate/cputimeinstate.h
@@ -22,6 +22,7 @@
namespace android {
namespace bpf {
+bool isTrackingUidTimesSupported();
bool startTrackingUidTimes();
std::optional<std::vector<std::vector<uint64_t>>> getTotalCpuFreqTimes();
std::optional<std::vector<std::vector<uint64_t>>> getUidCpuFreqTimes(uint32_t uid);
diff --git a/libs/cputimeinstate/testtimeinstate.cpp b/libs/cputimeinstate/testtimeinstate.cpp
index d25b2e9d6f..2112b10ebc 100644
--- a/libs/cputimeinstate/testtimeinstate.cpp
+++ b/libs/cputimeinstate/testtimeinstate.cpp
@@ -40,6 +40,11 @@ static constexpr uint64_t NSEC_PER_YEAR = NSEC_PER_SEC * 60 * 60 * 24 * 365;
using std::vector;
+TEST(TimeInStateTest, IsTrackingSupported) {
+ isTrackingUidTimesSupported();
+ SUCCEED();
+}
+
TEST(TimeInStateTest, TotalTimeInState) {
auto times = getTotalCpuFreqTimes();
ASSERT_TRUE(times.has_value());