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

Commit c4b46e0a authored by Yifan Hong's avatar Yifan Hong
Browse files

storaged: use health HAL to read DiskStats.

Test: storaged unit tests
Bug: 68388678
Change-Id: I03ce3aa71fb54ae40489c7b35973cd4b83b13bfb
parent 4a43bdc5
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -103,7 +103,10 @@ cc_test {

    srcs: ["tests/storaged_test.cpp"],

    static_libs: ["libstoraged"],
    static_libs: [
        "libhealthhalutils",
        "libstoraged",
    ],
}

// AIDL interface between storaged and framework.jar
+1 −1
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ class storaged_t : public android::hardware::health::V2_0::IHealthInfoCallback,
  private:
    time_t mTimer;
    storaged_config mConfig;
    disk_stats_monitor mDsm;
    unique_ptr<disk_stats_monitor> mDsm;
    uid_monitor mUidm;
    time_t mStarttime;
    sp<android::hardware::health::V2_0::IHealth> health;
+25 −16
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@

#include <stdint.h>

#include <android/hardware/health/2.0/IHealth.h>

// number of attributes diskstats has
#define DISK_STATS_SIZE ( 11 )

@@ -160,6 +162,7 @@ private:
    const double mSigma;
    struct disk_perf mMean;
    struct disk_perf mStd;
    android::sp<android::hardware::health::V2_0::IHealth> mHealth;

    void update_mean();
    void update_std();
@@ -170,19 +173,25 @@ private:
    void update(struct disk_stats* stats);

public:
    disk_stats_monitor(uint32_t window_size = 5, double sigma = 1.0) :
        DISK_STATS_PATH(access(MMC_DISK_STATS_PATH, R_OK) ?
                            (access(SDA_DISK_STATS_PATH, R_OK) ?
                                nullptr :
                                SDA_DISK_STATS_PATH) :
                            MMC_DISK_STATS_PATH),
        mPrevious(), mAccumulate(), mAccumulate_pub(),
        mStall(false), mValid(false),
        mWindow(window_size), mSigma(sigma),
        mMean(), mStd() {}
    bool enabled() {
        return DISK_STATS_PATH != nullptr;
    }
  disk_stats_monitor(const android::sp<android::hardware::health::V2_0::IHealth>& healthService,
                     uint32_t window_size = 5, double sigma = 1.0)
      : DISK_STATS_PATH(
            healthService != nullptr
                ? nullptr
                : (access(MMC_DISK_STATS_PATH, R_OK) == 0
                       ? MMC_DISK_STATS_PATH
                       : (access(SDA_DISK_STATS_PATH, R_OK) == 0 ? SDA_DISK_STATS_PATH : nullptr))),
        mPrevious(),
        mAccumulate(),
        mAccumulate_pub(),
        mStall(false),
        mValid(false),
        mWindow(window_size),
        mSigma(sigma),
        mMean(),
        mStd(),
        mHealth(healthService) {}
  bool enabled() { return mHealth != nullptr || DISK_STATS_PATH != nullptr; }
  void update(void);
  void publish(void);
};
+4 −3
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ Return<void> storaged_t::healthInfoChanged(const HealthInfo& props) {

void storaged_t::init() {
    init_health_service();
    mDsm = std::make_unique<disk_stats_monitor>(health);
}

void storaged_t::init_health_service() {
@@ -311,10 +312,10 @@ void storaged_t::flush_protos(unordered_map<int, StoragedProto>* protos) {
void storaged_t::event(void) {
    unordered_map<int, StoragedProto> protos;

    if (mDsm.enabled()) {
        mDsm.update();
    if (mDsm->enabled()) {
        mDsm->update();
        if (!(mTimer % mConfig.periodic_chores_interval_disk_stats_publish)) {
            mDsm.publish();
            mDsm->publish();
        }
    }

+78 −12
Original line number Diff line number Diff line
@@ -30,6 +30,12 @@

namespace {

using android::sp;
using android::hardware::health::V2_0::DiskStats;
using android::hardware::health::V2_0::IHealth;
using android::hardware::health::V2_0::Result;
using android::hardware::health::V2_0::toString;

#ifdef DEBUG
void log_debug_disk_perf(struct disk_perf* perf, const char* type) {
    // skip if the input structure are all zeros
@@ -60,17 +66,30 @@ void log_event_disk_stats(struct disk_stats* stats, const char* type) {

} // namespace

bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats)
{
    // Get time
    struct timespec ts;
bool get_time(struct timespec* ts) {
    // Use monotonic to exclude suspend time so that we measure IO bytes/sec
    // when system is running.
    int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
    int ret = clock_gettime(CLOCK_MONOTONIC, ts);
    if (ret < 0) {
        PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
        return false;
    }
    return true;
}

void init_disk_stats_other(const struct timespec& ts, struct disk_stats* stats) {
    stats->start_time = 0;
    stats->end_time = (uint64_t)ts.tv_sec * SEC_TO_MSEC + ts.tv_nsec / (MSEC_TO_USEC * USEC_TO_NSEC);
    stats->counter = 1;
    stats->io_avg = (double)stats->io_in_flight;
}

bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) {
    // Get time
    struct timespec ts;
    if (!get_time(&ts)) {
        return false;
    }

    std::string buffer;
    if (!android::base::ReadFileToString(disk_stats_path, &buffer)) {
@@ -84,11 +103,52 @@ bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats)
        ss >> *((uint64_t*)stats + i);
    }
    // Other entries
    stats->start_time = 0;
    stats->end_time = (uint64_t)ts.tv_sec * SEC_TO_MSEC +
        ts.tv_nsec / (MSEC_TO_USEC * USEC_TO_NSEC);
    stats->counter = 1;
    stats->io_avg = (double)stats->io_in_flight;
    init_disk_stats_other(ts, stats);
    return true;
}

void convert_hal_disk_stats(struct disk_stats* dst, const DiskStats& src) {
    dst->read_ios = src.reads;
    dst->read_merges = src.readMerges;
    dst->read_sectors = src.readSectors;
    dst->read_ticks = src.readTicks;
    dst->write_ios = src.writes;
    dst->write_merges = src.writeMerges;
    dst->write_sectors = src.writeSectors;
    dst->write_ticks = src.writeTicks;
    dst->io_in_flight = src.ioInFlight;
    dst->io_ticks = src.ioTicks;
    dst->io_in_queue = src.ioInQueue;
}

bool get_disk_stats_from_health_hal(const sp<IHealth>& service, struct disk_stats* stats) {
    struct timespec ts;
    if (!get_time(&ts)) {
        return false;
    }

    bool success = false;
    auto ret = service->getDiskStats([&success, stats](auto result, const auto& halStats) {
        if (result != Result::SUCCESS || halStats.size() == 0) {
            LOG_TO(SYSTEM, ERROR) << "getDiskStats failed with result " << toString(result)
                                  << " and size " << halStats.size();
            return;
        }

        convert_hal_disk_stats(stats, halStats[0]);
        success = true;
    });

    if (!ret.isOk()) {
        LOG_TO(SYSTEM, ERROR) << "getDiskStats failed with " << ret.description();
        return false;
    }

    if (!success) {
        return false;
    }

    init_disk_stats_other(ts, stats);
    return true;
}

@@ -243,9 +303,15 @@ void disk_stats_monitor::update(struct disk_stats* curr)

void disk_stats_monitor::update() {
    disk_stats curr;
    if (mHealth != nullptr) {
        if (!get_disk_stats_from_health_hal(mHealth, &curr)) {
            return;
        }
    } else {
        if (!parse_disk_stats(DISK_STATS_PATH, &curr)) {
            return;
        }
    }

    update(&curr);
}
Loading