android: lowmemorykiller: add lmk parameters tunning code.

There are cases that LMK doesn't run, even when it must run.
It is due to LMK shrinker not considering memory status per zone.
So add LMK parameters(other_free, other_file) tunnig code to
consider target zone of LMK shrinker.

Change-Id: I6f1f8660d5da920a0e3af45a160499965032081d
Git-commit: 22d990a58fc17b3f0155e15eb2dc3efa037bea1c
Git-repo: https://android.googlesource.com/kernel/common/
[ohaugan@codeaurora.org: Fix compilation issues]
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
Signed-off-by: Liam Mark <lmark@codeaurora.org>
This commit is contained in:
seungho1.park 2012-07-24 10:20:44 +09:00 committed by Jeevan Shriram
parent 21f86651a6
commit e4c1c94265

View file

@ -44,6 +44,13 @@
#include <linux/notifier.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/swap.h>
#ifdef CONFIG_HIGHMEM
#define _ZONE ZONE_HIGHMEM
#else
#define _ZONE ZONE_NORMAL
#endif
#define CREATE_TRACE_POINTS
#include "trace/lowmemorykiller.h"
@ -63,6 +70,7 @@ static int lowmem_minfree[6] = {
16 * 1024, /* 64MB */
};
static int lowmem_minfree_size = 4;
static int lmk_fast_run = 1;
static unsigned long lowmem_deathpending_timeout;
@ -99,6 +107,82 @@ static int test_task_flag(struct task_struct *p, int flag)
static DEFINE_MUTEX(scan_mutex);
void tune_lmk_zone_param(struct zonelist *zonelist, int classzone_idx,
int *other_free, int *other_file)
{
struct zone *zone;
struct zoneref *zoneref;
int zone_idx;
for_each_zone_zonelist(zone, zoneref, zonelist, MAX_NR_ZONES) {
if ((zone_idx = zonelist_zone_idx(zoneref)) == ZONE_MOVABLE)
continue;
if (zone_idx > classzone_idx) {
if (other_free != NULL)
*other_free -= zone_page_state(zone,
NR_FREE_PAGES);
if (other_file != NULL)
*other_file -= zone_page_state(zone,
NR_FILE_PAGES)
- zone_page_state(zone, NR_SHMEM);
} else if (zone_idx < classzone_idx) {
if (zone_watermark_ok(zone, 0, 0, classzone_idx, 0))
*other_free -=
zone->lowmem_reserve[classzone_idx];
else
*other_free -=
zone_page_state(zone, NR_FREE_PAGES);
}
}
}
void tune_lmk_param(int *other_free, int *other_file, struct shrink_control *sc)
{
gfp_t gfp_mask;
struct zone *preferred_zone;
struct zonelist *zonelist;
enum zone_type high_zoneidx, classzone_idx;
unsigned long balance_gap;
gfp_mask = sc->gfp_mask;
zonelist = node_zonelist(0, gfp_mask);
high_zoneidx = gfp_zone(gfp_mask);
first_zones_zonelist(zonelist, high_zoneidx, NULL, &preferred_zone);
classzone_idx = zone_idx(preferred_zone);
balance_gap = min(low_wmark_pages(preferred_zone),
(preferred_zone->present_pages +
KSWAPD_ZONE_BALANCE_GAP_RATIO-1) /
KSWAPD_ZONE_BALANCE_GAP_RATIO);
if (likely(current_is_kswapd() && zone_watermark_ok(preferred_zone, 0,
high_wmark_pages(preferred_zone) + SWAP_CLUSTER_MAX +
balance_gap, 0, 0))) {
if (lmk_fast_run)
tune_lmk_zone_param(zonelist, classzone_idx, other_free,
other_file);
else
tune_lmk_zone_param(zonelist, classzone_idx, other_free,
NULL);
if (zone_watermark_ok(preferred_zone, 0, 0, _ZONE, 0))
*other_free -=
preferred_zone->lowmem_reserve[_ZONE];
else
*other_free -= zone_page_state(preferred_zone,
NR_FREE_PAGES);
lowmem_print(4, "lowmem_shrink of kswapd tunning for highmem "
"ofree %d, %d\n", *other_free, *other_file);
} else {
tune_lmk_zone_param(zonelist, classzone_idx, other_free,
other_file);
lowmem_print(4, "lowmem_shrink tunning for others ofree %d, "
"%d\n", *other_free, *other_file);
}
}
static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
{
struct task_struct *tsk;
@ -122,6 +206,8 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc)
global_page_state(NR_SHMEM) -
total_swapcache_pages();
tune_lmk_param(&other_free, &other_file, sc);
if (lowmem_adj_size < array_size)
array_size = lowmem_adj_size;
if (lowmem_minfree_size < array_size)
@ -343,4 +429,5 @@ module_param_array_named(adj, lowmem_adj, short, &lowmem_adj_size,
module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
S_IRUGO | S_IWUSR);
module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
module_param_named(lmk_fast_run, lmk_fast_run, int, S_IRUGO | S_IWUSR);