Merge "lmkd: Add meminfo logging after each kill for easy troubleshooting"
am: 7bb1ae2d88
Change-Id: Ie54654d0dd35b9549b017a7e2d10b80536e4a3af
diff --git a/lmkd/Android.bp b/lmkd/Android.bp
index 1369b8b..903d0e2 100644
--- a/lmkd/Android.bp
+++ b/lmkd/Android.bp
@@ -20,6 +20,7 @@
],
},
},
+ logtags: ["event.logtags"],
}
cc_library_static {
diff --git a/lmkd/event.logtags b/lmkd/event.logtags
new file mode 100644
index 0000000..7c2cd18
--- /dev/null
+++ b/lmkd/event.logtags
@@ -0,0 +1,38 @@
+# The entries in this file map a sparse set of log tag numbers to tag names.
+# This is installed on the device, in /system/etc, and parsed by logcat.
+#
+# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
+# negative values alone for now.)
+#
+# Tag names are one or more ASCII letters and numbers or underscores, i.e.
+# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
+# impacts log readability, the latter makes regex searches more annoying).
+#
+# Tag numbers and names are separated by whitespace. Blank lines and lines
+# starting with '#' are ignored.
+#
+# Optionally, after the tag names can be put a description for the value(s)
+# of the tag. Description are in the format
+# (<name>|data type[|data unit])
+# Multiple values are separated by commas.
+#
+# The data type is a number from the following values:
+# 1: int
+# 2: long
+# 3: string
+# 4: list
+#
+# The data unit is a number taken from the following list:
+# 1: Number of objects
+# 2: Number of bytes
+# 3: Number of milliseconds
+# 4: Number of allocations
+# 5: Id
+# 6: Percent
+# s: Number of seconds (monotonic time)
+# Default value for data of type int/long is 2 (bytes).
+#
+# TODO: generate ".java" and ".h" files with integer constants from this file.
+
+# for meminfo logs
+10195355 meminfo (MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(ION_heap|1),(ION_heap_pool|1),(CmaFree|1)
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index a14d0e5..166edb6 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -37,6 +37,7 @@
#include <cutils/sockets.h>
#include <lmkd.h>
#include <log/log.h>
+#include <log/log_event_list.h>
#ifdef LMKD_LOG_STATS
#include "statslog.h"
@@ -72,6 +73,9 @@
#define MEMINFO_PATH "/proc/meminfo"
#define LINE_MAX 128
+/* Android Logger event logtags (see event.logtags) */
+#define MEMINFO_LOG_TAG 10195355
+
/* gid containing AID_SYSTEM required */
#define INKERNEL_MINFREE_PATH "/sys/module/lowmemorykiller/parameters/minfree"
#define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj"
@@ -85,6 +89,8 @@
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define STRINGIFY_INTERNAL(x) #x
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+
/* default to old in-kernel interface if no memory pressure events */
static bool use_inkernel_interface = true;
static bool has_inkernel_module;
@@ -120,6 +126,8 @@
static bool use_minfree_levels;
static bool per_app_memcg;
+static android_log_context ctx;
+
/* data required to handle events */
struct event_handler_info {
int data;
@@ -198,7 +206,17 @@
MI_SHMEM,
MI_UNEVICTABLE,
MI_FREE_SWAP,
- MI_DIRTY,
+ MI_ACTIVE_ANON,
+ MI_INACTIVE_ANON,
+ MI_ACTIVE_FILE,
+ MI_INACTIVE_FILE,
+ MI_SRECLAIMABLE,
+ MI_SUNRECLAIM,
+ MI_KERNEL_STACK,
+ MI_PAGE_TABLES,
+ MI_ION_HELP,
+ MI_ION_HELP_POOL,
+ MI_CMA_FREE,
MI_FIELD_COUNT
};
@@ -210,7 +228,17 @@
"Shmem:",
"Unevictable:",
"SwapFree:",
- "Dirty:",
+ "Active(anon):",
+ "Inactive(anon):",
+ "Active(file):",
+ "Inactive(file):",
+ "SReclaimable:",
+ "SUnreclaim:",
+ "KernelStack:",
+ "PageTables:",
+ "ION_heap:",
+ "ION_heap_pool:",
+ "CmaFree:",
};
union meminfo {
@@ -222,7 +250,17 @@
int64_t shmem;
int64_t unevictable;
int64_t free_swap;
- int64_t dirty;
+ int64_t active_anon;
+ int64_t inactive_anon;
+ int64_t active_file;
+ int64_t inactive_file;
+ int64_t sreclaimable;
+ int64_t sunreclaimable;
+ int64_t kernel_stack;
+ int64_t page_tables;
+ int64_t ion_heap;
+ int64_t ion_heap_pool;
+ int64_t cma_free;
/* fields below are calculated rather than read from the file */
int64_t nr_file_pages;
} field;
@@ -915,6 +953,15 @@
return 0;
}
+static void meminfo_log(union meminfo *mi) {
+ for (int field_idx = 0; field_idx < MI_FIELD_COUNT; field_idx++) {
+ android_log_write_int32(ctx, (int32_t)min(mi->arr[field_idx] * page_k, INT32_MAX));
+ }
+
+ android_log_write_list(ctx, LOG_ID_EVENTS);
+ android_log_reset(ctx);
+}
+
static int proc_get_size(int pid) {
char path[PATH_MAX];
char line[LINE_MAX];
@@ -1322,6 +1369,8 @@
if (debug_process_killing) {
ALOGI("Nothing to kill");
}
+ } else {
+ meminfo_log(&mi);
}
} else {
int pages_freed;
@@ -1370,6 +1419,9 @@
pages_to_free, pages_freed);
gettimeofday(&last_report_tm, NULL);
}
+ if (pages_freed > 0) {
+ meminfo_log(&mi);
+ }
}
}
@@ -1584,6 +1636,8 @@
per_app_memcg =
property_get_bool("ro.config.per_app_memcg", low_ram_device);
+ ctx = create_android_logger(MEMINFO_LOG_TAG);
+
#ifdef LMKD_LOG_STATS
statslog_init(&log_ctx, &enable_stats_log);
#endif
@@ -1619,6 +1673,8 @@
statslog_destroy(&log_ctx);
#endif
+ android_log_destroy(&ctx);
+
ALOGI("exiting");
return 0;
}