Merge branch 'akpm' (patches from Andrew)
[linux-2.6-microblaze.git] / mm / z3fold.c
index 9d889ad..b3c0577 100644 (file)
@@ -62,7 +62,7 @@
 #define ZHDR_SIZE_ALIGNED round_up(sizeof(struct z3fold_header), CHUNK_SIZE)
 #define ZHDR_CHUNKS    (ZHDR_SIZE_ALIGNED >> CHUNK_SHIFT)
 #define TOTAL_CHUNKS   (PAGE_SIZE >> CHUNK_SHIFT)
-#define NCHUNKS                ((PAGE_SIZE - ZHDR_SIZE_ALIGNED) >> CHUNK_SHIFT)
+#define NCHUNKS                (TOTAL_CHUNKS - ZHDR_CHUNKS)
 
 #define BUDDY_MASK     (0x3)
 #define BUDDY_SHIFT    2
@@ -144,6 +144,8 @@ struct z3fold_header {
  * @c_handle:  cache for z3fold_buddy_slots allocation
  * @ops:       pointer to a structure of user defined operations specified at
  *             pool creation time.
+ * @zpool:     zpool driver
+ * @zpool_ops: zpool operations structure with an evict callback
  * @compact_wq:        workqueue for page layout background optimization
  * @release_wq:        workqueue for safe page release
  * @work:      work_struct for safe page release
@@ -253,9 +255,8 @@ static inline void z3fold_page_unlock(struct z3fold_header *zhdr)
        spin_unlock(&zhdr->page_lock);
 }
 
-
-static inline struct z3fold_header *__get_z3fold_header(unsigned long handle,
-                                                       bool lock)
+/* return locked z3fold page if it's not headless */
+static inline struct z3fold_header *get_z3fold_header(unsigned long handle)
 {
        struct z3fold_buddy_slots *slots;
        struct z3fold_header *zhdr;
@@ -269,13 +270,12 @@ static inline struct z3fold_header *__get_z3fold_header(unsigned long handle,
                        read_lock(&slots->lock);
                        addr = *(unsigned long *)handle;
                        zhdr = (struct z3fold_header *)(addr & PAGE_MASK);
-                       if (lock)
-                               locked = z3fold_page_trylock(zhdr);
+                       locked = z3fold_page_trylock(zhdr);
                        read_unlock(&slots->lock);
                        if (locked)
                                break;
                        cpu_relax();
-               } while (lock);
+               } while (true);
        } else {
                zhdr = (struct z3fold_header *)(handle & PAGE_MASK);
        }
@@ -283,18 +283,6 @@ static inline struct z3fold_header *__get_z3fold_header(unsigned long handle,
        return zhdr;
 }
 
-/* Returns the z3fold page where a given handle is stored */
-static inline struct z3fold_header *handle_to_z3fold_header(unsigned long h)
-{
-       return __get_z3fold_header(h, false);
-}
-
-/* return locked z3fold page if it's not headless */
-static inline struct z3fold_header *get_z3fold_header(unsigned long h)
-{
-       return __get_z3fold_header(h, true);
-}
-
 static inline void put_z3fold_header(struct z3fold_header *zhdr)
 {
        struct page *page = virt_to_page(zhdr);
@@ -391,7 +379,7 @@ static void z3fold_unregister_migration(struct z3fold_pool *pool)
 {
        if (pool->inode)
                iput(pool->inode);
- }
+}
 
 /* Initializes the z3fold header of a newly allocated z3fold page */
 static struct z3fold_header *init_z3fold_page(struct page *page, bool headless,
@@ -998,7 +986,8 @@ static struct z3fold_pool *z3fold_create_pool(const char *name, gfp_t gfp,
                goto out_c;
        spin_lock_init(&pool->lock);
        spin_lock_init(&pool->stale_lock);
-       pool->unbuddied = __alloc_percpu(sizeof(struct list_head)*NCHUNKS, 2);
+       pool->unbuddied = __alloc_percpu(sizeof(struct list_head) * NCHUNKS,
+                                        __alignof__(struct list_head));
        if (!pool->unbuddied)
                goto out_pool;
        for_each_possible_cpu(cpu) {
@@ -1059,6 +1048,7 @@ static void z3fold_destroy_pool(struct z3fold_pool *pool)
        destroy_workqueue(pool->compact_wq);
        destroy_workqueue(pool->release_wq);
        z3fold_unregister_migration(pool);
+       free_percpu(pool->unbuddied);
        kfree(pool);
 }
 
@@ -1382,7 +1372,7 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries)
                        if (zhdr->foreign_handles ||
                            test_and_set_bit(PAGE_CLAIMED, &page->private)) {
                                if (kref_put(&zhdr->refcount,
-                                               release_z3fold_page))
+                                               release_z3fold_page_locked))
                                        atomic64_dec(&pool->pages_nr);
                                else
                                        z3fold_page_unlock(zhdr);
@@ -1803,8 +1793,11 @@ static int __init init_z3fold(void)
 {
        int ret;
 
-       /* Make sure the z3fold header is not larger than the page size */
-       BUILD_BUG_ON(ZHDR_SIZE_ALIGNED > PAGE_SIZE);
+       /*
+        * Make sure the z3fold header is not larger than the page size and
+        * there has remaining spaces for its buddy.
+        */
+       BUILD_BUG_ON(ZHDR_SIZE_ALIGNED > PAGE_SIZE - CHUNK_SIZE);
        ret = z3fold_mount();
        if (ret)
                return ret;