From 8157775d791c124fcd84cdbeb7a751226bcb285b Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Tue, 21 Feb 2017 12:09:39 -0800 Subject: [PATCH] storaged: include start time in IO usage dumpsys New format: starttime1,endtime1 records [starttime2],endtime2 records Note starttime2 is skipped if it equals with endtime1. Bug: 34198239 Change-Id: I8a88a3bf1d50e065510d3ab123422d564fb6159f --- storaged/include/storaged.h | 2 +- storaged/include/storaged_uid_monitor.h | 13 ++++++-- storaged/storaged_service.cpp | 12 ++++++-- storaged/storaged_uid_monitor.cpp | 40 +++++++++++++++---------- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h index 591719e74..c291bd98c 100644 --- a/storaged/include/storaged.h +++ b/storaged/include/storaged.h @@ -301,7 +301,7 @@ public: std::unordered_map get_uids(void) { return mUidm.get_uid_io_stats(); } - std::map> get_uid_records( + std::map get_uid_records( double hours, uint64_t threshold, bool force_report) { return mUidm.dump(hours, threshold, force_report); } diff --git a/storaged/include/storaged_uid_monitor.h b/storaged/include/storaged_uid_monitor.h index 031b7c4ee..b32c9a095 100644 --- a/storaged/include/storaged_uid_monitor.h +++ b/storaged/include/storaged_uid_monitor.h @@ -63,18 +63,25 @@ struct uid_record { struct uid_io_usage ios; }; +struct uid_records { + uint64_t start_ts; + std::vector entries; +}; + class uid_monitor { private: // last dump from /proc/uid_io/stats, uid -> uid_info std::unordered_map last_uid_io_stats; // current io usage for next report, app name -> uid_io_usage std::unordered_map curr_io_stats; - // io usage records, timestamp -> vector of events - std::map> records; + // io usage records, end timestamp -> {start timestamp, vector of records} + std::map records; // charger ON/OFF charger_stat_t charger_stat; // protects curr_io_stats, last_uid_io_stats, records and charger_stat sem_t um_lock; + // start time for IO records + uint64_t start_ts; // reads from /proc/uid_io/stats std::unordered_map get_uid_io_stats_locked(); @@ -91,7 +98,7 @@ public: // called by storaged -u std::unordered_map get_uid_io_stats(); // called by dumpsys - std::map> dump( + std::map dump( double hours, uint64_t threshold, bool force_report); // called by battery properties listener void set_charger_state(charger_stat_t stat); diff --git a/storaged/storaged_service.cpp b/storaged/storaged_service.cpp index 9c8cbf0e8..a3352982a 100644 --- a/storaged/storaged_service.cpp +++ b/storaged/storaged_service.cpp @@ -118,11 +118,17 @@ status_t Storaged::dump(int fd, const Vector& args) { } } - const std::map>& records = + uint64_t last_ts = 0; + const std::map& records = storaged.get_uid_records(hours, threshold, force_report); for (const auto& it : records) { - dprintf(fd, "%llu\n", (unsigned long long)it.first); - for (const auto& record : it.second) { + if (last_ts != it.second.start_ts) { + dprintf(fd, "%llu", (unsigned long long)it.second.start_ts); + } + dprintf(fd, ",%llu\n", (unsigned long long)it.first); + last_ts = it.first; + + for (const auto& record : it.second.entries) { dprintf(fd, "%s %llu %llu %llu %llu %llu %llu %llu %llu\n", record.name.c_str(), (unsigned long long)record.ios.bytes[READ][FOREGROUND][CHARGER_OFF], diff --git a/storaged/storaged_uid_monitor.cpp b/storaged/storaged_uid_monitor.cpp index 49d0d4861..78e0a832e 100644 --- a/storaged/storaged_uid_monitor.cpp +++ b/storaged/storaged_uid_monitor.cpp @@ -103,11 +103,11 @@ std::unordered_map uid_monitor::get_uid_io_stats_lock static const int MAX_UID_RECORDS_SIZE = 1000 * 48; // 1000 uids in 48 hours static inline int records_size( - const std::map>& records) + const std::map& curr_records) { int count = 0; - for (auto const& it : records) { - count += it.second.size(); + for (auto const& it : curr_records) { + count += it.second.entries.size(); } return count; } @@ -122,34 +122,36 @@ void uid_monitor::add_records_locked(uint64_t curr_ts) records.erase(records.begin(), it); } - std::vector new_records; + struct uid_records new_records; for (const auto& p : curr_io_stats) { struct uid_record record = {}; record.name = p.first; record.ios = p.second; if (memcmp(&record.ios, &zero_io_usage, sizeof(struct uid_io_usage))) { - new_records.push_back(record); + new_records.entries.push_back(record); } } curr_io_stats.clear(); + new_records.start_ts = start_ts; + start_ts = curr_ts; - if (new_records.empty()) + if (new_records.entries.empty()) return; // make some room for new records int overflow = records_size(records) + - new_records.size() - MAX_UID_RECORDS_SIZE; + new_records.entries.size() - MAX_UID_RECORDS_SIZE; while (overflow > 0 && records.size() > 0) { - overflow -= records[0].size(); + auto del_it = records.begin(); + overflow -= del_it->second.entries.size(); records.erase(records.begin()); } - records[curr_ts].insert(records[curr_ts].end(), - new_records.begin(), new_records.end()); + records[curr_ts] = new_records; } -std::map> uid_monitor::dump( +std::map uid_monitor::dump( double hours, uint64_t threshold, bool force_report) { if (force_report) { @@ -158,7 +160,7 @@ std::map> uid_monitor::dump( std::unique_ptr lock(new lock_t(&um_lock)); - std::map> dump_records; + std::map dump_records; uint64_t first_ts = 0; if (hours != 0) { @@ -166,8 +168,8 @@ std::map> uid_monitor::dump( } for (auto it = records.lower_bound(first_ts); it != records.end(); ++it) { - const std::vector& recs = it->second; - std::vector filtered; + const std::vector& recs = it->second.entries; + struct uid_records filtered; for (const auto& rec : recs) { if (rec.ios.bytes[READ][FOREGROUND][CHARGER_ON] + @@ -178,11 +180,16 @@ std::map> uid_monitor::dump( rec.ios.bytes[WRITE][FOREGROUND][CHARGER_OFF] + rec.ios.bytes[WRITE][BACKGROUND][CHARGER_ON] + rec.ios.bytes[WRITE][BACKGROUND][CHARGER_OFF] > threshold) { - filtered.push_back(rec); + filtered.entries.push_back(rec); } } + + if (filtered.entries.empty()) + continue; + + filtered.start_ts = it->second.start_ts; dump_records.insert( - std::pair>(it->first, filtered)); + std::pair(it->first, filtered)); } return dump_records; @@ -249,6 +256,7 @@ void uid_monitor::set_charger_state(charger_stat_t stat) void uid_monitor::init(charger_stat_t stat) { charger_stat = stat; + start_ts = time(NULL); last_uid_io_stats = get_uid_io_stats(); }