summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Mark <lmark@codeaurora.org>2014-03-10 16:06:39 -0700
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-13 11:10:16 -0700
commitf47218c220b6fe29c5440bec65ec4b8bb1ac030b (patch)
treec3339a73026347f6da2dfde47dace40293f4845c
parent55fc1595ecb35f8f3ba263d534047f24f04b75f8 (diff)
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. Change-Id: I938644584f374763d10d429d835e74daa4854a38 Signed-off-by: Liam Mark <lmark@codeaurora.org>
-rw-r--r--drivers/staging/android/lowmemorykiller.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 347becf1cc35..0536ba2672af 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -179,6 +179,36 @@ 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;
@@ -189,6 +219,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);