staging: zsmalloc: prevent mappping in interrupt context
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / drivers / staging / zsmalloc / zsmalloc-main.c
CommitLineData
61989a80
NG
1/*
2 * zsmalloc memory allocator
3 *
4 * Copyright (C) 2011 Nitin Gupta
5 *
6 * This code is released using a dual license strategy: BSD/GPL
7 * You can choose the license that better fits your requirements.
8 *
9 * Released under the terms of 3-clause BSD License
10 * Released under the terms of GNU General Public License Version 2.0
11 */
12
2db51dae
NG
13
14/*
15 * This allocator is designed for use with zcache and zram. Thus, the
16 * allocator is supposed to work well under low memory conditions. In
17 * particular, it never attempts higher order page allocation which is
18 * very likely to fail under memory pressure. On the other hand, if we
19 * just use single (0-order) pages, it would suffer from very high
20 * fragmentation -- any object of size PAGE_SIZE/2 or larger would occupy
21 * an entire page. This was one of the major issues with its predecessor
22 * (xvmalloc).
23 *
24 * To overcome these issues, zsmalloc allocates a bunch of 0-order pages
25 * and links them together using various 'struct page' fields. These linked
26 * pages act as a single higher-order page i.e. an object can span 0-order
27 * page boundaries. The code refers to these linked pages as a single entity
28 * called zspage.
29 *
30 * Following is how we use various fields and flags of underlying
31 * struct page(s) to form a zspage.
32 *
33 * Usage of struct page fields:
34 * page->first_page: points to the first component (0-order) page
35 * page->index (union with page->freelist): offset of the first object
36 * starting in this page. For the first page, this is
37 * always 0, so we use this field (aka freelist) to point
38 * to the first free object in zspage.
39 * page->lru: links together all component pages (except the first page)
40 * of a zspage
41 *
42 * For _first_ page only:
43 *
44 * page->private (union with page->first_page): refers to the
45 * component page after the first page
46 * page->freelist: points to the first free object in zspage.
47 * Free objects are linked together using in-place
48 * metadata.
49 * page->objects: maximum number of objects we can store in this
50 * zspage (class->zspage_order * PAGE_SIZE / class->size)
51 * page->lru: links together first pages of various zspages.
52 * Basically forming list of zspages in a fullness group.
53 * page->mapping: class index and fullness group of the zspage
54 *
55 * Usage of struct page flags:
56 * PG_private: identifies the first component page
57 * PG_private2: identifies the last component page
58 *
59 */
60
61989a80
NG
61#ifdef CONFIG_ZSMALLOC_DEBUG
62#define DEBUG
63#endif
64
65#include <linux/module.h>
66#include <linux/kernel.h>
67#include <linux/bitops.h>
68#include <linux/errno.h>
69#include <linux/highmem.h>
70#include <linux/init.h>
71#include <linux/string.h>
72#include <linux/slab.h>
73#include <asm/tlbflush.h>
74#include <asm/pgtable.h>
75#include <linux/cpumask.h>
76#include <linux/cpu.h>
0cbb613f 77#include <linux/vmalloc.h>
c60369f0 78#include <linux/hardirq.h>
61989a80
NG
79
80#include "zsmalloc.h"
81#include "zsmalloc_int.h"
82
83/*
84 * A zspage's class index and fullness group
85 * are encoded in its (first)page->mapping
86 */
87#define CLASS_IDX_BITS 28
88#define FULLNESS_BITS 4
89#define CLASS_IDX_MASK ((1 << CLASS_IDX_BITS) - 1)
90#define FULLNESS_MASK ((1 << FULLNESS_BITS) - 1)
91
61989a80
NG
92/* per-cpu VM mapping areas for zspage accesses that cross page boundaries */
93static DEFINE_PER_CPU(struct mapping_area, zs_map_area);
94
95static int is_first_page(struct page *page)
96{
a27545bf 97 return PagePrivate(page);
61989a80
NG
98}
99
100static int is_last_page(struct page *page)
101{
a27545bf 102 return PagePrivate2(page);
61989a80
NG
103}
104
105static void get_zspage_mapping(struct page *page, unsigned int *class_idx,
106 enum fullness_group *fullness)
107{
108 unsigned long m;
109 BUG_ON(!is_first_page(page));
110
111 m = (unsigned long)page->mapping;
112 *fullness = m & FULLNESS_MASK;
113 *class_idx = (m >> FULLNESS_BITS) & CLASS_IDX_MASK;
114}
115
116static void set_zspage_mapping(struct page *page, unsigned int class_idx,
117 enum fullness_group fullness)
118{
119 unsigned long m;
120 BUG_ON(!is_first_page(page));
121
122 m = ((class_idx & CLASS_IDX_MASK) << FULLNESS_BITS) |
123 (fullness & FULLNESS_MASK);
124 page->mapping = (struct address_space *)m;
125}
126
127static int get_size_class_index(int size)
128{
129 int idx = 0;
130
131 if (likely(size > ZS_MIN_ALLOC_SIZE))
132 idx = DIV_ROUND_UP(size - ZS_MIN_ALLOC_SIZE,
133 ZS_SIZE_CLASS_DELTA);
134
135 return idx;
136}
137
138static enum fullness_group get_fullness_group(struct page *page)
139{
140 int inuse, max_objects;
141 enum fullness_group fg;
142 BUG_ON(!is_first_page(page));
143
144 inuse = page->inuse;
145 max_objects = page->objects;
146
147 if (inuse == 0)
148 fg = ZS_EMPTY;
149 else if (inuse == max_objects)
150 fg = ZS_FULL;
151 else if (inuse <= max_objects / fullness_threshold_frac)
152 fg = ZS_ALMOST_EMPTY;
153 else
154 fg = ZS_ALMOST_FULL;
155
156 return fg;
157}
158
159static void insert_zspage(struct page *page, struct size_class *class,
160 enum fullness_group fullness)
161{
162 struct page **head;
163
164 BUG_ON(!is_first_page(page));
165
166 if (fullness >= _ZS_NR_FULLNESS_GROUPS)
167 return;
168
169 head = &class->fullness_list[fullness];
170 if (*head)
171 list_add_tail(&page->lru, &(*head)->lru);
172
173 *head = page;
174}
175
176static void remove_zspage(struct page *page, struct size_class *class,
177 enum fullness_group fullness)
178{
179 struct page **head;
180
181 BUG_ON(!is_first_page(page));
182
183 if (fullness >= _ZS_NR_FULLNESS_GROUPS)
184 return;
185
186 head = &class->fullness_list[fullness];
187 BUG_ON(!*head);
188 if (list_empty(&(*head)->lru))
189 *head = NULL;
190 else if (*head == page)
191 *head = (struct page *)list_entry((*head)->lru.next,
192 struct page, lru);
193
194 list_del_init(&page->lru);
195}
196
197static enum fullness_group fix_fullness_group(struct zs_pool *pool,
198 struct page *page)
199{
200 int class_idx;
201 struct size_class *class;
202 enum fullness_group currfg, newfg;
203
204 BUG_ON(!is_first_page(page));
205
206 get_zspage_mapping(page, &class_idx, &currfg);
207 newfg = get_fullness_group(page);
208 if (newfg == currfg)
209 goto out;
210
211 class = &pool->size_class[class_idx];
212 remove_zspage(page, class, currfg);
213 insert_zspage(page, class, newfg);
214 set_zspage_mapping(page, class_idx, newfg);
215
216out:
217 return newfg;
218}
219
220/*
221 * We have to decide on how many pages to link together
222 * to form a zspage for each size class. This is important
223 * to reduce wastage due to unusable space left at end of
224 * each zspage which is given as:
225 * wastage = Zp - Zp % size_class
226 * where Zp = zspage size = k * PAGE_SIZE where k = 1, 2, ...
227 *
228 * For example, for size class of 3/8 * PAGE_SIZE, we should
229 * link together 3 PAGE_SIZE sized pages to form a zspage
230 * since then we can perfectly fit in 8 such objects.
231 */
2e3b6154 232static int get_pages_per_zspage(int class_size)
61989a80
NG
233{
234 int i, max_usedpc = 0;
235 /* zspage order which gives maximum used size per KB */
236 int max_usedpc_order = 1;
237
84d4faab 238 for (i = 1; i <= ZS_MAX_PAGES_PER_ZSPAGE; i++) {
61989a80
NG
239 int zspage_size;
240 int waste, usedpc;
241
242 zspage_size = i * PAGE_SIZE;
243 waste = zspage_size % class_size;
244 usedpc = (zspage_size - waste) * 100 / zspage_size;
245
246 if (usedpc > max_usedpc) {
247 max_usedpc = usedpc;
248 max_usedpc_order = i;
249 }
250 }
251
252 return max_usedpc_order;
253}
254
255/*
256 * A single 'zspage' is composed of many system pages which are
257 * linked together using fields in struct page. This function finds
258 * the first/head page, given any component page of a zspage.
259 */
260static struct page *get_first_page(struct page *page)
261{
262 if (is_first_page(page))
263 return page;
264 else
265 return page->first_page;
266}
267
268static struct page *get_next_page(struct page *page)
269{
270 struct page *next;
271
272 if (is_last_page(page))
273 next = NULL;
274 else if (is_first_page(page))
275 next = (struct page *)page->private;
276 else
277 next = list_entry(page->lru.next, struct page, lru);
278
279 return next;
280}
281
282/* Encode <page, obj_idx> as a single handle value */
283static void *obj_location_to_handle(struct page *page, unsigned long obj_idx)
284{
285 unsigned long handle;
286
287 if (!page) {
288 BUG_ON(obj_idx);
289 return NULL;
290 }
291
292 handle = page_to_pfn(page) << OBJ_INDEX_BITS;
293 handle |= (obj_idx & OBJ_INDEX_MASK);
294
295 return (void *)handle;
296}
297
298/* Decode <page, obj_idx> pair from the given object handle */
c2344348 299static void obj_handle_to_location(unsigned long handle, struct page **page,
61989a80
NG
300 unsigned long *obj_idx)
301{
c2344348
MK
302 *page = pfn_to_page(handle >> OBJ_INDEX_BITS);
303 *obj_idx = handle & OBJ_INDEX_MASK;
61989a80
NG
304}
305
306static unsigned long obj_idx_to_offset(struct page *page,
307 unsigned long obj_idx, int class_size)
308{
309 unsigned long off = 0;
310
311 if (!is_first_page(page))
312 off = page->index;
313
314 return off + obj_idx * class_size;
315}
316
f4477e90
NG
317static void reset_page(struct page *page)
318{
319 clear_bit(PG_private, &page->flags);
320 clear_bit(PG_private_2, &page->flags);
321 set_page_private(page, 0);
322 page->mapping = NULL;
323 page->freelist = NULL;
324 reset_page_mapcount(page);
325}
326
61989a80
NG
327static void free_zspage(struct page *first_page)
328{
f4477e90 329 struct page *nextp, *tmp, *head_extra;
61989a80
NG
330
331 BUG_ON(!is_first_page(first_page));
332 BUG_ON(first_page->inuse);
333
f4477e90 334 head_extra = (struct page *)page_private(first_page);
61989a80 335
f4477e90 336 reset_page(first_page);
61989a80
NG
337 __free_page(first_page);
338
339 /* zspage with only 1 system page */
f4477e90 340 if (!head_extra)
61989a80
NG
341 return;
342
f4477e90 343 list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) {
61989a80 344 list_del(&nextp->lru);
f4477e90 345 reset_page(nextp);
61989a80
NG
346 __free_page(nextp);
347 }
f4477e90
NG
348 reset_page(head_extra);
349 __free_page(head_extra);
61989a80
NG
350}
351
352/* Initialize a newly allocated zspage */
353static void init_zspage(struct page *first_page, struct size_class *class)
354{
355 unsigned long off = 0;
356 struct page *page = first_page;
357
358 BUG_ON(!is_first_page(first_page));
359 while (page) {
360 struct page *next_page;
361 struct link_free *link;
362 unsigned int i, objs_on_page;
363
364 /*
365 * page->index stores offset of first object starting
366 * in the page. For the first page, this is always 0,
367 * so we use first_page->index (aka ->freelist) to store
368 * head of corresponding zspage's freelist.
369 */
370 if (page != first_page)
371 page->index = off;
372
373 link = (struct link_free *)kmap_atomic(page) +
374 off / sizeof(*link);
375 objs_on_page = (PAGE_SIZE - off) / class->size;
376
377 for (i = 1; i <= objs_on_page; i++) {
378 off += class->size;
379 if (off < PAGE_SIZE) {
380 link->next = obj_location_to_handle(page, i);
381 link += class->size / sizeof(*link);
382 }
383 }
384
385 /*
386 * We now come to the last (full or partial) object on this
387 * page, which must point to the first object on the next
388 * page (if present)
389 */
390 next_page = get_next_page(page);
391 link->next = obj_location_to_handle(next_page, 0);
392 kunmap_atomic(link);
393 page = next_page;
394 off = (off + class->size) % PAGE_SIZE;
395 }
396}
397
398/*
399 * Allocate a zspage for the given size class
400 */
401static struct page *alloc_zspage(struct size_class *class, gfp_t flags)
402{
403 int i, error;
b4b700c5 404 struct page *first_page = NULL, *uninitialized_var(prev_page);
61989a80
NG
405
406 /*
407 * Allocate individual pages and link them together as:
408 * 1. first page->private = first sub-page
409 * 2. all sub-pages are linked together using page->lru
410 * 3. each sub-page is linked to the first page using page->first_page
411 *
412 * For each size class, First/Head pages are linked together using
413 * page->lru. Also, we set PG_private to identify the first page
414 * (i.e. no other sub-page has this flag set) and PG_private_2 to
415 * identify the last page.
416 */
417 error = -ENOMEM;
2e3b6154 418 for (i = 0; i < class->pages_per_zspage; i++) {
b4b700c5 419 struct page *page;
61989a80
NG
420
421 page = alloc_page(flags);
422 if (!page)
423 goto cleanup;
424
425 INIT_LIST_HEAD(&page->lru);
426 if (i == 0) { /* first page */
a27545bf 427 SetPagePrivate(page);
61989a80
NG
428 set_page_private(page, 0);
429 first_page = page;
430 first_page->inuse = 0;
431 }
432 if (i == 1)
433 first_page->private = (unsigned long)page;
434 if (i >= 1)
435 page->first_page = first_page;
436 if (i >= 2)
437 list_add(&page->lru, &prev_page->lru);
2e3b6154 438 if (i == class->pages_per_zspage - 1) /* last page */
a27545bf 439 SetPagePrivate2(page);
61989a80
NG
440 prev_page = page;
441 }
442
443 init_zspage(first_page, class);
444
445 first_page->freelist = obj_location_to_handle(first_page, 0);
446 /* Maximum number of objects we can store in this zspage */
2e3b6154 447 first_page->objects = class->pages_per_zspage * PAGE_SIZE / class->size;
61989a80
NG
448
449 error = 0; /* Success */
450
451cleanup:
452 if (unlikely(error) && first_page) {
453 free_zspage(first_page);
454 first_page = NULL;
455 }
456
457 return first_page;
458}
459
460static struct page *find_get_zspage(struct size_class *class)
461{
462 int i;
463 struct page *page;
464
465 for (i = 0; i < _ZS_NR_FULLNESS_GROUPS; i++) {
466 page = class->fullness_list[i];
467 if (page)
468 break;
469 }
470
471 return page;
472}
473
6539a36c 474static void zs_copy_map_object(char *buf, struct page *page,
5f601902
SJ
475 int off, int size)
476{
477 struct page *pages[2];
478 int sizes[2];
479 void *addr;
480
6539a36c
SJ
481 pages[0] = page;
482 pages[1] = get_next_page(page);
5f601902
SJ
483 BUG_ON(!pages[1]);
484
485 sizes[0] = PAGE_SIZE - off;
486 sizes[1] = size - sizes[0];
487
5f601902
SJ
488 /* copy object to per-cpu buffer */
489 addr = kmap_atomic(pages[0]);
490 memcpy(buf, addr + off, sizes[0]);
491 kunmap_atomic(addr);
492 addr = kmap_atomic(pages[1]);
493 memcpy(buf + sizes[0], addr, sizes[1]);
494 kunmap_atomic(addr);
495}
496
6539a36c 497static void zs_copy_unmap_object(char *buf, struct page *page,
5f601902
SJ
498 int off, int size)
499{
500 struct page *pages[2];
501 int sizes[2];
502 void *addr;
503
6539a36c
SJ
504 pages[0] = page;
505 pages[1] = get_next_page(page);
5f601902
SJ
506 BUG_ON(!pages[1]);
507
508 sizes[0] = PAGE_SIZE - off;
509 sizes[1] = size - sizes[0];
510
511 /* copy per-cpu buffer to object */
512 addr = kmap_atomic(pages[0]);
513 memcpy(addr + off, buf, sizes[0]);
514 kunmap_atomic(addr);
515 addr = kmap_atomic(pages[1]);
516 memcpy(addr, buf + sizes[0], sizes[1]);
517 kunmap_atomic(addr);
5f601902 518}
61989a80 519
61989a80
NG
520static int zs_cpu_notifier(struct notifier_block *nb, unsigned long action,
521 void *pcpu)
522{
523 int cpu = (long)pcpu;
524 struct mapping_area *area;
525
526 switch (action) {
527 case CPU_UP_PREPARE:
528 area = &per_cpu(zs_map_area, cpu);
5f601902
SJ
529 /*
530 * Make sure we don't leak memory if a cpu UP notification
531 * and zs_init() race and both call zs_cpu_up() on the same cpu
532 */
533 if (area->vm_buf)
534 return 0;
535 area->vm_buf = (char *)__get_free_page(GFP_KERNEL);
536 if (!area->vm_buf)
537 return -ENOMEM;
538 return 0;
61989a80
NG
539 break;
540 case CPU_DEAD:
541 case CPU_UP_CANCELED:
542 area = &per_cpu(zs_map_area, cpu);
5f601902
SJ
543 if (area->vm_buf)
544 free_page((unsigned long)area->vm_buf);
545 area->vm_buf = NULL;
61989a80
NG
546 break;
547 }
548
549 return NOTIFY_OK;
550}
551
552static struct notifier_block zs_cpu_nb = {
553 .notifier_call = zs_cpu_notifier
554};
555
556static void zs_exit(void)
557{
558 int cpu;
559
560 for_each_online_cpu(cpu)
561 zs_cpu_notifier(NULL, CPU_DEAD, (void *)(long)cpu);
562 unregister_cpu_notifier(&zs_cpu_nb);
563}
564
565static int zs_init(void)
566{
567 int cpu, ret;
568
569 register_cpu_notifier(&zs_cpu_nb);
570 for_each_online_cpu(cpu) {
571 ret = zs_cpu_notifier(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
572 if (notifier_to_errno(ret))
573 goto fail;
574 }
575 return 0;
576fail:
577 zs_exit();
578 return notifier_to_errno(ret);
579}
580
581struct zs_pool *zs_create_pool(const char *name, gfp_t flags)
582{
069f101f 583 int i, ovhd_size;
61989a80
NG
584 struct zs_pool *pool;
585
586 if (!name)
587 return NULL;
588
589 ovhd_size = roundup(sizeof(*pool), PAGE_SIZE);
590 pool = kzalloc(ovhd_size, GFP_KERNEL);
591 if (!pool)
592 return NULL;
593
594 for (i = 0; i < ZS_SIZE_CLASSES; i++) {
595 int size;
596 struct size_class *class;
597
598 size = ZS_MIN_ALLOC_SIZE + i * ZS_SIZE_CLASS_DELTA;
599 if (size > ZS_MAX_ALLOC_SIZE)
600 size = ZS_MAX_ALLOC_SIZE;
601
602 class = &pool->size_class[i];
603 class->size = size;
604 class->index = i;
605 spin_lock_init(&class->lock);
2e3b6154 606 class->pages_per_zspage = get_pages_per_zspage(size);
61989a80
NG
607
608 }
609
61989a80
NG
610 pool->flags = flags;
611 pool->name = name;
612
61989a80
NG
613 return pool;
614}
615EXPORT_SYMBOL_GPL(zs_create_pool);
616
617void zs_destroy_pool(struct zs_pool *pool)
618{
619 int i;
620
621 for (i = 0; i < ZS_SIZE_CLASSES; i++) {
622 int fg;
623 struct size_class *class = &pool->size_class[i];
624
625 for (fg = 0; fg < _ZS_NR_FULLNESS_GROUPS; fg++) {
626 if (class->fullness_list[fg]) {
627 pr_info("Freeing non-empty class with size "
628 "%db, fullness group %d\n",
629 class->size, fg);
630 }
631 }
632 }
633 kfree(pool);
634}
635EXPORT_SYMBOL_GPL(zs_destroy_pool);
636
637/**
638 * zs_malloc - Allocate block of given size from pool.
639 * @pool: pool to allocate from
640 * @size: size of block to allocate
61989a80 641 *
00a61d86 642 * On success, handle to the allocated object is returned,
c2344348 643 * otherwise 0.
61989a80
NG
644 * Allocation requests with size > ZS_MAX_ALLOC_SIZE will fail.
645 */
c2344348 646unsigned long zs_malloc(struct zs_pool *pool, size_t size)
61989a80 647{
c2344348 648 unsigned long obj;
61989a80
NG
649 struct link_free *link;
650 int class_idx;
651 struct size_class *class;
652
653 struct page *first_page, *m_page;
654 unsigned long m_objidx, m_offset;
655
656 if (unlikely(!size || size > ZS_MAX_ALLOC_SIZE))
c2344348 657 return 0;
61989a80
NG
658
659 class_idx = get_size_class_index(size);
660 class = &pool->size_class[class_idx];
661 BUG_ON(class_idx != class->index);
662
663 spin_lock(&class->lock);
664 first_page = find_get_zspage(class);
665
666 if (!first_page) {
667 spin_unlock(&class->lock);
668 first_page = alloc_zspage(class, pool->flags);
669 if (unlikely(!first_page))
c2344348 670 return 0;
61989a80
NG
671
672 set_zspage_mapping(first_page, class->index, ZS_EMPTY);
673 spin_lock(&class->lock);
2e3b6154 674 class->pages_allocated += class->pages_per_zspage;
61989a80
NG
675 }
676
c2344348 677 obj = (unsigned long)first_page->freelist;
61989a80
NG
678 obj_handle_to_location(obj, &m_page, &m_objidx);
679 m_offset = obj_idx_to_offset(m_page, m_objidx, class->size);
680
681 link = (struct link_free *)kmap_atomic(m_page) +
682 m_offset / sizeof(*link);
683 first_page->freelist = link->next;
684 memset(link, POISON_INUSE, sizeof(*link));
685 kunmap_atomic(link);
686
687 first_page->inuse++;
688 /* Now move the zspage to another fullness group, if required */
689 fix_fullness_group(pool, first_page);
690 spin_unlock(&class->lock);
691
692 return obj;
693}
694EXPORT_SYMBOL_GPL(zs_malloc);
695
c2344348 696void zs_free(struct zs_pool *pool, unsigned long obj)
61989a80
NG
697{
698 struct link_free *link;
699 struct page *first_page, *f_page;
700 unsigned long f_objidx, f_offset;
701
702 int class_idx;
703 struct size_class *class;
704 enum fullness_group fullness;
705
706 if (unlikely(!obj))
707 return;
708
709 obj_handle_to_location(obj, &f_page, &f_objidx);
710 first_page = get_first_page(f_page);
711
712 get_zspage_mapping(first_page, &class_idx, &fullness);
713 class = &pool->size_class[class_idx];
714 f_offset = obj_idx_to_offset(f_page, f_objidx, class->size);
715
716 spin_lock(&class->lock);
717
718 /* Insert this object in containing zspage's freelist */
719 link = (struct link_free *)((unsigned char *)kmap_atomic(f_page)
720 + f_offset);
721 link->next = first_page->freelist;
722 kunmap_atomic(link);
c2344348 723 first_page->freelist = (void *)obj;
61989a80
NG
724
725 first_page->inuse--;
726 fullness = fix_fullness_group(pool, first_page);
727
728 if (fullness == ZS_EMPTY)
2e3b6154 729 class->pages_allocated -= class->pages_per_zspage;
61989a80
NG
730
731 spin_unlock(&class->lock);
732
733 if (fullness == ZS_EMPTY)
734 free_zspage(first_page);
735}
736EXPORT_SYMBOL_GPL(zs_free);
737
00a61d86
MK
738/**
739 * zs_map_object - get address of allocated object from handle.
740 * @pool: pool from which the object was allocated
741 * @handle: handle returned from zs_malloc
742 *
743 * Before using an object allocated from zs_malloc, it must be mapped using
744 * this function. When done with the object, it must be unmapped using
166cfda7
SJ
745 * zs_unmap_object.
746 *
747 * Only one object can be mapped per cpu at a time. There is no protection
748 * against nested mappings.
749 *
750 * This function returns with preemption and page faults disabled.
00a61d86 751*/
b7418510
SJ
752void *zs_map_object(struct zs_pool *pool, unsigned long handle,
753 enum zs_mapmode mm)
61989a80
NG
754{
755 struct page *page;
756 unsigned long obj_idx, off;
757
758 unsigned int class_idx;
759 enum fullness_group fg;
760 struct size_class *class;
761 struct mapping_area *area;
762
763 BUG_ON(!handle);
764
c60369f0
SJ
765 /*
766 * Because we use per-cpu mapping areas shared among the
767 * pools/users, we can't allow mapping in interrupt context
768 * because it can corrupt another users mappings.
769 */
770 BUG_ON(in_interrupt());
771
61989a80
NG
772 obj_handle_to_location(handle, &page, &obj_idx);
773 get_zspage_mapping(get_first_page(page), &class_idx, &fg);
774 class = &pool->size_class[class_idx];
775 off = obj_idx_to_offset(page, obj_idx, class->size);
776
777 area = &get_cpu_var(zs_map_area);
778 if (off + class->size <= PAGE_SIZE) {
779 /* this object is contained entirely within a page */
780 area->vm_addr = kmap_atomic(page);
5f601902 781 return area->vm_addr + off;
61989a80
NG
782 }
783
b7418510
SJ
784 /* disable page faults to match kmap_atomic() return conditions */
785 pagefault_disable();
786
787 if (mm != ZS_MM_WO)
788 zs_copy_map_object(area->vm_buf, page, off, class->size);
10312330 789 area->vm_addr = NULL;
5f601902 790 return area->vm_buf;
61989a80
NG
791}
792EXPORT_SYMBOL_GPL(zs_map_object);
793
c2344348 794void zs_unmap_object(struct zs_pool *pool, unsigned long handle)
61989a80
NG
795{
796 struct page *page;
797 unsigned long obj_idx, off;
798
799 unsigned int class_idx;
800 enum fullness_group fg;
801 struct size_class *class;
802 struct mapping_area *area;
803
10312330 804 area = &__get_cpu_var(zs_map_area);
b7418510 805 /* single-page object fastpath */
10312330 806 if (area->vm_addr) {
10312330 807 kunmap_atomic(area->vm_addr);
b7418510 808 goto out;
10312330
SJ
809 }
810
b7418510
SJ
811 /* no write fastpath */
812 if (area->vm_mm == ZS_MM_RO)
813 goto pfenable;
814
61989a80
NG
815 BUG_ON(!handle);
816
817 obj_handle_to_location(handle, &page, &obj_idx);
818 get_zspage_mapping(get_first_page(page), &class_idx, &fg);
819 class = &pool->size_class[class_idx];
820 off = obj_idx_to_offset(page, obj_idx, class->size);
821
10312330 822 zs_copy_unmap_object(area->vm_buf, page, off, class->size);
b7418510
SJ
823
824pfenable:
825 /* enable page faults to match kunmap_atomic() return conditions */
826 pagefault_enable();
827out:
61989a80
NG
828 put_cpu_var(zs_map_area);
829}
830EXPORT_SYMBOL_GPL(zs_unmap_object);
831
832u64 zs_get_total_size_bytes(struct zs_pool *pool)
833{
834 int i;
835 u64 npages = 0;
836
837 for (i = 0; i < ZS_SIZE_CLASSES; i++)
838 npages += pool->size_class[i].pages_allocated;
839
840 return npages << PAGE_SHIFT;
841}
842EXPORT_SYMBOL_GPL(zs_get_total_size_bytes);
069f101f
BH
843
844module_init(zs_init);
845module_exit(zs_exit);
846
847MODULE_LICENSE("Dual BSD/GPL");
848MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>");