aidl: Import gs101 memtrack HAL

From hardware/google/graphics/common @ android-13.0.0_r4

Needs:
aa30f47cf6
ced6904b88
620019f26c

Change-Id: I46ebd21033b7b387503adc835a5d6057bc7c8779
urubino
Tim Zimmermann 2 years ago
parent f302a32df3
commit 1ce96deebe
  1. 34
      aidl/memtrack/core/Android.bp
  2. 59
      aidl/memtrack/core/GpuSysfsReader.cpp
  3. 17
      aidl/memtrack/core/GpuSysfsReader.h
  4. 79
      aidl/memtrack/core/Memtrack.cpp
  5. 70
      aidl/memtrack/core/filesystem.cpp
  6. 60
      aidl/memtrack/core/filesystem.h
  7. 25
      aidl/memtrack/core/include/Memtrack.h
  8. 20
      aidl/memtrack/service/Android.bp
  9. 22
      aidl/memtrack/service/main.cpp
  10. 4
      aidl/memtrack/service/memtrack.rc
  11. 7
      aidl/memtrack/service/memtrack.xml

@ -0,0 +1,34 @@
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_library_shared {
name: "libmemtrack-pixel",
vendor: true,
srcs: [
"Memtrack.cpp",
"GpuSysfsReader.cpp",
"filesystem.cpp",
],
export_include_dirs: [
"include",
],
shared_libs: [
"android.hardware.memtrack-V1-ndk",
"libbase",
"libbinder_ndk",
"liblog",
],
cppflags: [
"-Wall",
"-Werror",
"-Wformat",
"-Wthread-safety",
"-Wunused",
"-Wunreachable-code",
],
visibility: [
"//hardware/google/graphics/common/memtrack-pixel/service:__pkg__"
],
}

@ -0,0 +1,59 @@
#include "GpuSysfsReader.h"
#include <log/log.h>
#include <fstream>
#include <sstream>
#include "filesystem.h"
#undef LOG_TAG
#define LOG_TAG "memtrack-gpusysfsreader"
using namespace GpuSysfsReader;
namespace {
uint64_t readNode(const std::string node, pid_t pid) {
std::stringstream ss;
if (pid)
ss << kSysfsDevicePath << "/" << kProcessDir << "/" << pid << "/" << node;
else
ss << kSysfsDevicePath << "/" << node;
const std::string path = ss.str();
if (!filesystem::exists(filesystem::path(path))) {
ALOGV("File not found: %s", path.c_str());
return 0;
}
std::ifstream file(path.c_str());
if (!file.is_open()) {
ALOGW("Failed to open %s path", path.c_str());
return 0;
}
uint64_t out;
file >> out;
file.close();
return out;
}
} // namespace
uint64_t GpuSysfsReader::getDmaBufGpuMem(pid_t pid) { return readNode(kDmaBufGpuMemNode, pid); }
uint64_t GpuSysfsReader::getGpuMemTotal(pid_t pid) { return readNode(kTotalGpuMemNode, pid); }
uint64_t GpuSysfsReader::getPrivateGpuMem(pid_t pid) {
auto dma_buf_size = getDmaBufGpuMem(pid);
auto gpu_total_size = getGpuMemTotal(pid);
if (dma_buf_size > gpu_total_size) {
ALOGE("Bug in reader, dma-buf size (%" PRIu64 ") is higher than total gpu size (%" PRIu64
")",
dma_buf_size, gpu_total_size);
return 0;
}
return gpu_total_size - dma_buf_size;
}

@ -0,0 +1,17 @@
#pragma once
#include <inttypes.h>
#include <sys/types.h>
namespace GpuSysfsReader {
uint64_t getDmaBufGpuMem(pid_t pid = 0);
uint64_t getGpuMemTotal(pid_t pid = 0);
uint64_t getPrivateGpuMem(pid_t pid = 0);
constexpr char kSysfsDevicePath[] = "/sys/class/misc/mali0/device";
constexpr char kProcessDir[] = "kprcs";
constexpr char kMappedDmaBufsDir[] = "dma_bufs";
constexpr char kTotalGpuMemNode[] = "total_gpu_mem";
constexpr char kDmaBufGpuMemNode[] = "dma_buf_gpu_mem";
} // namespace GpuSysfsReader

@ -0,0 +1,79 @@
#include <Memtrack.h>
#include <stdlib.h>
#include <sstream>
#include <string>
#include <vector>
#include "GpuSysfsReader.h"
#include "filesystem.h"
#undef LOG_TAG
#define LOG_TAG "memtrack-core"
namespace aidl {
namespace android {
namespace hardware {
namespace memtrack {
ndk::ScopedAStatus Memtrack::getMemory(int pid, MemtrackType type,
std::vector<MemtrackRecord>* _aidl_return) {
if (pid < 0)
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
if (type != MemtrackType::OTHER && type != MemtrackType::GL && type != MemtrackType::GRAPHICS &&
type != MemtrackType::MULTIMEDIA && type != MemtrackType::CAMERA)
return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
_aidl_return->clear();
// Other types are retained only for backward compatibility
if (type != MemtrackType::GL && type != MemtrackType::GRAPHICS)
return ndk::ScopedAStatus::ok();
// pid 0 is only supported for GL type to report total private memory
if (pid == 0 && type != MemtrackType::GL)
return ndk::ScopedAStatus::ok();
uint64_t size = 0;
switch (type) {
case MemtrackType::GL:
size = GpuSysfsReader::getPrivateGpuMem(pid);
break;
case MemtrackType::GRAPHICS:
// TODO(b/194483693): This is not PSS as required by memtrack HAL
// but complete dmabuf allocations. Reporting PSS requires reading
// procfs. This HAL does not have that permission yet.
size = GpuSysfsReader::getDmaBufGpuMem(pid);
break;
default:
break;
}
MemtrackRecord record = {
.flags = MemtrackRecord::FLAG_SMAPS_UNACCOUNTED,
.sizeInBytes = static_cast<long>(size),
};
_aidl_return->emplace_back(record);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Memtrack::getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) {
auto devPath = filesystem::path(GpuSysfsReader::kSysfsDevicePath);
std::string devName = "default-gpu";
if (filesystem::exists(devPath) && filesystem::is_symlink(devPath)) {
devName = filesystem::read_symlink(devPath).filename().string();
}
DeviceInfo dev_info = {.id = 0, .name = devName};
_aidl_return->clear();
_aidl_return->emplace_back(dev_info);
return ndk::ScopedAStatus::ok();
}
} // namespace memtrack
} // namespace hardware
} // namespace android
} // namespace aidl

@ -0,0 +1,70 @@
#include "filesystem.h"
#include <dirent.h>
#include <log/log.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sstream>
#include <string>
#include <vector>
namespace filesystem {
bool exists(const path& p) {
struct stat s;
return stat(p.string().c_str(), &s) == 0;
}
bool is_directory(const path& p) {
struct stat s;
if (stat(p.string().c_str(), &s))
return false;
return S_ISDIR(s.st_mode);
}
bool is_symlink(const path& p) {
struct stat s;
if (lstat(p.string().c_str(), &s))
return false;
return S_ISLNK(s.st_mode);
}
path read_symlink(const path& p) {
char* actualPath = realpath(p.string().c_str(), NULL);
if (!actualPath) {
return path(p.string());
}
path out(actualPath);
free(actualPath);
return out;
}
std::vector<directory_entry> directory_iterator(const path& p) {
if (!exists(p) || !is_directory(p))
return {};
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(p.string().c_str()), &closedir);
if (!dir) {
ALOGE("Failed to open %s directory", p.string().c_str());
}
std::vector<directory_entry> out;
struct dirent* dent;
while ((dent = readdir(dir.get()))) {
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
continue;
std::stringstream ss(p.string());
ss << "/" << dent->d_name;
out.emplace_back(ss.str());
}
return out;
}
} // namespace filesystem

@ -0,0 +1,60 @@
// TODO(b/147469372): filesystem library in Android's libcxx is not available
// for vendors. It had an unstable ABI and libcxx isn't updated ever since.
// This simply implements some of the required functions in not-so-safe fashion.
#pragma once
#include <dirent.h>
#include <log/log.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string>
#include <vector>
namespace filesystem {
class path {
public:
path(const std::string _path) : strPath(_path) {}
path filename() const {
auto pos = strPath.rfind('/');
if (pos == std::string::npos)
return path(strPath);
pos++;
auto l = strPath.size();
return path(strPath.substr(pos, l - pos));
}
std::string string() const { return strPath; }
private:
std::string strPath;
};
class directory_entry {
public:
directory_entry(const std::string _path) : p(_path) {}
class path path() {
return p;
}
private:
class path p;
};
bool exists(const path& p);
bool is_directory(const path& p);
bool is_symlink(const path& p);
path read_symlink(const path& p);
// Vector is easier to create than an iterator and serves our purposes well
std::vector<directory_entry> directory_iterator(const path& p);
} // namespace filesystem

@ -0,0 +1,25 @@
#pragma once
#include <aidl/android/hardware/memtrack/BnMemtrack.h>
#include <aidl/android/hardware/memtrack/DeviceInfo.h>
#include <aidl/android/hardware/memtrack/MemtrackRecord.h>
#include <aidl/android/hardware/memtrack/MemtrackType.h>
namespace aidl {
namespace android {
namespace hardware {
namespace memtrack {
class Memtrack : public BnMemtrack {
public:
ndk::ScopedAStatus getMemory(int pid, MemtrackType type,
std::vector<MemtrackRecord>* _aidl_return) override;
ndk::ScopedAStatus getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) override;
};
} // namespace memtrack
} // namespace hardware
} // namespace android
} // namespace aidl

@ -0,0 +1,20 @@
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_binary {
name: "android.hardware.memtrack-service.pixel",
relative_install_path: "hw",
init_rc: ["memtrack.rc"],
vintf_fragments: ["memtrack.xml"],
vendor: true,
shared_libs: [
"android.hardware.memtrack-V1-ndk",
"libbase",
"libbinder_ndk",
"libmemtrack-pixel",
],
srcs: [
"main.cpp",
],
}

@ -0,0 +1,22 @@
#include <Memtrack.h>
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#undef LOG_TAG
#define LOG_TAG "memtrack-service"
using aidl::android::hardware::memtrack::Memtrack;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<Memtrack> memtrack = ndk::SharedRefBase::make<Memtrack>();
const std::string instance = std::string() + Memtrack::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(memtrack->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // Unreachable
}

@ -0,0 +1,4 @@
service vendor.memtrack-default /vendor/bin/hw/android.hardware.memtrack-service.pixel
class hal
user graphics
group system

@ -0,0 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.memtrack</name>
<fqname>IMemtrack/default</fqname>
</hal>
</manifest>
Loading…
Cancel
Save