atomisp: hmm: allow sleep when alloc_private_pages() is trying order == 0
authorDavid Cohen <david.a.cohen@intel.com>
Mon, 26 Mar 2012 08:16:50 +0000 (11:16 +0300)
committerbuildbot <buildbot@intel.com>
Tue, 10 Apr 2012 20:18:43 +0000 (13:18 -0700)
BZ: 27472

For performance purpose, alloc_private_pages() tries to allocate pages
without allowing to sleep. But such approach may fail when system isn't
yet running out of memory.
This patch allows alloc_pages() to sleep when page order == 0, which
happens after a bigger order failed in atomic mode or even in case it was
the original requested order.

Change-Id: I9f1c83eac3aae973b4c7a2961a1b9c7dec3e72a6
Signed-off-by: David Cohen <david.a.cohen@intel.com>
Signed-off-by: Tuukka Toivonen <tuukka.toivonen@intel.com>
Tested-by: Vinod Govindapillai <vinod.govindapillai@intel.com>
Reviewed-on: http://android.intel.com:8080/40704
Reviewed-by: Koskinen, Ilkka <ilkka.koskinen@intel.com>
Reviewed-by: Kruger, Jozef <jozef.kruger@intel.com>
Tested-by: Lampila, KalleX <kallex.lampila@intel.com>
Reviewed-by: Wang, Wen W <wen.w.wang@intel.com>
Reviewed-by: Laakso, Antti <antti.laakso@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/media/video/atomisp/hmm/hmm_bo.c

index 883eb93..eb26e11 100644 (file)
@@ -315,7 +315,7 @@ static int alloc_private_pages(struct hmm_buffer_object *bo, int from_highmem,
        unsigned int pgnr, order, blk_pgnr;
        struct page *pages;
        struct page_block *pgblk;
-       gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN;
+       gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN; /* REVISIT: need __GFP_FS too? */
        int i, j;
        int failure_number = 0;
        bool reduce_order = false;
@@ -344,6 +344,20 @@ static int alloc_private_pages(struct hmm_buffer_object *bo, int from_highmem,
                else if (order > HMM_MAX_ORDER)
                        order = HMM_MAX_ORDER;
 retry:
+               /*
+                * When order > HMM_MIN_ORDER, for performance reasons we don't
+                * want alloc_pages() to sleep. In case it fails and fallbacks
+                * to HMM_MIN_ORDER or in case the requested order is originally
+                * the minimum value, we can allow alloc_pages() to sleep for
+                * robustness purpose.
+                *
+                * REVISIT: why __GFP_FS is necessary?
+                */
+               if (order == HMM_MIN_ORDER) {
+                       gfp &= ~GFP_NOWAIT;
+                       gfp |= __GFP_WAIT | __GFP_FS;
+               }
+
                pages = alloc_pages(gfp, order);
                if (unlikely(!pages)) {
                        /*
@@ -354,13 +368,10 @@ retry:
                         */
                        if (order == HMM_MIN_ORDER) {
                                v4l2_err(&atomisp_dev,
-                                        "out of memory in alloc_pages\n");
+                                        "%s: cannot allocate pages\n",
+                                        __func__);
                                goto cleanup;
                        }
-                       v4l2_warn(&atomisp_dev,
-                                 "allocate order=%d pages failed."
-                                 "reduing page order to %d.\n",
-                                 order, HMM_MIN_ORDER);
                        order = HMM_MIN_ORDER;
                        failure_number++;
                        reduce_order = true;