Loading services/gpuservice/gpumem/GpuMem.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <libbpf_android.h> #include <log/log.h> #include <unistd.h> #include <utils/Timers.h> #include <utils/Trace.h> #include <unordered_map> Loading Loading @@ -128,4 +129,24 @@ void GpuMem::dump(const Vector<String16>& /* args */, std::string* result) { } } void GpuMem::traverseGpuMemTotals(const std::function<void(int64_t ts, uint32_t gpuId, uint32_t pid, uint64_t size)>& callback) { auto res = mGpuMemTotalMap.getFirstKey(); if (!res.ok()) return; uint64_t key = res.value(); while (true) { uint32_t gpu_id = key >> 32; uint32_t pid = key; res = mGpuMemTotalMap.readValue(key); if (!res.ok()) break; uint64_t size = res.value(); callback(systemTime(), gpu_id, pid, size); res = mGpuMemTotalMap.getNextKey(key); if (!res.ok()) break; key = res.value(); } } } // namespace android services/gpuservice/gpumem/include/gpumem/GpuMem.h +5 −21 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <utils/String16.h> #include <utils/Vector.h> #include <functional> namespace android { class GpuMem { Loading @@ -33,27 +35,9 @@ public: void dump(const Vector<String16>& args, std::string* result); bool isInitialized() { return mInitialized.load(); } // Traverse the map and send each value read back to the callback function. // Used for tracing. template <typename lambda> void traceGpuMemTotals(lambda tracerCallback) { auto res = mGpuMemTotalMap.getFirstKey(); if (!res.ok()) return; uint64_t key = res.value(); while (true) { uint32_t gpu_id = key >> 32; uint32_t pid = key; res = mGpuMemTotalMap.readValue(key); if (!res.ok()) break; uint64_t size = res.value(); tracerCallback(gpu_id, pid, size); res = mGpuMemTotalMap.getNextKey(key); if (!res.ok()) break; key = res.value(); } } // Traverse the gpu memory total map to feed the callback function. void traverseGpuMemTotals(const std::function<void(int64_t ts, uint32_t gpuId, uint32_t pid, uint64_t size)>& callback); private: // Friend class for testing. Loading services/gpuservice/tests/unittests/GpuMemTest.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ constexpr uint64_t TEST_PROC_KEY_1 = 1; constexpr uint64_t TEST_PROC_VAL_1 = 234; constexpr uint64_t TEST_PROC_KEY_2 = 4294967298; // (1 << 32) + 2 constexpr uint64_t TEST_PROC_VAL_2 = 345; constexpr uint32_t TEST_KEY_MASK = 0x1 | 0x2 | 0x4; constexpr uint32_t TEST_KEY_COUNT = 3; class GpuMemTest : public testing::Test { public: Loading Loading @@ -143,5 +145,37 @@ TEST_F(GpuMemTest, procMemTotal) { TEST_PROC_VAL_2))); } TEST_F(GpuMemTest, traverseGpuMemTotals) { SKIP_IF_BPF_NOT_SUPPORTED; ASSERT_RESULT_OK(mTestMap.writeValue(TEST_GLOBAL_KEY, TEST_GLOBAL_VAL, BPF_ANY)); ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_1, TEST_PROC_VAL_1, BPF_ANY)); ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_2, TEST_PROC_VAL_2, BPF_ANY)); mTestableGpuMem.setGpuMemTotalMap(mTestMap); static uint32_t sMask = 0; static uint32_t sCount = 0; mGpuMem->traverseGpuMemTotals([](int64_t, uint32_t gpuId, uint32_t pid, uint64_t size) { const uint64_t key = ((uint64_t)gpuId << 32) | pid; switch (key) { case TEST_GLOBAL_KEY: EXPECT_EQ(size, TEST_GLOBAL_VAL); sMask |= 0x1; break; case TEST_PROC_KEY_1: EXPECT_EQ(size, TEST_PROC_VAL_1); sMask |= 0x2; break; case TEST_PROC_KEY_2: EXPECT_EQ(size, TEST_PROC_VAL_2); sMask |= 0x4; break; } sCount++; }); EXPECT_EQ(sMask, TEST_KEY_MASK); EXPECT_EQ(sCount, TEST_KEY_COUNT); } } // namespace } // namespace android services/gpuservice/tracing/GpuMemTracer.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -23,9 +23,7 @@ #include <gpumem/GpuMem.h> #include <perfetto/trace/android/gpu_mem_event.pbzero.h> #include <unistd.h> #include <utils/Timers.h> #include <algorithm> #include <thread> PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(android::GpuMemTracer::GpuMemDataSource); Loading Loading @@ -79,10 +77,10 @@ void GpuMemTracer::traceInitialCounters() { ALOGE("Cannot trace without GpuMem initialization"); return; } mGpuMem->traceGpuMemTotals([](uint32_t gpuId, uint32_t pid, uint64_t size) { mGpuMem->traverseGpuMemTotals([](int64_t ts, uint32_t gpuId, uint32_t pid, uint64_t size) { GpuMemDataSource::Trace([&](GpuMemDataSource::TraceContext ctx) { auto packet = ctx.NewTracePacket(); packet->set_timestamp(systemTime()); packet->set_timestamp(ts); auto* event = packet->set_gpu_mem_total_event(); event->set_gpu_id(gpuId); event->set_pid(pid); Loading Loading
services/gpuservice/gpumem/GpuMem.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <libbpf_android.h> #include <log/log.h> #include <unistd.h> #include <utils/Timers.h> #include <utils/Trace.h> #include <unordered_map> Loading Loading @@ -128,4 +129,24 @@ void GpuMem::dump(const Vector<String16>& /* args */, std::string* result) { } } void GpuMem::traverseGpuMemTotals(const std::function<void(int64_t ts, uint32_t gpuId, uint32_t pid, uint64_t size)>& callback) { auto res = mGpuMemTotalMap.getFirstKey(); if (!res.ok()) return; uint64_t key = res.value(); while (true) { uint32_t gpu_id = key >> 32; uint32_t pid = key; res = mGpuMemTotalMap.readValue(key); if (!res.ok()) break; uint64_t size = res.value(); callback(systemTime(), gpu_id, pid, size); res = mGpuMemTotalMap.getNextKey(key); if (!res.ok()) break; key = res.value(); } } } // namespace android
services/gpuservice/gpumem/include/gpumem/GpuMem.h +5 −21 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <utils/String16.h> #include <utils/Vector.h> #include <functional> namespace android { class GpuMem { Loading @@ -33,27 +35,9 @@ public: void dump(const Vector<String16>& args, std::string* result); bool isInitialized() { return mInitialized.load(); } // Traverse the map and send each value read back to the callback function. // Used for tracing. template <typename lambda> void traceGpuMemTotals(lambda tracerCallback) { auto res = mGpuMemTotalMap.getFirstKey(); if (!res.ok()) return; uint64_t key = res.value(); while (true) { uint32_t gpu_id = key >> 32; uint32_t pid = key; res = mGpuMemTotalMap.readValue(key); if (!res.ok()) break; uint64_t size = res.value(); tracerCallback(gpu_id, pid, size); res = mGpuMemTotalMap.getNextKey(key); if (!res.ok()) break; key = res.value(); } } // Traverse the gpu memory total map to feed the callback function. void traverseGpuMemTotals(const std::function<void(int64_t ts, uint32_t gpuId, uint32_t pid, uint64_t size)>& callback); private: // Friend class for testing. Loading
services/gpuservice/tests/unittests/GpuMemTest.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ constexpr uint64_t TEST_PROC_KEY_1 = 1; constexpr uint64_t TEST_PROC_VAL_1 = 234; constexpr uint64_t TEST_PROC_KEY_2 = 4294967298; // (1 << 32) + 2 constexpr uint64_t TEST_PROC_VAL_2 = 345; constexpr uint32_t TEST_KEY_MASK = 0x1 | 0x2 | 0x4; constexpr uint32_t TEST_KEY_COUNT = 3; class GpuMemTest : public testing::Test { public: Loading Loading @@ -143,5 +145,37 @@ TEST_F(GpuMemTest, procMemTotal) { TEST_PROC_VAL_2))); } TEST_F(GpuMemTest, traverseGpuMemTotals) { SKIP_IF_BPF_NOT_SUPPORTED; ASSERT_RESULT_OK(mTestMap.writeValue(TEST_GLOBAL_KEY, TEST_GLOBAL_VAL, BPF_ANY)); ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_1, TEST_PROC_VAL_1, BPF_ANY)); ASSERT_RESULT_OK(mTestMap.writeValue(TEST_PROC_KEY_2, TEST_PROC_VAL_2, BPF_ANY)); mTestableGpuMem.setGpuMemTotalMap(mTestMap); static uint32_t sMask = 0; static uint32_t sCount = 0; mGpuMem->traverseGpuMemTotals([](int64_t, uint32_t gpuId, uint32_t pid, uint64_t size) { const uint64_t key = ((uint64_t)gpuId << 32) | pid; switch (key) { case TEST_GLOBAL_KEY: EXPECT_EQ(size, TEST_GLOBAL_VAL); sMask |= 0x1; break; case TEST_PROC_KEY_1: EXPECT_EQ(size, TEST_PROC_VAL_1); sMask |= 0x2; break; case TEST_PROC_KEY_2: EXPECT_EQ(size, TEST_PROC_VAL_2); sMask |= 0x4; break; } sCount++; }); EXPECT_EQ(sMask, TEST_KEY_MASK); EXPECT_EQ(sCount, TEST_KEY_COUNT); } } // namespace } // namespace android
services/gpuservice/tracing/GpuMemTracer.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -23,9 +23,7 @@ #include <gpumem/GpuMem.h> #include <perfetto/trace/android/gpu_mem_event.pbzero.h> #include <unistd.h> #include <utils/Timers.h> #include <algorithm> #include <thread> PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(android::GpuMemTracer::GpuMemDataSource); Loading Loading @@ -79,10 +77,10 @@ void GpuMemTracer::traceInitialCounters() { ALOGE("Cannot trace without GpuMem initialization"); return; } mGpuMem->traceGpuMemTotals([](uint32_t gpuId, uint32_t pid, uint64_t size) { mGpuMem->traverseGpuMemTotals([](int64_t ts, uint32_t gpuId, uint32_t pid, uint64_t size) { GpuMemDataSource::Trace([&](GpuMemDataSource::TraceContext ctx) { auto packet = ctx.NewTracePacket(); packet->set_timestamp(systemTime()); packet->set_timestamp(ts); auto* event = packet->set_gpu_mem_total_event(); event->set_gpu_id(gpuId); event->set_pid(pid); Loading