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

Commit 6abe26cd authored by Jin Qian's avatar Jin Qian Committed by Android (Google) Code Review
Browse files

Merge "storaged: add task io to dump service"

parents e2f94b99 3906c892
Loading
Loading
Loading
Loading
+0 −16
Original line number Diff line number Diff line
@@ -97,22 +97,6 @@ struct disk_perf {
    uint32_t queue;             // I/Os in queue
};

#define CMD_MAX_LEN ( 64 )
struct task_info {
    uint32_t pid;                   // task id
    uint64_t rchar;                 // characters read
    uint64_t wchar;                 // characters written
    uint64_t syscr;                 // read syscalls
    uint64_t syscw;                 // write syscalls
    uint64_t read_bytes;            // bytes read (from storage layer)
    uint64_t write_bytes;           // bytes written (to storage layer)
    uint64_t cancelled_write_bytes; // cancelled write byte by truncate

    uint64_t starttime;             // start time of task

    char cmd[CMD_MAX_LEN];          // filename of the executable
};

class lock_t {
    sem_t* mSem;
public:
+19 −3
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ enum io_type_t {
    IO_TYPES = 2
};

struct uid_io_stats {
struct io_stats {
    uint64_t rchar;                 // characters read
    uint64_t wchar;                 // characters written
    uint64_t read_bytes;            // bytes read (from storage layer)
@@ -49,14 +49,30 @@ struct uid_io_stats {
    uint64_t fsync;                 // number of fsync syscalls
};

struct task_info {
    std::string comm;
    pid_t pid;
    struct io_stats io[UID_STATS];
    bool parse_task_io_stats(std::string&& s);
};

struct uid_info {
    uint32_t uid;                   // user id
    std::string name;               // package name
    struct uid_io_stats io[UID_STATS];    // [0]:foreground [1]:background
    struct io_stats io[UID_STATS];    // [0]:foreground [1]:background
    std::unordered_map<uint32_t, task_info> tasks; // mapped from pid
    bool parse_uid_io_stats(std::string&& s);
};

struct uid_io_usage {
struct io_usage {
    uint64_t bytes[IO_TYPES][UID_STATS][CHARGER_STATS];
    bool is_zero() const;
};

struct uid_io_usage {
    struct io_usage uid_ios;
    // mapped from task comm to task io usage
    std::map<std::string, struct io_usage> task_ios;
};

struct uid_record {
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ bool parse_emmc_ecsd(int ext_csd_fd, struct emmc_info* info);
void sort_running_uids_info(std::vector<struct uid_info> &uids);

// Logging
void log_console_running_uids_info(std::vector<struct uid_info> uids);
void log_console_running_uids_info(const std::vector<struct uid_info>& uids, bool flag_dump_task);

void log_debug_disk_perf(struct disk_perf* perf, const char* type);

+15 −9
Original line number Diff line number Diff line
@@ -63,13 +63,15 @@ void* storaged_main(void* /* unused */) {
static void help_message(void) {
    printf("usage: storaged [OPTION]\n");
    printf("  -u    --uid                   Dump uid I/O usage to stdout\n");
    printf("  -t    --task                  Dump task I/O usage to stdout\n");
    printf("  -s    --start                 Start storaged (default)\n");
    fflush(stdout);
}

int main(int argc, char** argv) {
    int flag_main_service = 0;
    int flag_dump_uid = 0;
    bool flag_main_service = false;
    bool flag_dump_uid = false;
    bool flag_dump_task = false;
    int opt;

    for (;;) {
@@ -78,19 +80,23 @@ int main(int argc, char** argv) {
            {"start",       no_argument,        0, 's'},
            {"kill",        no_argument,        0, 'k'},
            {"uid",         no_argument,        0, 'u'},
            {"task",        no_argument,        0, 't'},
            {"help",        no_argument,        0, 'h'}
        };
        opt = getopt_long(argc, argv, ":skdhu0", long_options, &opt_idx);
        opt = getopt_long(argc, argv, ":skdhu0t", long_options, &opt_idx);
        if (opt == -1) {
            break;
        }

        switch (opt) {
        case 's':
            flag_main_service = 1;
            flag_main_service = true;
            break;
        case 'u':
            flag_dump_uid = 1;
            flag_dump_uid = true;
            break;
        case 't':
            flag_dump_task = true;
            break;
        case 'h':
            help_message();
@@ -104,10 +110,10 @@ int main(int argc, char** argv) {
    }

    if (argc == 1) {
        flag_main_service = 1;
        flag_main_service = true;
    }

    if (flag_main_service && flag_dump_uid) {
    if (flag_main_service && (flag_dump_uid || flag_dump_task)) {
        fprintf(stderr, "Invalid arguments. Option \"start\" and \"dump\" cannot be used together.\n");
        help_message();
        return -1;
@@ -130,7 +136,7 @@ int main(int argc, char** argv) {
        return 0;
    }

    if (flag_dump_uid) {
    if (flag_dump_uid || flag_dump_task) {
        sp<IStoraged> storaged_service = get_storaged_service();
        if (storaged_service == NULL) {
            fprintf(stderr, "Cannot find storaged service.\nMaybe run storaged --start first?\n");
@@ -144,7 +150,7 @@ int main(int argc, char** argv) {
        }

        sort_running_uids_info(res);
        log_console_running_uids_info(res);
        log_console_running_uids_info(res, flag_dump_task);

        return 0;
    }
+53 −12
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 */

#include <inttypes.h>
#include <stdint.h>

#include <vector>
@@ -47,6 +48,15 @@ std::vector<struct uid_info> BpStoraged::dump_uids(const char* /*option*/) {
        uid.uid = reply.readInt32();
        uid.name = reply.readCString();
        reply.read(&uid.io, sizeof(uid.io));

        uint32_t tasks_size = reply.readInt32();
        for (uint32_t i = 0; i < tasks_size; i++) {
            struct task_info task;
            task.pid = reply.readInt32();
            task.comm = reply.readCString();
            reply.read(&task.io, sizeof(task.io));
            uid.tasks[task.pid] = task;
        }
    }
    return res;
}
@@ -59,10 +69,17 @@ status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply
                    return BAD_TYPE;
                std::vector<struct uid_info> res = dump_uids(NULL);
                reply->writeInt32(res.size());
                for (auto uid : res) {
                for (const auto& uid : res) {
                    reply->writeInt32(uid.uid);
                    reply->writeCString(uid.name.c_str());
                    reply->write(&uid.io, sizeof(uid.io));

                    reply->writeInt32(uid.tasks.size());
                    for (const auto& task_it : uid.tasks) {
                        reply->writeInt32(task_it.first);
                        reply->writeCString(task_it.second.comm.c_str());
                        reply->write(&task_it.second.io, sizeof(task_it.second.io));
                    }
                }
                return NO_ERROR;
            }
@@ -96,6 +113,7 @@ status_t Storaged::dump(int fd, const Vector<String16>& args) {
    int time_window = 0;
    uint64_t threshold = 0;
    bool force_report = false;
    bool debug = false;
    for (size_t i = 0; i < args.size(); i++) {
        const auto& arg = args[i];
        if (arg == String16("--hours")) {
@@ -123,6 +141,10 @@ status_t Storaged::dump(int fd, const Vector<String16>& args) {
            force_report = true;
            continue;
        }
        if (arg == String16("--debug")) {
            debug = true;
            continue;
        }
    }

    uint64_t last_ts = 0;
@@ -130,22 +152,41 @@ status_t Storaged::dump(int fd, const Vector<String16>& args) {
                storaged->get_uid_records(hours, threshold, force_report);
    for (const auto& it : records) {
        if (last_ts != it.second.start_ts) {
            dprintf(fd, "%llu", (unsigned long long)it.second.start_ts);
            dprintf(fd, "%" PRIu64, it.second.start_ts);
        }
        dprintf(fd, ",%llu\n", (unsigned long long)it.first);
        dprintf(fd, ",%" PRIu64 "\n", it.first);
        last_ts = it.first;

        for (const auto& record : it.second.entries) {
            dprintf(fd, "%s %ju %ju %ju %ju %ju %ju %ju %ju\n",
            const struct io_usage& uid_usage = record.ios.uid_ios;
            dprintf(fd, "%s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
                    " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
                record.name.c_str(),
                record.ios.bytes[READ][FOREGROUND][CHARGER_OFF],
                record.ios.bytes[WRITE][FOREGROUND][CHARGER_OFF],
                record.ios.bytes[READ][BACKGROUND][CHARGER_OFF],
                record.ios.bytes[WRITE][BACKGROUND][CHARGER_OFF],
                record.ios.bytes[READ][FOREGROUND][CHARGER_ON],
                record.ios.bytes[WRITE][FOREGROUND][CHARGER_ON],
                record.ios.bytes[READ][BACKGROUND][CHARGER_ON],
                record.ios.bytes[WRITE][BACKGROUND][CHARGER_ON]);
                uid_usage.bytes[READ][FOREGROUND][CHARGER_OFF],
                uid_usage.bytes[WRITE][FOREGROUND][CHARGER_OFF],
                uid_usage.bytes[READ][BACKGROUND][CHARGER_OFF],
                uid_usage.bytes[WRITE][BACKGROUND][CHARGER_OFF],
                uid_usage.bytes[READ][FOREGROUND][CHARGER_ON],
                uid_usage.bytes[WRITE][FOREGROUND][CHARGER_ON],
                uid_usage.bytes[READ][BACKGROUND][CHARGER_ON],
                uid_usage.bytes[WRITE][BACKGROUND][CHARGER_ON]);
            if (debug) {
                for (const auto& task_it : record.ios.task_ios) {
                    const struct io_usage& task_usage = task_it.second;
                    const std::string& comm = task_it.first;
                    dprintf(fd, "-> %s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
                            " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
                        comm.c_str(),
                        task_usage.bytes[READ][FOREGROUND][CHARGER_OFF],
                        task_usage.bytes[WRITE][FOREGROUND][CHARGER_OFF],
                        task_usage.bytes[READ][BACKGROUND][CHARGER_OFF],
                        task_usage.bytes[WRITE][BACKGROUND][CHARGER_OFF],
                        task_usage.bytes[READ][FOREGROUND][CHARGER_ON],
                        task_usage.bytes[WRITE][FOREGROUND][CHARGER_ON],
                        task_usage.bytes[READ][BACKGROUND][CHARGER_ON],
                        task_usage.bytes[WRITE][BACKGROUND][CHARGER_ON]);
                }
            }
        }
    }

Loading