Loading storaged/include/storaged.h +15 −22 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <vector> #include <batteryservice/IBatteryPropertiesListener.h> #include <utils/Mutex.h> #include <android/hardware/health/2.0/IHealth.h> Loading Loading @@ -83,17 +84,18 @@ 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; static const string proto_file; storaged_proto::StoragedProto proto; enum stat { NOT_AVAILABLE, AVAILABLE, LOADED, }; stat proto_stat; 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); string proto_path(userid_t user_id) { return string("/data/misc_ce/") + to_string(user_id) + "/storaged/storaged.proto"; } public: storaged_t(void); ~storaged_t() {} void event(void); void event_checked(void); void pause(void) { Loading @@ -114,8 +116,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, proto.mutable_uid_io_usage()); return mUidm.dump(hours, threshold, force_report, &protos); } void update_uid_io_interval(int interval) { Loading @@ -124,15 +125,8 @@ public: } } void set_proto_stat_available(bool available) { if (available) { if (proto_stat != LOADED) { proto_stat = AVAILABLE; } } else { proto_stat = NOT_AVAILABLE; } }; void add_user_ce(userid_t user_id); void remove_user_ce(userid_t user_id); void init_health_service(); virtual ::android::hardware::Return<void> healthInfoChanged( Loading @@ -141,8 +135,7 @@ public: void report_storage_info(); void load_proto(); void flush_proto(); void flush_protos(); }; // Eventlog tag Loading storaged/include/storaged_info.h +5 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <chrono> #include <utils/Mutex.h> #include "storaged.h" #include "storaged.pb.h" Loading @@ -28,6 +30,7 @@ friend class test_case_name##_##test_name##_Test using namespace std; using namespace android; using namespace chrono; using namespace storaged_proto; Loading @@ -51,13 +54,12 @@ protected: uint32_t nr_days; vector<uint32_t> weekly_perf; uint32_t nr_weeks; sem_t si_lock; Mutex si_mutex; storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0), userdata_total_kb(0), userdata_free_kb(0), nr_samples(0), daily_perf(WEEK_TO_DAYS, 0), nr_days(0), weekly_perf(YEAR_TO_WEEKS, 0), nr_weeks(0) { sem_init(&si_lock, 0, 1); day_start_tp = system_clock::now(); day_start_tp -= chrono::seconds(duration_cast<chrono::seconds>( day_start_tp.time_since_epoch()).count() % DAY_TO_SEC); Loading @@ -66,7 +68,7 @@ protected: storage_info_t* s_info; public: static storage_info_t* get_storage_info(); virtual ~storage_info_t() { sem_destroy(&si_lock); } virtual ~storage_info_t() {}; virtual void report() {}; void load_perf_history_proto(const IOPerfHistory& perf_history); void refresh(IOPerfHistory* perf_history); Loading storaged/include/storaged_service.h +3 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,9 @@ using namespace android::os; using namespace android::os::storaged; class StoragedService : public BinderService<StoragedService>, public BnStoraged { private: void dumpUidRecordsDebug(int fd, const vector<struct uid_record>& entries); void dumpUidRecords(int fd, const vector<struct uid_record>& entries); public: static status_t start(); static char const* getServiceName() { return "storaged"; } Loading storaged/include/storaged_uid_monitor.h +38 −29 Original line number Diff line number Diff line Loading @@ -23,92 +23,101 @@ #include <unordered_map> #include <vector> #include <cutils/multiuser.h> #include <utils/Mutex.h> #include "storaged.pb.h" #include "uid_info.h" #define FRIEND_TEST(test_case_name, test_name) \ friend class test_case_name##_##test_name##_Test using namespace std; using namespace storaged_proto; using namespace android; using namespace android::os::storaged; class uid_info : public UidInfo { public: bool parse_uid_io_stats(std::string&& s); bool parse_uid_io_stats(string&& s); }; struct io_usage { class io_usage { public: io_usage() : bytes{{{0}}} {}; uint64_t bytes[IO_TYPES][UID_STATS][CHARGER_STATS]; bool is_zero() const; io_usage& operator+= (const io_usage& stats) { for (int i = 0; i < IO_TYPES; i++) { for (int j = 0; j < UID_STATS; j++) { for (int k = 0; k < CHARGER_STATS; k++) { bytes[i][j][k] += stats.bytes[i][j][k]; } } } return *this; } }; struct uid_io_usage { struct io_usage uid_ios; userid_t user_id; io_usage uid_ios; // mapped from task comm to task io usage std::map<std::string, struct io_usage> task_ios; map<string, io_usage> task_ios; }; struct uid_record { std::string name; string name; struct uid_io_usage ios; }; struct uid_records { uint64_t start_ts; std::vector<struct uid_record> entries; }; class lock_t { sem_t* mSem; public: lock_t(sem_t* sem) { mSem = sem; sem_wait(mSem); } ~lock_t() { sem_post(mSem); } vector<struct uid_record> entries; }; class uid_monitor { private: FRIEND_TEST(storaged_test, uid_monitor); // last dump from /proc/uid_io/stats, uid -> uid_info std::unordered_map<uint32_t, uid_info> last_uid_io_stats; unordered_map<uint32_t, uid_info> last_uid_io_stats; // current io usage for next report, app name -> uid_io_usage std::unordered_map<std::string, struct uid_io_usage> curr_io_stats; unordered_map<string, struct uid_io_usage> curr_io_stats; // io usage records, end timestamp -> {start timestamp, vector of records} std::map<uint64_t, struct uid_records> io_history; map<uint64_t, struct uid_records> io_history; // charger ON/OFF charger_stat_t charger_stat; // protects curr_io_stats, last_uid_io_stats, records and charger_stat sem_t um_lock; Mutex uidm_mutex; // start time for IO records uint64_t start_ts; // true if UID_IO_STATS_PATH is accessible const bool enable; // reads from /proc/uid_io/stats std::unordered_map<uint32_t, uid_info> get_uid_io_stats_locked(); unordered_map<uint32_t, uid_info> get_uid_io_stats_locked(); // flushes curr_io_stats to records void add_records_locked(uint64_t curr_ts); // updates curr_io_stats and set last_uid_io_stats void update_curr_io_stats_locked(); // writes io_history to protobuf void update_uid_io_proto(UidIOUsage* proto); void update_uid_io_proto(unordered_map<int, StoragedProto>* protos); public: uid_monitor(); ~uid_monitor(); // called by storaged main thread void init(charger_stat_t stat); // called by storaged -u std::unordered_map<uint32_t, uid_info> get_uid_io_stats(); unordered_map<uint32_t, uid_info> get_uid_io_stats(); // called by dumpsys std::map<uint64_t, struct uid_records> dump( map<uint64_t, struct uid_records> dump( double hours, uint64_t threshold, bool force_report, UidIOUsage* uid_io_proto); unordered_map<int, StoragedProto>* protos); // called by battery properties listener void set_charger_state(charger_stat_t stat); // called by storaged periodic_chore or dump with force_report bool enabled() { return enable; }; void report(UidIOUsage* proto); void report(unordered_map<int, StoragedProto>* protos); // restores io_history from protobuf void load_uid_io_proto(const UidIOUsage& proto); }; Loading storaged/include/storaged_utils.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ void get_inc_disk_stats(const struct disk_stats* prev, const struct disk_stats* void add_disk_stats(struct disk_stats* src, struct disk_stats* dst); // UID I/O map<string, io_usage> merge_io_usage(const vector<uid_record>& entries); void sort_running_uids_info(std::vector<UidInfo> &uids); // Logging Loading Loading
storaged/include/storaged.h +15 −22 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <vector> #include <batteryservice/IBatteryPropertiesListener.h> #include <utils/Mutex.h> #include <android/hardware/health/2.0/IHealth.h> Loading Loading @@ -83,17 +84,18 @@ 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; static const string proto_file; storaged_proto::StoragedProto proto; enum stat { NOT_AVAILABLE, AVAILABLE, LOADED, }; stat proto_stat; 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); string proto_path(userid_t user_id) { return string("/data/misc_ce/") + to_string(user_id) + "/storaged/storaged.proto"; } public: storaged_t(void); ~storaged_t() {} void event(void); void event_checked(void); void pause(void) { Loading @@ -114,8 +116,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, proto.mutable_uid_io_usage()); return mUidm.dump(hours, threshold, force_report, &protos); } void update_uid_io_interval(int interval) { Loading @@ -124,15 +125,8 @@ public: } } void set_proto_stat_available(bool available) { if (available) { if (proto_stat != LOADED) { proto_stat = AVAILABLE; } } else { proto_stat = NOT_AVAILABLE; } }; void add_user_ce(userid_t user_id); void remove_user_ce(userid_t user_id); void init_health_service(); virtual ::android::hardware::Return<void> healthInfoChanged( Loading @@ -141,8 +135,7 @@ public: void report_storage_info(); void load_proto(); void flush_proto(); void flush_protos(); }; // Eventlog tag Loading
storaged/include/storaged_info.h +5 −3 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <chrono> #include <utils/Mutex.h> #include "storaged.h" #include "storaged.pb.h" Loading @@ -28,6 +30,7 @@ friend class test_case_name##_##test_name##_Test using namespace std; using namespace android; using namespace chrono; using namespace storaged_proto; Loading @@ -51,13 +54,12 @@ protected: uint32_t nr_days; vector<uint32_t> weekly_perf; uint32_t nr_weeks; sem_t si_lock; Mutex si_mutex; storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0), userdata_total_kb(0), userdata_free_kb(0), nr_samples(0), daily_perf(WEEK_TO_DAYS, 0), nr_days(0), weekly_perf(YEAR_TO_WEEKS, 0), nr_weeks(0) { sem_init(&si_lock, 0, 1); day_start_tp = system_clock::now(); day_start_tp -= chrono::seconds(duration_cast<chrono::seconds>( day_start_tp.time_since_epoch()).count() % DAY_TO_SEC); Loading @@ -66,7 +68,7 @@ protected: storage_info_t* s_info; public: static storage_info_t* get_storage_info(); virtual ~storage_info_t() { sem_destroy(&si_lock); } virtual ~storage_info_t() {}; virtual void report() {}; void load_perf_history_proto(const IOPerfHistory& perf_history); void refresh(IOPerfHistory* perf_history); Loading
storaged/include/storaged_service.h +3 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,9 @@ using namespace android::os; using namespace android::os::storaged; class StoragedService : public BinderService<StoragedService>, public BnStoraged { private: void dumpUidRecordsDebug(int fd, const vector<struct uid_record>& entries); void dumpUidRecords(int fd, const vector<struct uid_record>& entries); public: static status_t start(); static char const* getServiceName() { return "storaged"; } Loading
storaged/include/storaged_uid_monitor.h +38 −29 Original line number Diff line number Diff line Loading @@ -23,92 +23,101 @@ #include <unordered_map> #include <vector> #include <cutils/multiuser.h> #include <utils/Mutex.h> #include "storaged.pb.h" #include "uid_info.h" #define FRIEND_TEST(test_case_name, test_name) \ friend class test_case_name##_##test_name##_Test using namespace std; using namespace storaged_proto; using namespace android; using namespace android::os::storaged; class uid_info : public UidInfo { public: bool parse_uid_io_stats(std::string&& s); bool parse_uid_io_stats(string&& s); }; struct io_usage { class io_usage { public: io_usage() : bytes{{{0}}} {}; uint64_t bytes[IO_TYPES][UID_STATS][CHARGER_STATS]; bool is_zero() const; io_usage& operator+= (const io_usage& stats) { for (int i = 0; i < IO_TYPES; i++) { for (int j = 0; j < UID_STATS; j++) { for (int k = 0; k < CHARGER_STATS; k++) { bytes[i][j][k] += stats.bytes[i][j][k]; } } } return *this; } }; struct uid_io_usage { struct io_usage uid_ios; userid_t user_id; io_usage uid_ios; // mapped from task comm to task io usage std::map<std::string, struct io_usage> task_ios; map<string, io_usage> task_ios; }; struct uid_record { std::string name; string name; struct uid_io_usage ios; }; struct uid_records { uint64_t start_ts; std::vector<struct uid_record> entries; }; class lock_t { sem_t* mSem; public: lock_t(sem_t* sem) { mSem = sem; sem_wait(mSem); } ~lock_t() { sem_post(mSem); } vector<struct uid_record> entries; }; class uid_monitor { private: FRIEND_TEST(storaged_test, uid_monitor); // last dump from /proc/uid_io/stats, uid -> uid_info std::unordered_map<uint32_t, uid_info> last_uid_io_stats; unordered_map<uint32_t, uid_info> last_uid_io_stats; // current io usage for next report, app name -> uid_io_usage std::unordered_map<std::string, struct uid_io_usage> curr_io_stats; unordered_map<string, struct uid_io_usage> curr_io_stats; // io usage records, end timestamp -> {start timestamp, vector of records} std::map<uint64_t, struct uid_records> io_history; map<uint64_t, struct uid_records> io_history; // charger ON/OFF charger_stat_t charger_stat; // protects curr_io_stats, last_uid_io_stats, records and charger_stat sem_t um_lock; Mutex uidm_mutex; // start time for IO records uint64_t start_ts; // true if UID_IO_STATS_PATH is accessible const bool enable; // reads from /proc/uid_io/stats std::unordered_map<uint32_t, uid_info> get_uid_io_stats_locked(); unordered_map<uint32_t, uid_info> get_uid_io_stats_locked(); // flushes curr_io_stats to records void add_records_locked(uint64_t curr_ts); // updates curr_io_stats and set last_uid_io_stats void update_curr_io_stats_locked(); // writes io_history to protobuf void update_uid_io_proto(UidIOUsage* proto); void update_uid_io_proto(unordered_map<int, StoragedProto>* protos); public: uid_monitor(); ~uid_monitor(); // called by storaged main thread void init(charger_stat_t stat); // called by storaged -u std::unordered_map<uint32_t, uid_info> get_uid_io_stats(); unordered_map<uint32_t, uid_info> get_uid_io_stats(); // called by dumpsys std::map<uint64_t, struct uid_records> dump( map<uint64_t, struct uid_records> dump( double hours, uint64_t threshold, bool force_report, UidIOUsage* uid_io_proto); unordered_map<int, StoragedProto>* protos); // called by battery properties listener void set_charger_state(charger_stat_t stat); // called by storaged periodic_chore or dump with force_report bool enabled() { return enable; }; void report(UidIOUsage* proto); void report(unordered_map<int, StoragedProto>* protos); // restores io_history from protobuf void load_uid_io_proto(const UidIOUsage& proto); }; Loading
storaged/include/storaged_utils.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ void get_inc_disk_stats(const struct disk_stats* prev, const struct disk_stats* void add_disk_stats(struct disk_stats* src, struct disk_stats* dst); // UID I/O map<string, io_usage> merge_io_usage(const vector<uid_record>& entries); void sort_running_uids_info(std::vector<UidInfo> &uids); // Logging Loading