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

Commit 94b64ef3 authored by Jin Qian's avatar Jin Qian
Browse files

storaged: remove protos from storaged class

protobuf is only needed when serializing/deserializing data. Instead of
maintaining a permanent buffer in storaged object, move the container to
stack so that the buffer is released when we don't need it. In addition,
we don't need to clear the buffer before updating it.

Also added a function to clear user io history when the user is removed.

Bug: 63740245
Change-Id: Ia5d19b9a0c3f92a93b061a56be89bb0b958a2a29
parent c7bd7fef
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -84,12 +84,11 @@ class storaged_t : public android::hardware::health::V2_0::IHealthInfoCallback,
    sp<android::hardware::health::V2_0::IHealth> health;
    unique_ptr<storage_info_t> storage_info;
    static const uint32_t crc_init;
    unordered_map<int, storaged_proto::StoragedProto> protos;
    Mutex proto_mutex;
    void load_proto_locked(userid_t user_id);
    void prepare_proto(StoragedProto* proto, userid_t user_id);
    void flush_proto_locked(userid_t user_id);
    void flush_proto_user_system_locked(StoragedProto* proto);
    unordered_map<userid_t, bool> proto_loaded;
    void load_proto(userid_t user_id);
    void prepare_proto(userid_t user_id, StoragedProto* proto);
    void flush_proto(userid_t user_id, StoragedProto* proto);
    void flush_proto_user_system(StoragedProto* proto);
    string proto_path(userid_t user_id) {
        return string("/data/misc_ce/") + to_string(user_id) +
               "/storaged/storaged.proto";
@@ -116,7 +115,7 @@ public:

    map<uint64_t, struct uid_records> get_uid_records(
            double hours, uint64_t threshold, bool force_report) {
        return mUidm.dump(hours, threshold, force_report, &protos);
        return mUidm.dump(hours, threshold, force_report);
    }

    void update_uid_io_interval(int interval) {
@@ -135,7 +134,7 @@ public:

    void report_storage_info();

    void flush_protos();
    void flush_protos(unordered_map<int, StoragedProto>* protos);
};

// Eventlog tag
+2 −2
Original line number Diff line number Diff line
@@ -111,8 +111,7 @@ public:
    unordered_map<uint32_t, uid_info> get_uid_io_stats();
    // called by dumpsys
    map<uint64_t, struct uid_records> dump(
        double hours, uint64_t threshold, bool force_report,
        unordered_map<int, StoragedProto>* protos);
        double hours, uint64_t threshold, bool force_report);
    // called by battery properties listener
    void set_charger_state(charger_stat_t stat);
    // called by storaged periodic_chore or dump with force_report
@@ -120,6 +119,7 @@ public:
    void report(unordered_map<int, StoragedProto>* protos);
    // restores io_history from protobuf
    void load_uid_io_proto(const UidIOUsage& proto);
    void clear_user_history(userid_t user_id);
};

#endif /* _STORAGED_UID_MONITOR_H_ */
+27 −34
Original line number Diff line number Diff line
@@ -165,19 +165,17 @@ storaged_t::storaged_t(void) {
}

void storaged_t::add_user_ce(userid_t user_id) {
    Mutex::Autolock _l(proto_mutex);
    protos.insert({user_id, {}});
    load_proto_locked(user_id);
    protos[user_id].set_loaded(1);
    load_proto(user_id);
    proto_loaded[user_id] = true;
}

void storaged_t::remove_user_ce(userid_t user_id) {
    Mutex::Autolock _l(proto_mutex);
    protos.erase(user_id);
    proto_loaded[user_id] = false;
    mUidm.clear_user_history(user_id);
    RemoveFileIfExists(proto_path(user_id), nullptr);
}

void storaged_t::load_proto_locked(userid_t user_id) {
void storaged_t::load_proto(userid_t user_id) {
    string proto_file = proto_path(user_id);
    ifstream in(proto_file, ofstream::in | ofstream::binary);

@@ -185,32 +183,30 @@ void storaged_t::load_proto_locked(userid_t user_id) {

    stringstream ss;
    ss << in.rdbuf();
    StoragedProto* proto = &protos[user_id];
    proto->Clear();
    proto->ParseFromString(ss.str());
    StoragedProto proto;
    proto.ParseFromString(ss.str());

    uint32_t crc = proto->crc();
    proto->set_crc(crc_init);
    string proto_str = proto->SerializeAsString();
    uint32_t crc = proto.crc();
    proto.set_crc(crc_init);
    string proto_str = proto.SerializeAsString();
    uint32_t computed_crc = crc32(crc_init,
        reinterpret_cast<const Bytef*>(proto_str.c_str()),
        proto_str.size());

    if (crc != computed_crc) {
        LOG_TO(SYSTEM, WARNING) << "CRC mismatch in " << proto_file;
        proto->Clear();
        return;
    }

    mUidm.load_uid_io_proto(proto->uid_io_usage());
    mUidm.load_uid_io_proto(proto.uid_io_usage());

    if (user_id == USER_SYSTEM) {
        storage_info->load_perf_history_proto(proto->perf_history());
        storage_info->load_perf_history_proto(proto.perf_history());
    }
}

void storaged_t:: prepare_proto(StoragedProto* proto, userid_t user_id) {
    proto->set_version(2);
void storaged_t:: prepare_proto(userid_t user_id, StoragedProto* proto) {
    proto->set_version(3);
    proto->set_crc(crc_init);

    if (user_id == USER_SYSTEM) {
@@ -225,7 +221,7 @@ void storaged_t:: prepare_proto(StoragedProto* proto, userid_t user_id) {
        proto_str.size()));
}

void storaged_t::flush_proto_user_system_locked(StoragedProto* proto) {
void storaged_t::flush_proto_user_system(StoragedProto* proto) {
    string proto_str = proto->SerializeAsString();
    const char* data = proto_str.data();
    uint32_t size = proto_str.size();
@@ -274,11 +270,11 @@ void storaged_t::flush_proto_user_system_locked(StoragedProto* proto) {
    rename(tmp_file.c_str(), proto_file.c_str());
}

void storaged_t::flush_proto_locked(userid_t user_id) {
    StoragedProto* proto = &protos[user_id];
    prepare_proto(proto, user_id);
void storaged_t::flush_proto(userid_t user_id, StoragedProto* proto) {
    prepare_proto(user_id, proto);

    if (user_id == USER_SYSTEM) {
        flush_proto_user_system_locked(proto);
        flush_proto_user_system(proto);
        return;
    }

@@ -293,21 +289,20 @@ void storaged_t::flush_proto_locked(userid_t user_id) {
    rename(tmp_file.c_str(), proto_file.c_str());
}

void storaged_t::flush_protos() {
    Mutex::Autolock _l(proto_mutex);
    for (const auto& it : protos) {
void storaged_t::flush_protos(unordered_map<int, StoragedProto>* protos) {
    for (auto& it : *protos) {
        /*
         * Don't flush proto if we haven't loaded it from file and combined
         * with data in memory.
         * Don't flush proto if we haven't attempted to load it from file.
         */
        if (it.second.loaded() != 1) {
            continue;
        if (proto_loaded[it.first]) {
            flush_proto(it.first, &it.second);
        }
        flush_proto_locked(it.first);
    }
}

void storaged_t::event(void) {
    unordered_map<int, StoragedProto> protos;

    if (mDsm.enabled()) {
        mDsm.update();
        if (!(mTimer % mConfig.periodic_chores_interval_disk_stats_publish)) {
@@ -316,17 +311,15 @@ void storaged_t::event(void) {
    }

    if (!(mTimer % mConfig.periodic_chores_interval_uid_io)) {
        Mutex::Autolock _l(proto_mutex);
        mUidm.report(&protos);
    }

    if (storage_info) {
        Mutex::Autolock _l(proto_mutex);
        storage_info->refresh(protos[USER_SYSTEM].mutable_perf_history());
    }

    if (!(mTimer % mConfig.periodic_chores_interval_flush_proto)) {
        flush_protos();
        flush_protos(&protos);
    }

    mTimer += mConfig.periodic_chores_interval_unit;
+3 −4
Original line number Diff line number Diff line
@@ -54,8 +54,7 @@ message IOPerfHistory {
message StoragedProto {
  optional uint32 crc = 1;
  optional uint32 version = 2;
  optional uint32 loaded = 3;
  optional UidIOUsage uid_io_usage = 4;
  optional IOPerfHistory perf_history = 5;
  repeated uint32 padding = 6;
  optional UidIOUsage uid_io_usage = 3;
  optional IOPerfHistory perf_history = 4;
  repeated uint32 padding = 5;
}
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ storage_info_t* storage_info_t::get_storage_info()

void storage_info_t::load_perf_history_proto(const IOPerfHistory& perf_history)
{
    Mutex::Autolock _l(si_mutex);

    if (!perf_history.has_day_start_sec() ||
        perf_history.daily_perf_size() > (int)daily_perf.size() ||
        perf_history.weekly_perf_size() > (int)weekly_perf.size()) {
Loading