mm: memcg: remove unneeded checks from uncharge_page()
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / mempool.c
index 11f0d0a..d904981 100644 (file)
@@ -27,7 +27,15 @@ static void *remove_element(mempool_t *pool)
        return pool->elements[--pool->curr_nr];
 }
 
-static void free_pool(mempool_t *pool)
+/**
+ * mempool_destroy - deallocate a memory pool
+ * @pool:      pointer to the memory pool which was allocated via
+ *             mempool_create().
+ *
+ * Free all reserved elements in @pool and @pool itself.  This function
+ * only sleeps if the free_fn() function sleeps.
+ */
+void mempool_destroy(mempool_t *pool)
 {
        while (pool->curr_nr) {
                void *element = remove_element(pool);
@@ -36,6 +44,7 @@ static void free_pool(mempool_t *pool)
        kfree(pool->elements);
        kfree(pool);
 }
+EXPORT_SYMBOL(mempool_destroy);
 
 /**
  * mempool_create - create a memory pool
@@ -86,7 +95,7 @@ mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
 
                element = pool->alloc(GFP_KERNEL, pool->pool_data);
                if (unlikely(!element)) {
-                       free_pool(pool);
+                       mempool_destroy(pool);
                        return NULL;
                }
                add_element(pool, element);
@@ -172,23 +181,6 @@ out:
 EXPORT_SYMBOL(mempool_resize);
 
 /**
- * mempool_destroy - deallocate a memory pool
- * @pool:      pointer to the memory pool which was allocated via
- *             mempool_create().
- *
- * this function only sleeps if the free_fn() function sleeps. The caller
- * has to guarantee that all elements have been returned to the pool (ie:
- * freed) prior to calling mempool_destroy().
- */
-void mempool_destroy(mempool_t *pool)
-{
-       /* Check for outstanding elements */
-       BUG_ON(pool->curr_nr != pool->min_nr);
-       free_pool(pool);
-}
-EXPORT_SYMBOL(mempool_destroy);
-
-/**
  * mempool_alloc - allocate an element from a specific memory pool
  * @pool:      pointer to the memory pool which was allocated via
  *             mempool_create().
@@ -229,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);