Merge branches 'acpi-pm' and 'acpi-docs'
[linux-2.6-microblaze.git] / mm / zsmalloc.c
index 7289f50..30c358b 100644 (file)
@@ -357,7 +357,7 @@ static void cache_free_handle(struct zs_pool *pool, unsigned long handle)
 
 static struct zspage *cache_alloc_zspage(struct zs_pool *pool, gfp_t flags)
 {
-       return kmem_cache_alloc(pool->zspage_cachep,
+       return kmem_cache_zalloc(pool->zspage_cachep,
                        flags & ~(__GFP_HIGHMEM|__GFP_MOVABLE));
 }
 
@@ -816,7 +816,7 @@ static int get_pages_per_zspage(int class_size)
 
 static struct zspage *get_zspage(struct page *page)
 {
-       struct zspage *zspage = (struct zspage *)page->private;
+       struct zspage *zspage = (struct zspage *)page_private(page);
 
        BUG_ON(zspage->magic != ZSPAGE_MAGIC);
        return zspage;
@@ -1064,7 +1064,6 @@ static struct zspage *alloc_zspage(struct zs_pool *pool,
        if (!zspage)
                return NULL;
 
-       memset(zspage, 0, sizeof(struct zspage));
        zspage->magic = ZSPAGE_MAGIC;
        migrate_lock_init(zspage);
 
@@ -2213,11 +2212,13 @@ static unsigned long zs_can_compact(struct size_class *class)
        return obj_wasted * class->pages_per_zspage;
 }
 
-static void __zs_compact(struct zs_pool *pool, struct size_class *class)
+static unsigned long __zs_compact(struct zs_pool *pool,
+                                 struct size_class *class)
 {
        struct zs_compact_control cc;
        struct zspage *src_zspage;
        struct zspage *dst_zspage = NULL;
+       unsigned long pages_freed = 0;
 
        spin_lock(&class->lock);
        while ((src_zspage = isolate_zspage(class, true))) {
@@ -2247,7 +2248,7 @@ static void __zs_compact(struct zs_pool *pool, struct size_class *class)
                putback_zspage(class, dst_zspage);
                if (putback_zspage(class, src_zspage) == ZS_EMPTY) {
                        free_zspage(pool, class, src_zspage);
-                       pool->stats.pages_compacted += class->pages_per_zspage;
+                       pages_freed += class->pages_per_zspage;
                }
                spin_unlock(&class->lock);
                cond_resched();
@@ -2258,12 +2259,15 @@ static void __zs_compact(struct zs_pool *pool, struct size_class *class)
                putback_zspage(class, src_zspage);
 
        spin_unlock(&class->lock);
+
+       return pages_freed;
 }
 
 unsigned long zs_compact(struct zs_pool *pool)
 {
        int i;
        struct size_class *class;
+       unsigned long pages_freed = 0;
 
        for (i = ZS_SIZE_CLASSES - 1; i >= 0; i--) {
                class = pool->size_class[i];
@@ -2271,10 +2275,11 @@ unsigned long zs_compact(struct zs_pool *pool)
                        continue;
                if (class->index != i)
                        continue;
-               __zs_compact(pool, class);
+               pages_freed += __zs_compact(pool, class);
        }
+       atomic_long_add(pages_freed, &pool->stats.pages_compacted);
 
-       return pool->stats.pages_compacted;
+       return pages_freed;
 }
 EXPORT_SYMBOL_GPL(zs_compact);
 
@@ -2291,13 +2296,12 @@ static unsigned long zs_shrinker_scan(struct shrinker *shrinker,
        struct zs_pool *pool = container_of(shrinker, struct zs_pool,
                        shrinker);
 
-       pages_freed = pool->stats.pages_compacted;
        /*
         * Compact classes and calculate compaction delta.
         * Can run concurrently with a manually triggered
         * (by user) compaction.
         */
-       pages_freed = zs_compact(pool) - pages_freed;
+       pages_freed = zs_compact(pool);
 
        return pages_freed ? pages_freed : SHRINK_STOP;
 }