diff --git a/event.logtags b/event.logtags index 5382b49..269beb2 100644 --- a/event.logtags +++ b/event.logtags @@ -21,6 +21,7 @@ # 2: int64_t # 3: string # 4: list +# 5: float # # The data unit is a number taken from the following list: # 1: Number of objects @@ -35,4 +36,4 @@ # TODO: generate ".java" and ".h" files with integer constants from this file. # for killinfo logs -10195355 killinfo (Pid|1|5),(Uid|1|5),(OomAdj|1),(MinOomAdj|1),(TaskSize|1),(enum kill_reasons|1|5),(MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(IonHeap|1),(IonHeapPool|1),(CmaFree|1),(MsSinceEvent|1),(MsSincePrevWakeup|1),(WakeupsSinceEvent|1),(SkippedWakeups|1),(TaskSwapSize|1),(GPU|1) +10195355 killinfo (Pid|1|5),(Uid|1|5),(OomAdj|1),(MinOomAdj|1),(TaskSize|1),(enum kill_reasons|1|5),(MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(IonHeap|1),(IonHeapPool|1),(CmaFree|1),(MsSinceEvent|1),(MsSincePrevWakeup|1),(WakeupsSinceEvent|1),(SkippedWakeups|1),(TaskSwapSize|1),(GPU|1),(PsiMemSome|5),(PsiMemFull|5),(PsiIoSome|5),(PsiIoFull|5),(PsiCpuSome|5) diff --git a/libpsi/include/psi/psi.h b/libpsi/include/psi/psi.h index f29a7e7..9162446 100644 --- a/libpsi/include/psi/psi.h +++ b/libpsi/include/psi/psi.h @@ -23,6 +23,8 @@ __BEGIN_DECLS #define PSI_PATH_MEMORY "/proc/pressure/memory" +#define PSI_PATH_IO "/proc/pressure/io" +#define PSI_PATH_CPU "/proc/pressure/cpu" enum psi_stall_type { PSI_SOME, @@ -39,6 +41,8 @@ struct psi_stats { struct psi_data { struct psi_stats mem_stats[PSI_TYPE_COUNT]; + struct psi_stats io_stats[PSI_TYPE_COUNT]; + struct psi_stats cpu_stats[PSI_TYPE_COUNT]; }; /* diff --git a/lmkd.cpp b/lmkd.cpp index 1e174e5..926a1d0 100644 --- a/lmkd.cpp +++ b/lmkd.cpp @@ -1929,6 +1929,22 @@ static int psi_parse_mem(struct psi_data *psi_data) { return psi_parse(&file_data, psi_data->mem_stats, true); } +static int psi_parse_io(struct psi_data *psi_data) { + static struct reread_data file_data = { + .filename = PSI_PATH_IO, + .fd = -1, + }; + return psi_parse(&file_data, psi_data->io_stats, true); +} + +static int psi_parse_cpu(struct psi_data *psi_data) { + static struct reread_data file_data = { + .filename = PSI_PATH_CPU, + .fd = -1, + }; + return psi_parse(&file_data, psi_data->cpu_stats, false); +} + enum wakeup_reason { Event, Polling @@ -1966,7 +1982,8 @@ static void record_wakeup_time(struct timespec *tm, enum wakeup_reason reason, static void killinfo_log(struct proc* procp, int min_oom_score, int rss_kb, int swap_kb, int kill_reason, union meminfo *mi, - struct wakeup_info *wi, struct timespec *tm) { + struct wakeup_info *wi, struct timespec *tm, + struct psi_data *pd) { /* log process information */ android_log_write_int32(ctx, procp->pid); android_log_write_int32(ctx, procp->uid); @@ -1988,6 +2005,18 @@ static void killinfo_log(struct proc* procp, int min_oom_score, int rss_kb, android_log_write_int32(ctx, (int32_t)min(swap_kb, INT32_MAX)); android_log_write_int32(ctx, (int32_t)mi->field.total_gpu_kb); + if (pd) { + android_log_write_float32(ctx, pd->mem_stats[PSI_SOME].avg10); + android_log_write_float32(ctx, pd->mem_stats[PSI_FULL].avg10); + android_log_write_float32(ctx, pd->io_stats[PSI_SOME].avg10); + android_log_write_float32(ctx, pd->io_stats[PSI_FULL].avg10); + android_log_write_float32(ctx, pd->cpu_stats[PSI_SOME].avg10); + } else { + for (int i = 0; i < 5; i++) { + android_log_write_float32(ctx, 0); + } + } + android_log_write_list(ctx, LOG_ID_EVENTS); android_log_reset(ctx); } @@ -2162,7 +2191,8 @@ struct kill_info { /* Kill one process specified by procp. Returns the size (in pages) of the process killed */ static int kill_one_process(struct proc* procp, int min_oom_score, struct kill_info *ki, - union meminfo *mi, struct wakeup_info *wi, struct timespec *tm) { + union meminfo *mi, struct wakeup_info *wi, struct timespec *tm, + struct psi_data *pd) { int pid = procp->pid; int pidfd = procp->pidfd; uid_t uid = procp->uid; @@ -2234,7 +2264,7 @@ static int kill_one_process(struct proc* procp, int min_oom_score, struct kill_i kill_st.kill_reason = ki->kill_reason; kill_st.thrashing = ki->thrashing; kill_st.max_thrashing = ki->max_thrashing; - killinfo_log(procp, min_oom_score, rss_kb, swap_kb, ki->kill_reason, mi, wi, tm); + killinfo_log(procp, min_oom_score, rss_kb, swap_kb, ki->kill_reason, mi, wi, tm, pd); ALOGI("Kill '%s' (%d), uid %d, oom_score_adj %d to free %" PRId64 "kB rss, %" PRId64 "kB swap; reason: %s", taskname, pid, uid, procp->oomadj, rss_kb, swap_kb, ki->kill_desc); @@ -2242,7 +2272,7 @@ static int kill_one_process(struct proc* procp, int min_oom_score, struct kill_i kill_st.kill_reason = NONE; kill_st.thrashing = 0; kill_st.max_thrashing = 0; - killinfo_log(procp, min_oom_score, rss_kb, swap_kb, NONE, mi, wi, tm); + killinfo_log(procp, min_oom_score, rss_kb, swap_kb, NONE, mi, wi, tm, pd); ALOGI("Kill '%s' (%d), uid %d, oom_score_adj %d to free %" PRId64 "kB rss, %" PRId64 "kb swap", taskname, pid, uid, procp->oomadj, rss_kb, swap_kb); } @@ -2273,7 +2303,8 @@ out: * Returns size of the killed process. */ static int find_and_kill_process(int min_score_adj, struct kill_info *ki, union meminfo *mi, - struct wakeup_info *wi, struct timespec *tm) { + struct wakeup_info *wi, struct timespec *tm, + struct psi_data *pd) { int i; int killed_size = 0; bool lmk_state_change_start = false; @@ -2297,7 +2328,7 @@ static int find_and_kill_process(int min_score_adj, struct kill_info *ki, union if (!procp) break; - killed_size = kill_one_process(procp, min_score_adj, ki, mi, wi, tm); + killed_size = kill_one_process(procp, min_score_adj, ki, mi, wi, tm, pd); if (killed_size >= 0) { if (!lmk_state_change_start) { lmk_state_change_start = true; @@ -2710,7 +2741,9 @@ static void mp_event_psi(int data, uint32_t events, struct polling_params *poll_ if (critical_stall) { min_score_adj = 0; } - int pages_freed = find_and_kill_process(min_score_adj, &ki, &mi, &wi, &curr_tm); + psi_parse_io(&psi_data); + psi_parse_cpu(&psi_data); + int pages_freed = find_and_kill_process(min_score_adj, &ki, &mi, &wi, &curr_tm, &psi_data); if (pages_freed > 0) { killing = true; max_thrashing = 0; @@ -2930,7 +2963,7 @@ static void mp_event_common(int data, uint32_t events, struct polling_params *po do_kill: if (low_ram_device) { /* For Go devices kill only one task */ - if (find_and_kill_process(level_oomadj[level], NULL, &mi, &wi, &curr_tm) == 0) { + if (find_and_kill_process(level_oomadj[level], NULL, &mi, &wi, &curr_tm, NULL) == 0) { if (debug_process_killing) { ALOGI("Nothing to kill"); } @@ -2953,7 +2986,7 @@ do_kill: min_score_adj = level_oomadj[level]; } - pages_freed = find_and_kill_process(min_score_adj, NULL, &mi, &wi, &curr_tm); + pages_freed = find_and_kill_process(min_score_adj, NULL, &mi, &wi, &curr_tm, NULL); if (pages_freed == 0) { /* Rate limit kill reports when nothing was reclaimed */