BZ: 17272
when there are not enough memory in kernel, allocation pages maybe fails and
then sleep, so system will block in kernel and can not exit. to avoid this
case, we modify allocation pages flag to GFP_NOWAIT(not will sleep when
allocation). and modify allocation mechanism.
Change-Id: If5362583197a650bcb6d05b1a811d2a18967468c
Orig-Change-Id: I7e687b1a9107ebeedb71f6ce84a25b19169520af
Signed-off-by: ziyux.jiang <ziyux.jiang@intel.com>
Reviewed-on: http://android.intel.com:8080/25504
Reviewed-by: Zheng, ZixiangX <zixiangx.zheng@intel.com>
Reviewed-by: Hu, Gang A <gang.a.hu@intel.com>
Reviewed-by: Wang, Wen W <wen.w.wang@intel.com>
Reviewed-by: Cohen, David A <david.a.cohen@intel.com>
Tested-by: Ilvonen, Ville <ville.ilvonen@intel.com>
Reviewed-by: Koskinen, Ilkka <ilkka.koskinen@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
Reviewed-on: http://android.intel.com:8080/28049
Reviewed-by: Tuominen, TeemuX <teemux.tuominen@intel.com>
Reviewed-by: Koski, Anttu <anttu.koski@intel.com>
Tested-by: Koski, Anttu <anttu.koski@intel.com>
unsigned int pgnr, order, blk_pgnr;
struct page *pages;
struct page_block *pgblk;
- gfp_t gfp;
+ gfp_t gfp = GFP_NOWAIT;
int i, j;
+ int failure_number = 0;
+ bool reduce_order = false;
+ bool lack_mem = false;
+
- gfp = GFP_KERNEL;
if (from_highmem)
gfp |= __GFP_HIGHMEM;
i = 0;
while (pgnr) {
order = nr_to_order_bottom(pgnr);
- if (order > HMM_MAX_ORDER)
+ /*
+ * if be short of memory, we will set order to 0
+ * everytime
+ */
+ if (lack_mem)
+ order = HMM_MIN_ORDER;
+ else if (order > HMM_MAX_ORDER)
order = HMM_MAX_ORDER;
retry:
pages = alloc_pages(gfp, order);
"reduing page order to %d.\n",
order, HMM_MIN_ORDER);
order = HMM_MIN_ORDER;
+ failure_number++;
+ reduce_order = true;
+ /*
+ * if fail two times continuously, we think be
+ * short of memory now
+ */
+ if (failure_number == 2) {
+ lack_mem = true;
+ failure_number = 0;
+ }
goto retry;
} else {
blk_pgnr = order_to_nr(order);
goto cleanup;
}
}
+
+ /*
+ * if order is not reduced this time, clear
+ * failure number
+ */
+ if (reduce_order)
+ reduce_order = false;
+ else
+ failure_number = 0;
}
}