Android-x86
Fork
Spenden

  • R/O
  • HTTP
  • SSH
  • HTTPS

system-core: Commit

system/core


Commit MetaInfo

Revision244ace6b7b6508e97efc0a384c77f4b5b6c0de52 (tree)
Zeit2018-10-13 06:28:50
AutorRajeev Kumar <rajekumar@goog...>
CommiterRajeev Kumar

Log Message

Read memory stats from /proc/pid/stat file.

(cherry pick from commit 0301683e49ab255769b15469487feaab3466167a)
Bug: 117333340
Test: Manual testing using alloc-stress tool
Change-Id: Ie555933aafa6a6b7aa1dbf5518ebe804376e0afd
Merged-In: Ie555933aafa6a6b7aa1dbf5518ebe804376e0afd

Ändern Zusammenfassung

Diff

--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -114,6 +114,7 @@ static bool low_ram_device;
114114 static bool kill_heaviest_task;
115115 static unsigned long kill_timeout_ms;
116116 static bool use_minfree_levels;
117+static bool per_app_memcg;
117118
118119 /* data required to handle events */
119120 struct event_handler_info {
@@ -523,6 +524,10 @@ static void cmd_procremove(LMKD_CTRL_PACKET packet) {
523524 return;
524525
525526 lmkd_pack_get_procremove(packet, &params);
527+ /*
528+ * WARNING: After pid_remove() procp is freed and can't be used!
529+ * Therefore placed at the end of the function.
530+ */
526531 pid_remove(params.pid);
527532 }
528533
@@ -699,7 +704,7 @@ static void ctrl_connect_handler(int data __unused, uint32_t events __unused) {
699704 }
700705
701706 #ifdef LMKD_LOG_STATS
702-static void memory_stat_parse_line(char *line, struct memory_stat *mem_st) {
707+static void memory_stat_parse_line(char* line, struct memory_stat* mem_st) {
703708 char key[LINE_MAX + 1];
704709 int64_t value;
705710
@@ -721,25 +726,62 @@ static void memory_stat_parse_line(char *line, struct memory_stat *mem_st) {
721726 mem_st->swap_in_bytes = value;
722727 }
723728
724-static int memory_stat_parse(struct memory_stat *mem_st, int pid, uid_t uid) {
725- FILE *fp;
726- char buf[PATH_MAX];
729+static int memory_stat_from_cgroup(struct memory_stat* mem_st, int pid, uid_t uid) {
730+ FILE* fp;
731+ char buf[PATH_MAX];
727732
728- snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
733+ snprintf(buf, sizeof(buf), MEMCG_PROCESS_MEMORY_STAT_PATH, uid, pid);
729734
730- fp = fopen(buf, "r");
735+ fp = fopen(buf, "r");
731736
732- if (fp == NULL) {
733- ALOGE("%s open failed: %s", buf, strerror(errno));
734- return -1;
735- }
737+ if (fp == NULL) {
738+ ALOGE("%s open failed: %s", buf, strerror(errno));
739+ return -1;
740+ }
736741
737- while (fgets(buf, PAGE_SIZE, fp) != NULL ) {
738- memory_stat_parse_line(buf, mem_st);
739- }
740- fclose(fp);
742+ while (fgets(buf, PAGE_SIZE, fp) != NULL) {
743+ memory_stat_parse_line(buf, mem_st);
744+ }
745+ fclose(fp);
741746
742- return 0;
747+ return 0;
748+}
749+
750+static int memory_stat_from_procfs(struct memory_stat* mem_st, int pid) {
751+ char path[PATH_MAX];
752+ char buffer[PROC_STAT_BUFFER_SIZE];
753+ int fd, ret;
754+
755+ snprintf(path, sizeof(path), PROC_STAT_FILE_PATH, pid);
756+ if ((fd = open(path, O_RDONLY | O_CLOEXEC)) < 0) {
757+ ALOGE("%s open failed: %s", path, strerror(errno));
758+ return -1;
759+ }
760+
761+ ret = read(fd, buffer, sizeof(buffer));
762+ if (ret < 0) {
763+ ALOGE("%s read failed: %s", path, strerror(errno));
764+ close(fd);
765+ return -1;
766+ }
767+ close(fd);
768+
769+ // field 10 is pgfault
770+ // field 12 is pgmajfault
771+ // field 24 is rss_in_pages
772+ int64_t pgfault = 0, pgmajfault = 0, rss_in_pages = 0;
773+ if (sscanf(buffer,
774+ "%*u %*s %*s %*d %*d %*d %*d %*d %*d %" SCNd64 " %*d "
775+ "%" SCNd64 " %*d %*u %*u %*d %*d %*d %*d %*d %*d "
776+ "%*d %*d %" SCNd64 "",
777+ &pgfault, &pgmajfault, &rss_in_pages) != 3) {
778+ return -1;
779+ }
780+ mem_st->pgfault = pgfault;
781+ mem_st->pgmajfault = pgmajfault;
782+ mem_st->rss_in_bytes = (rss_in_pages * PAGE_SIZE);
783+
784+ return 0;
743785 }
744786 #endif
745787
@@ -964,6 +1006,7 @@ static int kill_one_process(struct proc* procp) {
9641006 char *taskname;
9651007 int tasksize;
9661008 int r;
1009+ int result = -1;
9671010
9681011 #ifdef LMKD_LOG_STATS
9691012 struct memory_stat mem_st = {};
@@ -972,46 +1015,57 @@ static int kill_one_process(struct proc* procp) {
9721015
9731016 taskname = proc_get_name(pid);
9741017 if (!taskname) {
975- pid_remove(pid);
976- return -1;
1018+ goto out;
9771019 }
9781020
9791021 tasksize = proc_get_size(pid);
9801022 if (tasksize <= 0) {
981- pid_remove(pid);
982- return -1;
1023+ goto out;
9831024 }
9841025
9851026 #ifdef LMKD_LOG_STATS
9861027 if (enable_stats_log) {
987- memory_stat_parse_result = memory_stat_parse(&mem_st, pid, uid);
1028+ if (per_app_memcg) {
1029+ memory_stat_parse_result = memory_stat_from_cgroup(&mem_st, pid, uid);
1030+ } else {
1031+ memory_stat_parse_result = memory_stat_from_procfs(&mem_st, pid);
1032+ }
9881033 }
9891034 #endif
9901035
9911036 TRACE_KILL_START(pid);
9921037
1038+ /* CAP_KILL required */
9931039 r = kill(pid, SIGKILL);
9941040 ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB",
9951041 taskname, pid, uid, procp->oomadj, tasksize * page_k);
996- pid_remove(pid);
9971042
9981043 TRACE_KILL_END();
9991044
10001045 if (r) {
10011046 ALOGE("kill(%d): errno=%d", pid, errno);
1002- return -1;
1047+ goto out;
10031048 } else {
10041049 #ifdef LMKD_LOG_STATS
10051050 if (memory_stat_parse_result == 0) {
10061051 stats_write_lmk_kill_occurred(log_ctx, LMK_KILL_OCCURRED, uid, taskname,
10071052 procp->oomadj, mem_st.pgfault, mem_st.pgmajfault, mem_st.rss_in_bytes,
10081053 mem_st.cache_in_bytes, mem_st.swap_in_bytes);
1054+ } else if (enable_stats_log) {
1055+ stats_write_lmk_kill_occurred(log_ctx, LMK_KILL_OCCURRED, uid, taskname, procp->oomadj,
1056+ -1, -1, tasksize * BYTES_IN_KILOBYTE, -1, -1);
10091057 }
10101058 #endif
1011- return tasksize;
1059+ result = tasksize;
10121060 }
10131061
1014- return tasksize;
1062+out:
1063+ /*
1064+ * WARNING: After pid_remove() procp is freed and can't be used!
1065+ * Therefore placed at the end of the function.
1066+ */
1067+ pid_remove(pid);
1068+ return result;
10151069 }
10161070
10171071 /*
@@ -1556,7 +1610,7 @@ int main(int argc __unused, char **argv __unused) {
15561610 (unsigned long)property_get_int32("ro.lmk.kill_timeout_ms", 0);
15571611 use_minfree_levels =
15581612 property_get_bool("ro.lmk.use_minfree_levels", false);
1559-
1613+ per_app_memcg = property_get_bool("ro.config.per_app_memcg", low_ram_device);
15601614 #ifdef LMKD_LOG_STATS
15611615 statslog_init(&log_ctx, &enable_stats_log);
15621616 #endif
--- a/lmkd/statslog.h
+++ b/lmkd/statslog.h
@@ -67,6 +67,9 @@ struct memory_stat {
6767 };
6868
6969 #define MEMCG_PROCESS_MEMORY_STAT_PATH "/dev/memcg/apps/uid_%u/pid_%u/memory.stat"
70+#define PROC_STAT_FILE_PATH "/proc/%d/stat"
71+#define PROC_STAT_BUFFER_SIZE 1024
72+#define BYTES_IN_KILOBYTE 1024
7073
7174 /**
7275 * Logs the change in LMKD state which is used as start/stop boundaries for logging
Show on old repository browser