summaryrefslogtreecommitdiffstats
path: root/lmkd/lmkd.c
diff options
context:
space:
mode:
authorSuren Baghdasaryan <surenb@google.com>2018-04-13 13:41:12 -0700
committerSuren Baghdasaryan <surenb@google.com>2018-04-15 10:03:05 +0000
commit45c9e0b30ca100714566629d4fa6511cae829470 (patch)
tree069260010484cd6149d4e9e92155873d062fc1d6 /lmkd/lmkd.c
parentb62d5ed25e77cf0983f2686c99271fd69aa704b6 (diff)
downloadsystem_core-45c9e0b30ca100714566629d4fa6511cae829470.tar.gz
system_core-45c9e0b30ca100714566629d4fa6511cae829470.tar.bz2
system_core-45c9e0b30ca100714566629d4fa6511cae829470.zip
lmkd: Switch to using /proc/meminfo to have access to file cache size
Current mechanism of getting system memory state by using sysinfo() is not enough because it does not provide information about file cache size which is needed to correctly assess memory state. Switch to using data from /proc/meminfo that includes information provided by sysinfo() and file cache size in addition to that. Bug: 77299493 Bug: 75322373 Merged-In: I16106fc4f9254f17f776803e60502b7b6474e1b7 Change-Id: I16106fc4f9254f17f776803e60502b7b6474e1b7 Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Diffstat (limited to 'lmkd/lmkd.c')
-rw-r--r--lmkd/lmkd.c79
1 files changed, 30 insertions, 49 deletions
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 77830a346..5eb3fbe15 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -95,14 +95,9 @@ static const char *level_name[] = {
"critical"
};
-struct mem_size {
- int free_mem;
- int free_swap;
-};
-
struct {
- int min_free; /* recorded but not used yet */
- int max_free;
+ int64_t min_nr_free_pages; /* recorded but not used yet */
+ int64_t max_nr_free_pages;
} low_pressure_mem = { -1, -1 };
static int level_oomadj[VMPRESS_LEVEL_COUNT];
@@ -230,13 +225,6 @@ enum field_match_result {
PARSE_SUCCESS
};
-struct sysmeminfo {
- int nr_free_pages;
- int nr_file_pages;
- int nr_shmem;
- int totalreserve_pages;
-};
-
struct adjslot_list {
struct adjslot_list *next;
struct adjslot_list *prev;
@@ -862,18 +850,6 @@ static int meminfo_parse(union meminfo *mi) {
return 0;
}
-static int get_free_memory(struct mem_size *ms) {
- struct sysinfo si;
-
- if (sysinfo(&si) < 0)
- return -1;
-
- ms->free_mem = (int)(si.freeram * si.mem_unit / PAGE_SIZE);
- ms->free_swap = (int)(si.freeswap * si.mem_unit / PAGE_SIZE);
-
- return 0;
-}
-
static int proc_get_size(int pid) {
char path[PATH_MAX];
char line[LINE_MAX];
@@ -1045,29 +1021,30 @@ static int64_t get_memory_usage(struct reread_data *file_data) {
return mem_usage;
}
-void record_low_pressure_levels(struct mem_size *free_mem) {
- if (low_pressure_mem.min_free == -1 ||
- low_pressure_mem.min_free > free_mem->free_mem) {
+void record_low_pressure_levels(union meminfo *mi) {
+ if (low_pressure_mem.min_nr_free_pages == -1 ||
+ low_pressure_mem.min_nr_free_pages > mi->field.nr_free_pages) {
if (debug_process_killing) {
- ALOGI("Low pressure min memory update from %d to %d",
- low_pressure_mem.min_free, free_mem->free_mem);
+ ALOGI("Low pressure min memory update from %" PRId64 " to %" PRId64,
+ low_pressure_mem.min_nr_free_pages, mi->field.nr_free_pages);
}
- low_pressure_mem.min_free = free_mem->free_mem;
+ low_pressure_mem.min_nr_free_pages = mi->field.nr_free_pages;
}
/*
* Free memory at low vmpressure events occasionally gets spikes,
* possibly a stale low vmpressure event with memory already
* freed up (no memory pressure should have been reported).
- * Ignore large jumps in max_free that would mess up our stats.
+ * Ignore large jumps in max_nr_free_pages that would mess up our stats.
*/
- if (low_pressure_mem.max_free == -1 ||
- (low_pressure_mem.max_free < free_mem->free_mem &&
- free_mem->free_mem - low_pressure_mem.max_free < low_pressure_mem.max_free * 0.1)) {
+ if (low_pressure_mem.max_nr_free_pages == -1 ||
+ (low_pressure_mem.max_nr_free_pages < mi->field.nr_free_pages &&
+ mi->field.nr_free_pages - low_pressure_mem.max_nr_free_pages <
+ low_pressure_mem.max_nr_free_pages * 0.1)) {
if (debug_process_killing) {
- ALOGI("Low pressure max memory update from %d to %d",
- low_pressure_mem.max_free, free_mem->free_mem);
+ ALOGI("Low pressure max memory update from %" PRId64 " to %" PRId64,
+ low_pressure_mem.max_nr_free_pages, mi->field.nr_free_pages);
}
- low_pressure_mem.max_free = free_mem->free_mem;
+ low_pressure_mem.max_nr_free_pages = mi->field.nr_free_pages;
}
}
@@ -1093,7 +1070,7 @@ static void mp_event_common(int data, uint32_t events __unused) {
int64_t mem_usage, memsw_usage;
int64_t mem_pressure;
enum vmpressure_level lvl;
- struct mem_size free_mem;
+ union meminfo mi;
static struct timeval last_report_tm;
static unsigned long skip_count = 0;
enum vmpressure_level level = (enum vmpressure_level)data;
@@ -1137,15 +1114,15 @@ static void mp_event_common(int data, uint32_t events __unused) {
skip_count = 0;
}
- if (get_free_memory(&free_mem) == 0) {
- if (level == VMPRESS_LEVEL_LOW) {
- record_low_pressure_levels(&free_mem);
- }
- } else {
+ if (meminfo_parse(&mi) < 0) {
ALOGE("Failed to get free memory!");
return;
}
+ if (level == VMPRESS_LEVEL_LOW) {
+ record_low_pressure_levels(&mi);
+ }
+
if (level_oomadj[level] > OOM_SCORE_ADJ_MAX) {
/* Do not monitor this pressure level */
return;
@@ -1197,16 +1174,20 @@ do_kill:
}
} else {
/* If pressure level is less than critical and enough free swap then ignore */
- if (level < VMPRESS_LEVEL_CRITICAL && free_mem.free_swap > low_pressure_mem.max_free) {
+ if (level < VMPRESS_LEVEL_CRITICAL &&
+ mi.field.free_swap > low_pressure_mem.max_nr_free_pages) {
if (debug_process_killing) {
- ALOGI("Ignoring pressure since %d swap pages are available ", free_mem.free_swap);
+ ALOGI("Ignoring pressure since %" PRId64
+ " swap pages are available ",
+ mi.field.free_swap);
}
return;
}
/* Free up enough memory to downgrate the memory pressure to low level */
- if (free_mem.free_mem < low_pressure_mem.max_free) {
- int pages_to_free = low_pressure_mem.max_free - free_mem.free_mem;
+ if (mi.field.nr_free_pages < low_pressure_mem.max_nr_free_pages) {
+ int pages_to_free = low_pressure_mem.max_nr_free_pages -
+ mi.field.nr_free_pages;
if (debug_process_killing) {
ALOGI("Trying to free %d pages", pages_to_free);
}