mempool: fix first round failure behavior
[firefly-linux-kernel-4.4.55.git] / mm / mempool.c
index e3a802a0cea096811bf911ba271f2b302d9c110d..d9049811f3521bc690ff1535831b87dc3b682fe4 100644 (file)
@@ -221,14 +221,23 @@ repeat_alloc:
                return element;
        }
 
-       /* We must not sleep in the GFP_ATOMIC case */
+       /*
+        * We use gfp mask w/o __GFP_WAIT or IO for the first round.  If
+        * alloc failed with that and @pool was empty, retry immediately.
+        */
+       if (gfp_temp != gfp_mask) {
+               spin_unlock_irqrestore(&pool->lock, flags);
+               gfp_temp = gfp_mask;
+               goto repeat_alloc;
+       }
+
+       /* We must not sleep if !__GFP_WAIT */
        if (!(gfp_mask & __GFP_WAIT)) {
                spin_unlock_irqrestore(&pool->lock, flags);
                return NULL;
        }
 
        /* Let's wait for someone else to return an element to @pool */
-       gfp_temp = gfp_mask;
        init_wait(&wait);
        prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);