]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - mm/z3fold.c
Merge tag 'metag-for-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/jhogan...
[karo-tx-linux.git] / mm / z3fold.c
1 /*
2  * z3fold.c
3  *
4  * Author: Vitaly Wool <vitaly.wool@konsulko.com>
5  * Copyright (C) 2016, Sony Mobile Communications Inc.
6  *
7  * This implementation is based on zbud written by Seth Jennings.
8  *
9  * z3fold is an special purpose allocator for storing compressed pages. It
10  * can store up to three compressed pages per page which improves the
11  * compression ratio of zbud while retaining its main concepts (e. g. always
12  * storing an integral number of objects per page) and simplicity.
13  * It still has simple and deterministic reclaim properties that make it
14  * preferable to a higher density approach (with no requirement on integral
15  * number of object per page) when reclaim is used.
16  *
17  * As in zbud, pages are divided into "chunks".  The size of the chunks is
18  * fixed at compile time and is determined by NCHUNKS_ORDER below.
19  *
20  * z3fold doesn't export any API and is meant to be used via zpool API.
21  */
22
23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25 #include <linux/atomic.h>
26 #include <linux/list.h>
27 #include <linux/mm.h>
28 #include <linux/module.h>
29 #include <linux/preempt.h>
30 #include <linux/slab.h>
31 #include <linux/spinlock.h>
32 #include <linux/zpool.h>
33
34 /*****************
35  * Structures
36 *****************/
37 struct z3fold_pool;
38 struct z3fold_ops {
39         int (*evict)(struct z3fold_pool *pool, unsigned long handle);
40 };
41
42 enum buddy {
43         HEADLESS = 0,
44         FIRST,
45         MIDDLE,
46         LAST,
47         BUDDIES_MAX
48 };
49
50 /*
51  * struct z3fold_header - z3fold page metadata occupying the first chunk of each
52  *                      z3fold page, except for HEADLESS pages
53  * @buddy:      links the z3fold page into the relevant list in the pool
54  * @page_lock:          per-page lock
55  * @refcount:           reference cound for the z3fold page
56  * @first_chunks:       the size of the first buddy in chunks, 0 if free
57  * @middle_chunks:      the size of the middle buddy in chunks, 0 if free
58  * @last_chunks:        the size of the last buddy in chunks, 0 if free
59  * @first_num:          the starting number (for the first handle)
60  */
61 struct z3fold_header {
62         struct list_head buddy;
63         spinlock_t page_lock;
64         struct kref refcount;
65         unsigned short first_chunks;
66         unsigned short middle_chunks;
67         unsigned short last_chunks;
68         unsigned short start_middle;
69         unsigned short first_num:2;
70 };
71
72 /*
73  * NCHUNKS_ORDER determines the internal allocation granularity, effectively
74  * adjusting internal fragmentation.  It also determines the number of
75  * freelists maintained in each pool. NCHUNKS_ORDER of 6 means that the
76  * allocation granularity will be in chunks of size PAGE_SIZE/64. Some chunks
77  * in the beginning of an allocated page are occupied by z3fold header, so
78  * NCHUNKS will be calculated to 63 (or 62 in case CONFIG_DEBUG_SPINLOCK=y),
79  * which shows the max number of free chunks in z3fold page, also there will
80  * be 63, or 62, respectively, freelists per pool.
81  */
82 #define NCHUNKS_ORDER   6
83
84 #define CHUNK_SHIFT     (PAGE_SHIFT - NCHUNKS_ORDER)
85 #define CHUNK_SIZE      (1 << CHUNK_SHIFT)
86 #define ZHDR_SIZE_ALIGNED round_up(sizeof(struct z3fold_header), CHUNK_SIZE)
87 #define ZHDR_CHUNKS     (ZHDR_SIZE_ALIGNED >> CHUNK_SHIFT)
88 #define TOTAL_CHUNKS    (PAGE_SIZE >> CHUNK_SHIFT)
89 #define NCHUNKS         ((PAGE_SIZE - ZHDR_SIZE_ALIGNED) >> CHUNK_SHIFT)
90
91 #define BUDDY_MASK      (0x3)
92
93 /**
94  * struct z3fold_pool - stores metadata for each z3fold pool
95  * @lock:       protects all pool fields and first|last_chunk fields of any
96  *              z3fold page in the pool
97  * @unbuddied:  array of lists tracking z3fold pages that contain 2- buddies;
98  *              the lists each z3fold page is added to depends on the size of
99  *              its free region.
100  * @lru:        list tracking the z3fold pages in LRU order by most recently
101  *              added buddy.
102  * @pages_nr:   number of z3fold pages in the pool.
103  * @ops:        pointer to a structure of user defined operations specified at
104  *              pool creation time.
105  *
106  * This structure is allocated at pool creation time and maintains metadata
107  * pertaining to a particular z3fold pool.
108  */
109 struct z3fold_pool {
110         spinlock_t lock;
111         struct list_head unbuddied[NCHUNKS];
112         struct list_head lru;
113         atomic64_t pages_nr;
114         const struct z3fold_ops *ops;
115         struct zpool *zpool;
116         const struct zpool_ops *zpool_ops;
117 };
118
119 /*
120  * Internal z3fold page flags
121  */
122 enum z3fold_page_flags {
123         PAGE_HEADLESS = 0,
124         MIDDLE_CHUNK_MAPPED,
125 };
126
127
128 /*****************
129  * Helpers
130 *****************/
131
132 /* Converts an allocation size in bytes to size in z3fold chunks */
133 static int size_to_chunks(size_t size)
134 {
135         return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT;
136 }
137
138 #define for_each_unbuddied_list(_iter, _begin) \
139         for ((_iter) = (_begin); (_iter) < NCHUNKS; (_iter)++)
140
141 /* Initializes the z3fold header of a newly allocated z3fold page */
142 static struct z3fold_header *init_z3fold_page(struct page *page)
143 {
144         struct z3fold_header *zhdr = page_address(page);
145
146         INIT_LIST_HEAD(&page->lru);
147         clear_bit(PAGE_HEADLESS, &page->private);
148         clear_bit(MIDDLE_CHUNK_MAPPED, &page->private);
149
150         spin_lock_init(&zhdr->page_lock);
151         kref_init(&zhdr->refcount);
152         zhdr->first_chunks = 0;
153         zhdr->middle_chunks = 0;
154         zhdr->last_chunks = 0;
155         zhdr->first_num = 0;
156         zhdr->start_middle = 0;
157         INIT_LIST_HEAD(&zhdr->buddy);
158         return zhdr;
159 }
160
161 /* Resets the struct page fields and frees the page */
162 static void free_z3fold_page(struct page *page)
163 {
164         __free_page(page);
165 }
166
167 static void release_z3fold_page(struct kref *ref)
168 {
169         struct z3fold_header *zhdr;
170         struct page *page;
171
172         zhdr = container_of(ref, struct z3fold_header, refcount);
173         page = virt_to_page(zhdr);
174
175         if (!list_empty(&zhdr->buddy))
176                 list_del(&zhdr->buddy);
177         if (!list_empty(&page->lru))
178                 list_del(&page->lru);
179         free_z3fold_page(page);
180 }
181
182 /* Lock a z3fold page */
183 static inline void z3fold_page_lock(struct z3fold_header *zhdr)
184 {
185         spin_lock(&zhdr->page_lock);
186 }
187
188 /* Try to lock a z3fold page */
189 static inline int z3fold_page_trylock(struct z3fold_header *zhdr)
190 {
191         return spin_trylock(&zhdr->page_lock);
192 }
193
194 /* Unlock a z3fold page */
195 static inline void z3fold_page_unlock(struct z3fold_header *zhdr)
196 {
197         spin_unlock(&zhdr->page_lock);
198 }
199
200 /*
201  * Encodes the handle of a particular buddy within a z3fold page
202  * Pool lock should be held as this function accesses first_num
203  */
204 static unsigned long encode_handle(struct z3fold_header *zhdr, enum buddy bud)
205 {
206         unsigned long handle;
207
208         handle = (unsigned long)zhdr;
209         if (bud != HEADLESS)
210                 handle += (bud + zhdr->first_num) & BUDDY_MASK;
211         return handle;
212 }
213
214 /* Returns the z3fold page where a given handle is stored */
215 static struct z3fold_header *handle_to_z3fold_header(unsigned long handle)
216 {
217         return (struct z3fold_header *)(handle & PAGE_MASK);
218 }
219
220 /*
221  * (handle & BUDDY_MASK) < zhdr->first_num is possible in encode_handle
222  *  but that doesn't matter. because the masking will result in the
223  *  correct buddy number.
224  */
225 static enum buddy handle_to_buddy(unsigned long handle)
226 {
227         struct z3fold_header *zhdr = handle_to_z3fold_header(handle);
228         return (handle - zhdr->first_num) & BUDDY_MASK;
229 }
230
231 /*
232  * Returns the number of free chunks in a z3fold page.
233  * NB: can't be used with HEADLESS pages.
234  */
235 static int num_free_chunks(struct z3fold_header *zhdr)
236 {
237         int nfree;
238         /*
239          * If there is a middle object, pick up the bigger free space
240          * either before or after it. Otherwise just subtract the number
241          * of chunks occupied by the first and the last objects.
242          */
243         if (zhdr->middle_chunks != 0) {
244                 int nfree_before = zhdr->first_chunks ?
245                         0 : zhdr->start_middle - ZHDR_CHUNKS;
246                 int nfree_after = zhdr->last_chunks ?
247                         0 : TOTAL_CHUNKS -
248                                 (zhdr->start_middle + zhdr->middle_chunks);
249                 nfree = max(nfree_before, nfree_after);
250         } else
251                 nfree = NCHUNKS - zhdr->first_chunks - zhdr->last_chunks;
252         return nfree;
253 }
254
255 /*****************
256  * API Functions
257 *****************/
258 /**
259  * z3fold_create_pool() - create a new z3fold pool
260  * @gfp:        gfp flags when allocating the z3fold pool structure
261  * @ops:        user-defined operations for the z3fold pool
262  *
263  * Return: pointer to the new z3fold pool or NULL if the metadata allocation
264  * failed.
265  */
266 static struct z3fold_pool *z3fold_create_pool(gfp_t gfp,
267                 const struct z3fold_ops *ops)
268 {
269         struct z3fold_pool *pool;
270         int i;
271
272         pool = kzalloc(sizeof(struct z3fold_pool), gfp);
273         if (!pool)
274                 return NULL;
275         spin_lock_init(&pool->lock);
276         for_each_unbuddied_list(i, 0)
277                 INIT_LIST_HEAD(&pool->unbuddied[i]);
278         INIT_LIST_HEAD(&pool->lru);
279         atomic64_set(&pool->pages_nr, 0);
280         pool->ops = ops;
281         return pool;
282 }
283
284 /**
285  * z3fold_destroy_pool() - destroys an existing z3fold pool
286  * @pool:       the z3fold pool to be destroyed
287  *
288  * The pool should be emptied before this function is called.
289  */
290 static void z3fold_destroy_pool(struct z3fold_pool *pool)
291 {
292         kfree(pool);
293 }
294
295 static inline void *mchunk_memmove(struct z3fold_header *zhdr,
296                                 unsigned short dst_chunk)
297 {
298         void *beg = zhdr;
299         return memmove(beg + (dst_chunk << CHUNK_SHIFT),
300                        beg + (zhdr->start_middle << CHUNK_SHIFT),
301                        zhdr->middle_chunks << CHUNK_SHIFT);
302 }
303
304 #define BIG_CHUNK_GAP   3
305 /* Has to be called with lock held */
306 static int z3fold_compact_page(struct z3fold_header *zhdr)
307 {
308         struct page *page = virt_to_page(zhdr);
309
310         if (test_bit(MIDDLE_CHUNK_MAPPED, &page->private))
311                 return 0; /* can't move middle chunk, it's used */
312
313         if (zhdr->middle_chunks == 0)
314                 return 0; /* nothing to compact */
315
316         if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
317                 /* move to the beginning */
318                 mchunk_memmove(zhdr, ZHDR_CHUNKS);
319                 zhdr->first_chunks = zhdr->middle_chunks;
320                 zhdr->middle_chunks = 0;
321                 zhdr->start_middle = 0;
322                 zhdr->first_num++;
323                 return 1;
324         }
325
326         /*
327          * moving data is expensive, so let's only do that if
328          * there's substantial gain (at least BIG_CHUNK_GAP chunks)
329          */
330         if (zhdr->first_chunks != 0 && zhdr->last_chunks == 0 &&
331             zhdr->start_middle - (zhdr->first_chunks + ZHDR_CHUNKS) >=
332                         BIG_CHUNK_GAP) {
333                 mchunk_memmove(zhdr, zhdr->first_chunks + ZHDR_CHUNKS);
334                 zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS;
335                 return 1;
336         } else if (zhdr->last_chunks != 0 && zhdr->first_chunks == 0 &&
337                    TOTAL_CHUNKS - (zhdr->last_chunks + zhdr->start_middle
338                                         + zhdr->middle_chunks) >=
339                         BIG_CHUNK_GAP) {
340                 unsigned short new_start = TOTAL_CHUNKS - zhdr->last_chunks -
341                         zhdr->middle_chunks;
342                 mchunk_memmove(zhdr, new_start);
343                 zhdr->start_middle = new_start;
344                 return 1;
345         }
346
347         return 0;
348 }
349
350 /**
351  * z3fold_alloc() - allocates a region of a given size
352  * @pool:       z3fold pool from which to allocate
353  * @size:       size in bytes of the desired allocation
354  * @gfp:        gfp flags used if the pool needs to grow
355  * @handle:     handle of the new allocation
356  *
357  * This function will attempt to find a free region in the pool large enough to
358  * satisfy the allocation request.  A search of the unbuddied lists is
359  * performed first. If no suitable free region is found, then a new page is
360  * allocated and added to the pool to satisfy the request.
361  *
362  * gfp should not set __GFP_HIGHMEM as highmem pages cannot be used
363  * as z3fold pool pages.
364  *
365  * Return: 0 if success and handle is set, otherwise -EINVAL if the size or
366  * gfp arguments are invalid or -ENOMEM if the pool was unable to allocate
367  * a new page.
368  */
369 static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp,
370                         unsigned long *handle)
371 {
372         int chunks = 0, i, freechunks;
373         struct z3fold_header *zhdr = NULL;
374         enum buddy bud;
375         struct page *page;
376
377         if (!size || (gfp & __GFP_HIGHMEM))
378                 return -EINVAL;
379
380         if (size > PAGE_SIZE)
381                 return -ENOSPC;
382
383         if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED - CHUNK_SIZE)
384                 bud = HEADLESS;
385         else {
386                 chunks = size_to_chunks(size);
387
388                 /* First, try to find an unbuddied z3fold page. */
389                 zhdr = NULL;
390                 for_each_unbuddied_list(i, chunks) {
391                         spin_lock(&pool->lock);
392                         zhdr = list_first_entry_or_null(&pool->unbuddied[i],
393                                                 struct z3fold_header, buddy);
394                         if (!zhdr || !z3fold_page_trylock(zhdr)) {
395                                 spin_unlock(&pool->lock);
396                                 continue;
397                         }
398                         kref_get(&zhdr->refcount);
399                         list_del_init(&zhdr->buddy);
400                         spin_unlock(&pool->lock);
401
402                         page = virt_to_page(zhdr);
403                         if (zhdr->first_chunks == 0) {
404                                 if (zhdr->middle_chunks != 0 &&
405                                     chunks >= zhdr->start_middle)
406                                         bud = LAST;
407                                 else
408                                         bud = FIRST;
409                         } else if (zhdr->last_chunks == 0)
410                                 bud = LAST;
411                         else if (zhdr->middle_chunks == 0)
412                                 bud = MIDDLE;
413                         else {
414                                 z3fold_page_unlock(zhdr);
415                                 spin_lock(&pool->lock);
416                                 if (kref_put(&zhdr->refcount,
417                                              release_z3fold_page))
418                                         atomic64_dec(&pool->pages_nr);
419                                 spin_unlock(&pool->lock);
420                                 pr_err("No free chunks in unbuddied\n");
421                                 WARN_ON(1);
422                                 continue;
423                         }
424                         goto found;
425                 }
426                 bud = FIRST;
427         }
428
429         /* Couldn't find unbuddied z3fold page, create new one */
430         page = alloc_page(gfp);
431         if (!page)
432                 return -ENOMEM;
433
434         atomic64_inc(&pool->pages_nr);
435         zhdr = init_z3fold_page(page);
436
437         if (bud == HEADLESS) {
438                 set_bit(PAGE_HEADLESS, &page->private);
439                 spin_lock(&pool->lock);
440                 goto headless;
441         }
442         z3fold_page_lock(zhdr);
443
444 found:
445         if (bud == FIRST)
446                 zhdr->first_chunks = chunks;
447         else if (bud == LAST)
448                 zhdr->last_chunks = chunks;
449         else {
450                 zhdr->middle_chunks = chunks;
451                 zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS;
452         }
453
454         spin_lock(&pool->lock);
455         if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0 ||
456                         zhdr->middle_chunks == 0) {
457                 /* Add to unbuddied list */
458                 freechunks = num_free_chunks(zhdr);
459                 list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
460         }
461
462 headless:
463         /* Add/move z3fold page to beginning of LRU */
464         if (!list_empty(&page->lru))
465                 list_del(&page->lru);
466
467         list_add(&page->lru, &pool->lru);
468
469         *handle = encode_handle(zhdr, bud);
470         spin_unlock(&pool->lock);
471         if (bud != HEADLESS)
472                 z3fold_page_unlock(zhdr);
473
474         return 0;
475 }
476
477 /**
478  * z3fold_free() - frees the allocation associated with the given handle
479  * @pool:       pool in which the allocation resided
480  * @handle:     handle associated with the allocation returned by z3fold_alloc()
481  *
482  * In the case that the z3fold page in which the allocation resides is under
483  * reclaim, as indicated by the PG_reclaim flag being set, this function
484  * only sets the first|last_chunks to 0.  The page is actually freed
485  * once both buddies are evicted (see z3fold_reclaim_page() below).
486  */
487 static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
488 {
489         struct z3fold_header *zhdr;
490         int freechunks;
491         struct page *page;
492         enum buddy bud;
493
494         zhdr = handle_to_z3fold_header(handle);
495         page = virt_to_page(zhdr);
496
497         if (test_bit(PAGE_HEADLESS, &page->private)) {
498                 /* HEADLESS page stored */
499                 bud = HEADLESS;
500         } else {
501                 z3fold_page_lock(zhdr);
502                 bud = handle_to_buddy(handle);
503
504                 switch (bud) {
505                 case FIRST:
506                         zhdr->first_chunks = 0;
507                         break;
508                 case MIDDLE:
509                         zhdr->middle_chunks = 0;
510                         zhdr->start_middle = 0;
511                         break;
512                 case LAST:
513                         zhdr->last_chunks = 0;
514                         break;
515                 default:
516                         pr_err("%s: unknown bud %d\n", __func__, bud);
517                         WARN_ON(1);
518                         z3fold_page_unlock(zhdr);
519                         return;
520                 }
521         }
522
523         if (bud == HEADLESS) {
524                 spin_lock(&pool->lock);
525                 list_del(&page->lru);
526                 spin_unlock(&pool->lock);
527                 free_z3fold_page(page);
528                 atomic64_dec(&pool->pages_nr);
529         } else {
530                 if (zhdr->first_chunks != 0 || zhdr->middle_chunks != 0 ||
531                     zhdr->last_chunks != 0) {
532                         z3fold_compact_page(zhdr);
533                         /* Add to the unbuddied list */
534                         spin_lock(&pool->lock);
535                         if (!list_empty(&zhdr->buddy))
536                                 list_del(&zhdr->buddy);
537                         freechunks = num_free_chunks(zhdr);
538                         list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
539                         spin_unlock(&pool->lock);
540                 }
541                 z3fold_page_unlock(zhdr);
542                 spin_lock(&pool->lock);
543                 if (kref_put(&zhdr->refcount, release_z3fold_page))
544                         atomic64_dec(&pool->pages_nr);
545                 spin_unlock(&pool->lock);
546         }
547
548 }
549
550 /**
551  * z3fold_reclaim_page() - evicts allocations from a pool page and frees it
552  * @pool:       pool from which a page will attempt to be evicted
553  * @retires:    number of pages on the LRU list for which eviction will
554  *              be attempted before failing
555  *
556  * z3fold reclaim is different from normal system reclaim in that it is done
557  * from the bottom, up. This is because only the bottom layer, z3fold, has
558  * information on how the allocations are organized within each z3fold page.
559  * This has the potential to create interesting locking situations between
560  * z3fold and the user, however.
561  *
562  * To avoid these, this is how z3fold_reclaim_page() should be called:
563
564  * The user detects a page should be reclaimed and calls z3fold_reclaim_page().
565  * z3fold_reclaim_page() will remove a z3fold page from the pool LRU list and
566  * call the user-defined eviction handler with the pool and handle as
567  * arguments.
568  *
569  * If the handle can not be evicted, the eviction handler should return
570  * non-zero. z3fold_reclaim_page() will add the z3fold page back to the
571  * appropriate list and try the next z3fold page on the LRU up to
572  * a user defined number of retries.
573  *
574  * If the handle is successfully evicted, the eviction handler should
575  * return 0 _and_ should have called z3fold_free() on the handle. z3fold_free()
576  * contains logic to delay freeing the page if the page is under reclaim,
577  * as indicated by the setting of the PG_reclaim flag on the underlying page.
578  *
579  * If all buddies in the z3fold page are successfully evicted, then the
580  * z3fold page can be freed.
581  *
582  * Returns: 0 if page is successfully freed, otherwise -EINVAL if there are
583  * no pages to evict or an eviction handler is not registered, -EAGAIN if
584  * the retry limit was hit.
585  */
586 static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries)
587 {
588         int i, ret = 0, freechunks;
589         struct z3fold_header *zhdr;
590         struct page *page;
591         unsigned long first_handle = 0, middle_handle = 0, last_handle = 0;
592
593         spin_lock(&pool->lock);
594         if (!pool->ops || !pool->ops->evict || retries == 0) {
595                 spin_unlock(&pool->lock);
596                 return -EINVAL;
597         }
598         for (i = 0; i < retries; i++) {
599                 if (list_empty(&pool->lru)) {
600                         spin_unlock(&pool->lock);
601                         return -EINVAL;
602                 }
603                 page = list_last_entry(&pool->lru, struct page, lru);
604                 list_del_init(&page->lru);
605
606                 zhdr = page_address(page);
607                 if (!test_bit(PAGE_HEADLESS, &page->private)) {
608                         if (!list_empty(&zhdr->buddy))
609                                 list_del_init(&zhdr->buddy);
610                         kref_get(&zhdr->refcount);
611                         spin_unlock(&pool->lock);
612                         z3fold_page_lock(zhdr);
613                         /*
614                          * We need encode the handles before unlocking, since
615                          * we can race with free that will set
616                          * (first|last)_chunks to 0
617                          */
618                         first_handle = 0;
619                         last_handle = 0;
620                         middle_handle = 0;
621                         if (zhdr->first_chunks)
622                                 first_handle = encode_handle(zhdr, FIRST);
623                         if (zhdr->middle_chunks)
624                                 middle_handle = encode_handle(zhdr, MIDDLE);
625                         if (zhdr->last_chunks)
626                                 last_handle = encode_handle(zhdr, LAST);
627                         z3fold_page_unlock(zhdr);
628                 } else {
629                         first_handle = encode_handle(zhdr, HEADLESS);
630                         last_handle = middle_handle = 0;
631                         spin_unlock(&pool->lock);
632                 }
633
634                 /* Issue the eviction callback(s) */
635                 if (middle_handle) {
636                         ret = pool->ops->evict(pool, middle_handle);
637                         if (ret)
638                                 goto next;
639                 }
640                 if (first_handle) {
641                         ret = pool->ops->evict(pool, first_handle);
642                         if (ret)
643                                 goto next;
644                 }
645                 if (last_handle) {
646                         ret = pool->ops->evict(pool, last_handle);
647                         if (ret)
648                                 goto next;
649                 }
650 next:
651                 if (test_bit(PAGE_HEADLESS, &page->private)) {
652                         if (ret == 0) {
653                                 free_z3fold_page(page);
654                                 return 0;
655                         } else {
656                                 spin_lock(&pool->lock);
657                         }
658                 } else {
659                         z3fold_page_lock(zhdr);
660                         if ((zhdr->first_chunks || zhdr->last_chunks ||
661                              zhdr->middle_chunks) &&
662                             !(zhdr->first_chunks && zhdr->last_chunks &&
663                               zhdr->middle_chunks)) {
664                                 z3fold_compact_page(zhdr);
665                                 /* add to unbuddied list */
666                                 spin_lock(&pool->lock);
667                                 freechunks = num_free_chunks(zhdr);
668                                 list_add(&zhdr->buddy,
669                                          &pool->unbuddied[freechunks]);
670                                 spin_unlock(&pool->lock);
671                         }
672                         z3fold_page_unlock(zhdr);
673                         spin_lock(&pool->lock);
674                         if (kref_put(&zhdr->refcount, release_z3fold_page)) {
675                                 spin_unlock(&pool->lock);
676                                 atomic64_dec(&pool->pages_nr);
677                                 return 0;
678                         }
679                 }
680
681                 /*
682                  * Add to the beginning of LRU.
683                  * Pool lock has to be kept here to ensure the page has
684                  * not already been released
685                  */
686                 list_add(&page->lru, &pool->lru);
687         }
688         spin_unlock(&pool->lock);
689         return -EAGAIN;
690 }
691
692 /**
693  * z3fold_map() - maps the allocation associated with the given handle
694  * @pool:       pool in which the allocation resides
695  * @handle:     handle associated with the allocation to be mapped
696  *
697  * Extracts the buddy number from handle and constructs the pointer to the
698  * correct starting chunk within the page.
699  *
700  * Returns: a pointer to the mapped allocation
701  */
702 static void *z3fold_map(struct z3fold_pool *pool, unsigned long handle)
703 {
704         struct z3fold_header *zhdr;
705         struct page *page;
706         void *addr;
707         enum buddy buddy;
708
709         zhdr = handle_to_z3fold_header(handle);
710         addr = zhdr;
711         page = virt_to_page(zhdr);
712
713         if (test_bit(PAGE_HEADLESS, &page->private))
714                 goto out;
715
716         z3fold_page_lock(zhdr);
717         buddy = handle_to_buddy(handle);
718         switch (buddy) {
719         case FIRST:
720                 addr += ZHDR_SIZE_ALIGNED;
721                 break;
722         case MIDDLE:
723                 addr += zhdr->start_middle << CHUNK_SHIFT;
724                 set_bit(MIDDLE_CHUNK_MAPPED, &page->private);
725                 break;
726         case LAST:
727                 addr += PAGE_SIZE - (zhdr->last_chunks << CHUNK_SHIFT);
728                 break;
729         default:
730                 pr_err("unknown buddy id %d\n", buddy);
731                 WARN_ON(1);
732                 addr = NULL;
733                 break;
734         }
735
736         z3fold_page_unlock(zhdr);
737 out:
738         return addr;
739 }
740
741 /**
742  * z3fold_unmap() - unmaps the allocation associated with the given handle
743  * @pool:       pool in which the allocation resides
744  * @handle:     handle associated with the allocation to be unmapped
745  */
746 static void z3fold_unmap(struct z3fold_pool *pool, unsigned long handle)
747 {
748         struct z3fold_header *zhdr;
749         struct page *page;
750         enum buddy buddy;
751
752         zhdr = handle_to_z3fold_header(handle);
753         page = virt_to_page(zhdr);
754
755         if (test_bit(PAGE_HEADLESS, &page->private))
756                 return;
757
758         z3fold_page_lock(zhdr);
759         buddy = handle_to_buddy(handle);
760         if (buddy == MIDDLE)
761                 clear_bit(MIDDLE_CHUNK_MAPPED, &page->private);
762         z3fold_page_unlock(zhdr);
763 }
764
765 /**
766  * z3fold_get_pool_size() - gets the z3fold pool size in pages
767  * @pool:       pool whose size is being queried
768  *
769  * Returns: size in pages of the given pool.
770  */
771 static u64 z3fold_get_pool_size(struct z3fold_pool *pool)
772 {
773         return atomic64_read(&pool->pages_nr);
774 }
775
776 /*****************
777  * zpool
778  ****************/
779
780 static int z3fold_zpool_evict(struct z3fold_pool *pool, unsigned long handle)
781 {
782         if (pool->zpool && pool->zpool_ops && pool->zpool_ops->evict)
783                 return pool->zpool_ops->evict(pool->zpool, handle);
784         else
785                 return -ENOENT;
786 }
787
788 static const struct z3fold_ops z3fold_zpool_ops = {
789         .evict =        z3fold_zpool_evict
790 };
791
792 static void *z3fold_zpool_create(const char *name, gfp_t gfp,
793                                const struct zpool_ops *zpool_ops,
794                                struct zpool *zpool)
795 {
796         struct z3fold_pool *pool;
797
798         pool = z3fold_create_pool(gfp, zpool_ops ? &z3fold_zpool_ops : NULL);
799         if (pool) {
800                 pool->zpool = zpool;
801                 pool->zpool_ops = zpool_ops;
802         }
803         return pool;
804 }
805
806 static void z3fold_zpool_destroy(void *pool)
807 {
808         z3fold_destroy_pool(pool);
809 }
810
811 static int z3fold_zpool_malloc(void *pool, size_t size, gfp_t gfp,
812                         unsigned long *handle)
813 {
814         return z3fold_alloc(pool, size, gfp, handle);
815 }
816 static void z3fold_zpool_free(void *pool, unsigned long handle)
817 {
818         z3fold_free(pool, handle);
819 }
820
821 static int z3fold_zpool_shrink(void *pool, unsigned int pages,
822                         unsigned int *reclaimed)
823 {
824         unsigned int total = 0;
825         int ret = -EINVAL;
826
827         while (total < pages) {
828                 ret = z3fold_reclaim_page(pool, 8);
829                 if (ret < 0)
830                         break;
831                 total++;
832         }
833
834         if (reclaimed)
835                 *reclaimed = total;
836
837         return ret;
838 }
839
840 static void *z3fold_zpool_map(void *pool, unsigned long handle,
841                         enum zpool_mapmode mm)
842 {
843         return z3fold_map(pool, handle);
844 }
845 static void z3fold_zpool_unmap(void *pool, unsigned long handle)
846 {
847         z3fold_unmap(pool, handle);
848 }
849
850 static u64 z3fold_zpool_total_size(void *pool)
851 {
852         return z3fold_get_pool_size(pool) * PAGE_SIZE;
853 }
854
855 static struct zpool_driver z3fold_zpool_driver = {
856         .type =         "z3fold",
857         .owner =        THIS_MODULE,
858         .create =       z3fold_zpool_create,
859         .destroy =      z3fold_zpool_destroy,
860         .malloc =       z3fold_zpool_malloc,
861         .free =         z3fold_zpool_free,
862         .shrink =       z3fold_zpool_shrink,
863         .map =          z3fold_zpool_map,
864         .unmap =        z3fold_zpool_unmap,
865         .total_size =   z3fold_zpool_total_size,
866 };
867
868 MODULE_ALIAS("zpool-z3fold");
869
870 static int __init init_z3fold(void)
871 {
872         /* Make sure the z3fold header is not larger than the page size */
873         BUILD_BUG_ON(ZHDR_SIZE_ALIGNED > PAGE_SIZE);
874         zpool_register_driver(&z3fold_zpool_driver);
875
876         return 0;
877 }
878
879 static void __exit exit_z3fold(void)
880 {
881         zpool_unregister_driver(&z3fold_zpool_driver);
882 }
883
884 module_init(init_z3fold);
885 module_exit(exit_z3fold);
886
887 MODULE_LICENSE("GPL");
888 MODULE_AUTHOR("Vitaly Wool <vitalywool@gmail.com>");
889 MODULE_DESCRIPTION("3-Fold Allocator for Compressed Pages");