From b011fc4ddca4f4b866203f3e20210ffee2d59abc Mon Sep 17 00:00:00 2001 From: Naveen Ramaraj <nramaraj@codeaurora.org> Date: Tue, 30 Sep 2014 15:16:18 -0700 Subject: [PATCH] lowmemorykiller: Account for highmem during kswapd reclaim Currenlty most memory reclaim is done through kswapd. Since kswapd uses a gfp mask of GFP_KERNEL, and because the lowmemorykiller is zone aware, the lowmemorykiller will ignore highmem most of the time. This results in the lowmemorykiller being overly aggressive. The fix to this issue is to allow the lowmemorykiller to count highmem when being called by the kswapd if the lowmem watermarks are satisfied. Bug: 17494249 Change-Id: I5fd3895ce242ccac0e777b003c3893685e061ff3 Signed-off-by: Liam Mark <lmark@codeaurora.org> Signed-off-by: Naveen Ramaraj <nramaraj@codeaurora.org> --- drivers/staging/android/lowmemorykiller.c | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 4a9dd1b4a060..60b2ded6d532 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -153,6 +153,35 @@ void tune_lmk_zone_param(struct zonelist *zonelist, int classzone_idx, } } +#ifdef CONFIG_HIGHMEM +void adjust_gfp_mask(gfp_t *gfp_mask) +{ + struct zone *preferred_zone; + struct zonelist *zonelist; + enum zone_type high_zoneidx; + + if (current_is_kswapd()) { + zonelist = node_zonelist(0, *gfp_mask); + high_zoneidx = gfp_zone(*gfp_mask); + first_zones_zonelist(zonelist, high_zoneidx, NULL, + &preferred_zone); + + if (high_zoneidx == ZONE_NORMAL) { + if (zone_watermark_ok_safe(preferred_zone, 0, + high_wmark_pages(preferred_zone), 0, + 0)) + *gfp_mask |= __GFP_HIGHMEM; + } else if (high_zoneidx == ZONE_HIGHMEM) { + *gfp_mask |= __GFP_HIGHMEM; + } + } +} +#else +void adjust_gfp_mask(gfp_t *unused) +{ +} +#endif + void tune_lmk_param(int *other_free, int *other_file, struct shrink_control *sc) { gfp_t gfp_mask; @@ -163,6 +192,8 @@ void tune_lmk_param(int *other_free, int *other_file, struct shrink_control *sc) int use_cma_pages; gfp_mask = sc->gfp_mask; + adjust_gfp_mask(&gfp_mask); + zonelist = node_zonelist(0, gfp_mask); high_zoneidx = gfp_zone(gfp_mask); first_zones_zonelist(zonelist, high_zoneidx, NULL, &preferred_zone); -- GitLab