Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a3dae23f authored by Yiwei Zhang's avatar Yiwei Zhang
Browse files

GPU Memory: ensure bpf program is attached to the tracepoint

Previously GpuMem is gated upon bpfloader loaded. Recently, bpfloader
gets initialized much earlier which in return makes GpuMem initialize
earlier. However, at that time, the kernel gfx driver may still not get
loaded yet. This change fixes the racing here.

Bug: 159963505
Test: adb shell dumpsys gpu --gpumem
Test: atest gpuservice_unittest:GpuMemTest
Change-Id: If434c205ff3175354d85924075fc1de1e91151f9
Merged-In: If434c205ff3175354d85924075fc1de1e91151f9
parent f3337153
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include <utils/Trace.h>
#include <vkjson.h>

#include <thread>

namespace android {

using base::StringAppendF;
@@ -47,7 +49,8 @@ const char* const GpuService::SERVICE_NAME = "gpu";

GpuService::GpuService()
      : mGpuMem(std::make_unique<GpuMem>()), mGpuStats(std::make_unique<GpuStats>()) {
    mGpuMem->initialize();
    std::thread asyncInitThread([this]() { mGpuMem->initialize(); });
    asyncInitThread.detach();
};

void GpuService::setGpuStats(const std::string& driverPackageName,
+14 −5
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <libbpf.h>
#include <libbpf_android.h>
#include <log/log.h>
#include <unistd.h>
#include <utils/Trace.h>

#include <unordered_map>
@@ -47,12 +48,18 @@ void GpuMem::initialize() {
        return;
    }

    // TODO(http://b/159963505): Figure out a nicer way to wait until GPU driver loaded.
    // Attach the program to the tracepoint, and the tracepoint is automatically enabled here.
    if (bpf_attach_tracepoint(fd, kGpuMemTraceGroup, kGpuMemTotalTracepoint) < 0) {
    int count = 0;
    while (bpf_attach_tracepoint(fd, kGpuMemTraceGroup, kGpuMemTotalTracepoint) < 0) {
        if (++count > kGpuWaitTimeout) {
            ALOGE("Failed to attach bpf program to %s/%s tracepoint", kGpuMemTraceGroup,
                  kGpuMemTotalTracepoint);
            return;
        }
        // Retry until GPU driver loaded or timeout.
        sleep(1);
    }

    // Use the read-only wrapper BpfMapRO to properly retrieve the read-only map.
    auto map = bpf::BpfMapRO<uint64_t, uint64_t>(kGpuMemTotalMapPath);
@@ -61,6 +68,8 @@ void GpuMem::initialize() {
        return;
    }
    setGpuMemTotalMap(map);

    mInitialized.store(true);
}

void GpuMem::setGpuMemTotalMap(bpf::BpfMap<uint64_t, uint64_t>& map) {
@@ -71,7 +80,7 @@ void GpuMem::setGpuMemTotalMap(bpf::BpfMap<uint64_t, uint64_t>& map) {
void GpuMem::dump(const Vector<String16>& /* args */, std::string* result) {
    ATRACE_CALL();

    if (!mGpuMemTotalMap.isValid()) {
    if (!mInitialized.load() || !mGpuMemTotalMap.isValid()) {
        result->append("Failed to initialize GPU memory eBPF\n");
        return;
    }
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ private:
    // set gpu memory total map
    void setGpuMemTotalMap(bpf::BpfMap<uint64_t, uint64_t>& map);

    // indicate whether ebpf has been initialized
    std::atomic<bool> mInitialized = false;
    // bpf map for GPU memory total data
    android::bpf::BpfMap<uint64_t, uint64_t> mGpuMemTotalMap;

@@ -51,6 +53,8 @@ private:
            "/sys/fs/bpf/prog_gpu_mem_tracepoint_gpu_mem_gpu_mem_total";
    // pinned gpu memory total bpf map path in bpf sysfs
    static constexpr char kGpuMemTotalMapPath[] = "/sys/fs/bpf/map_gpu_mem_gpu_mem_total_map";
    // 30 seconds timeout for trying to attach bpf program to tracepoint
    static constexpr int kGpuWaitTimeout = 30;
};

} // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public:

        mGpuMem = std::make_unique<GpuMem>();
        mTestableGpuMem = TestableGpuMem(mGpuMem.get());
        mTestableGpuMem.setInitialized();
        errno = 0;
        mTestMap = bpf::BpfMap<uint64_t, uint64_t>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE,
                                                   BPF_F_NO_PREALLOC);
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ public:
    TestableGpuMem() = default;
    explicit TestableGpuMem(GpuMem *gpuMem) : mGpuMem(gpuMem) {}

    void setInitialized() { mGpuMem->mInitialized.store(true); }

    void setGpuMemTotalMap(bpf::BpfMap<uint64_t, uint64_t>& map) {
        mGpuMem->setGpuMemTotalMap(map);
    }