1 // SPDX-License-Identifier: GPL-2.0-only 1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 2 /* 3 * z3fold.c 3 * z3fold.c 4 * 4 * 5 * Author: Vitaly Wool <vitaly.wool@konsulko.c 5 * Author: Vitaly Wool <vitaly.wool@konsulko.com> 6 * Copyright (C) 2016, Sony Mobile Communicati 6 * Copyright (C) 2016, Sony Mobile Communications Inc. 7 * 7 * 8 * This implementation is based on zbud writte 8 * This implementation is based on zbud written by Seth Jennings. 9 * 9 * 10 * z3fold is an special purpose allocator for 10 * z3fold is an special purpose allocator for storing compressed pages. It 11 * can store up to three compressed pages per 11 * can store up to three compressed pages per page which improves the 12 * compression ratio of zbud while retaining i 12 * compression ratio of zbud while retaining its main concepts (e. g. always 13 * storing an integral number of objects per p 13 * storing an integral number of objects per page) and simplicity. 14 * It still has simple and deterministic recla 14 * It still has simple and deterministic reclaim properties that make it 15 * preferable to a higher density approach (wi 15 * preferable to a higher density approach (with no requirement on integral 16 * number of object per page) when reclaim is 16 * number of object per page) when reclaim is used. 17 * 17 * 18 * As in zbud, pages are divided into "chunks" 18 * As in zbud, pages are divided into "chunks". The size of the chunks is 19 * fixed at compile time and is determined by 19 * fixed at compile time and is determined by NCHUNKS_ORDER below. 20 * 20 * 21 * z3fold doesn't export any API and is meant 21 * z3fold doesn't export any API and is meant to be used via zpool API. 22 */ 22 */ 23 23 24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 25 25 26 #include <linux/atomic.h> 26 #include <linux/atomic.h> 27 #include <linux/sched.h> 27 #include <linux/sched.h> 28 #include <linux/cpumask.h> 28 #include <linux/cpumask.h> >> 29 #include <linux/dcache.h> 29 #include <linux/list.h> 30 #include <linux/list.h> 30 #include <linux/mm.h> 31 #include <linux/mm.h> 31 #include <linux/module.h> 32 #include <linux/module.h> 32 #include <linux/page-flags.h> 33 #include <linux/page-flags.h> 33 #include <linux/migrate.h> 34 #include <linux/migrate.h> 34 #include <linux/node.h> 35 #include <linux/node.h> 35 #include <linux/compaction.h> 36 #include <linux/compaction.h> 36 #include <linux/percpu.h> 37 #include <linux/percpu.h> >> 38 #include <linux/mount.h> >> 39 #include <linux/fs.h> 37 #include <linux/preempt.h> 40 #include <linux/preempt.h> 38 #include <linux/workqueue.h> 41 #include <linux/workqueue.h> 39 #include <linux/slab.h> 42 #include <linux/slab.h> 40 #include <linux/spinlock.h> 43 #include <linux/spinlock.h> 41 #include <linux/zpool.h> 44 #include <linux/zpool.h> 42 #include <linux/kmemleak.h> << 43 45 44 /* 46 /* 45 * NCHUNKS_ORDER determines the internal alloc 47 * NCHUNKS_ORDER determines the internal allocation granularity, effectively 46 * adjusting internal fragmentation. It also 48 * adjusting internal fragmentation. It also determines the number of 47 * freelists maintained in each pool. NCHUNKS_ 49 * freelists maintained in each pool. NCHUNKS_ORDER of 6 means that the 48 * allocation granularity will be in chunks of 50 * allocation granularity will be in chunks of size PAGE_SIZE/64. Some chunks 49 * in the beginning of an allocated page are o 51 * in the beginning of an allocated page are occupied by z3fold header, so 50 * NCHUNKS will be calculated to 63 (or 62 in 52 * NCHUNKS will be calculated to 63 (or 62 in case CONFIG_DEBUG_SPINLOCK=y), 51 * which shows the max number of free chunks i 53 * which shows the max number of free chunks in z3fold page, also there will 52 * be 63, or 62, respectively, freelists per p 54 * be 63, or 62, respectively, freelists per pool. 53 */ 55 */ 54 #define NCHUNKS_ORDER 6 56 #define NCHUNKS_ORDER 6 55 57 56 #define CHUNK_SHIFT (PAGE_SHIFT - NCHUNKS_ 58 #define CHUNK_SHIFT (PAGE_SHIFT - NCHUNKS_ORDER) 57 #define CHUNK_SIZE (1 << CHUNK_SHIFT) 59 #define CHUNK_SIZE (1 << CHUNK_SHIFT) 58 #define ZHDR_SIZE_ALIGNED round_up(sizeof(stru 60 #define ZHDR_SIZE_ALIGNED round_up(sizeof(struct z3fold_header), CHUNK_SIZE) 59 #define ZHDR_CHUNKS (ZHDR_SIZE_ALIGNED >> 61 #define ZHDR_CHUNKS (ZHDR_SIZE_ALIGNED >> CHUNK_SHIFT) 60 #define TOTAL_CHUNKS (PAGE_SIZE >> CHUNK_SH 62 #define TOTAL_CHUNKS (PAGE_SIZE >> CHUNK_SHIFT) 61 #define NCHUNKS (TOTAL_CHUNKS - ZHDR_C !! 63 #define NCHUNKS ((PAGE_SIZE - ZHDR_SIZE_ALIGNED) >> CHUNK_SHIFT) 62 64 63 #define BUDDY_MASK (0x3) 65 #define BUDDY_MASK (0x3) 64 #define BUDDY_SHIFT 2 66 #define BUDDY_SHIFT 2 65 #define SLOTS_ALIGN (0x40) 67 #define SLOTS_ALIGN (0x40) 66 68 67 /***************** 69 /***************** 68 * Structures 70 * Structures 69 *****************/ 71 *****************/ 70 struct z3fold_pool; 72 struct z3fold_pool; >> 73 struct z3fold_ops { >> 74 int (*evict)(struct z3fold_pool *pool, unsigned long handle); >> 75 }; 71 76 72 enum buddy { 77 enum buddy { 73 HEADLESS = 0, 78 HEADLESS = 0, 74 FIRST, 79 FIRST, 75 MIDDLE, 80 MIDDLE, 76 LAST, 81 LAST, 77 BUDDIES_MAX = LAST 82 BUDDIES_MAX = LAST 78 }; 83 }; 79 84 80 struct z3fold_buddy_slots { 85 struct z3fold_buddy_slots { 81 /* 86 /* 82 * we are using BUDDY_MASK in handle_t 87 * we are using BUDDY_MASK in handle_to_buddy etc. so there should 83 * be enough slots to hold all possibl 88 * be enough slots to hold all possible variants 84 */ 89 */ 85 unsigned long slot[BUDDY_MASK + 1]; 90 unsigned long slot[BUDDY_MASK + 1]; 86 unsigned long pool; /* back link */ !! 91 unsigned long pool; /* back link + flags */ 87 rwlock_t lock; << 88 }; 92 }; 89 #define HANDLE_FLAG_MASK (0x03) 93 #define HANDLE_FLAG_MASK (0x03) 90 94 91 /* 95 /* 92 * struct z3fold_header - z3fold page metadata 96 * struct z3fold_header - z3fold page metadata occupying first chunks of each 93 * z3fold page, except fo 97 * z3fold page, except for HEADLESS pages 94 * @buddy: links the z3fold page 98 * @buddy: links the z3fold page into the relevant list in the 95 * pool 99 * pool 96 * @page_lock: per-page lock 100 * @page_lock: per-page lock 97 * @refcount: reference count for th 101 * @refcount: reference count for the z3fold page 98 * @work: work_struct for page l 102 * @work: work_struct for page layout optimization 99 * @slots: pointer to the structu 103 * @slots: pointer to the structure holding buddy slots 100 * @pool: pointer to the contain 104 * @pool: pointer to the containing pool 101 * @cpu: CPU which this page "b 105 * @cpu: CPU which this page "belongs" to 102 * @first_chunks: the size of the first 106 * @first_chunks: the size of the first buddy in chunks, 0 if free 103 * @middle_chunks: the size of the middle 107 * @middle_chunks: the size of the middle buddy in chunks, 0 if free 104 * @last_chunks: the size of the last b 108 * @last_chunks: the size of the last buddy in chunks, 0 if free 105 * @first_num: the starting number (f 109 * @first_num: the starting number (for the first handle) 106 * @mapped_count: the number of objects 110 * @mapped_count: the number of objects currently mapped 107 */ 111 */ 108 struct z3fold_header { 112 struct z3fold_header { 109 struct list_head buddy; 113 struct list_head buddy; 110 spinlock_t page_lock; 114 spinlock_t page_lock; 111 struct kref refcount; 115 struct kref refcount; 112 struct work_struct work; 116 struct work_struct work; 113 struct z3fold_buddy_slots *slots; 117 struct z3fold_buddy_slots *slots; 114 struct z3fold_pool *pool; 118 struct z3fold_pool *pool; 115 short cpu; 119 short cpu; 116 unsigned short first_chunks; 120 unsigned short first_chunks; 117 unsigned short middle_chunks; 121 unsigned short middle_chunks; 118 unsigned short last_chunks; 122 unsigned short last_chunks; 119 unsigned short start_middle; 123 unsigned short start_middle; 120 unsigned short first_num:2; 124 unsigned short first_num:2; 121 unsigned short mapped_count:2; 125 unsigned short mapped_count:2; 122 unsigned short foreign_handles:2; << 123 }; 126 }; 124 127 125 /** 128 /** 126 * struct z3fold_pool - stores metadata for ea 129 * struct z3fold_pool - stores metadata for each z3fold pool 127 * @name: pool name 130 * @name: pool name 128 * @lock: protects pool unbuddied lists !! 131 * @lock: protects pool unbuddied/lru lists 129 * @stale_lock: protects pool stale page list 132 * @stale_lock: protects pool stale page list 130 * @unbuddied: per-cpu array of lists trackin 133 * @unbuddied: per-cpu array of lists tracking z3fold pages that contain 2- 131 * buddies; the list each z3fold 134 * buddies; the list each z3fold page is added to depends on 132 * the size of its free region. 135 * the size of its free region. >> 136 * @lru: list tracking the z3fold pages in LRU order by most recently >> 137 * added buddy. 133 * @stale: list of pages marked for freei 138 * @stale: list of pages marked for freeing 134 * @pages_nr: number of z3fold pages in the 139 * @pages_nr: number of z3fold pages in the pool. 135 * @c_handle: cache for z3fold_buddy_slots a 140 * @c_handle: cache for z3fold_buddy_slots allocation >> 141 * @ops: pointer to a structure of user defined operations specified at >> 142 * pool creation time. 136 * @compact_wq: workqueue for page layout back 143 * @compact_wq: workqueue for page layout background optimization 137 * @release_wq: workqueue for safe page releas 144 * @release_wq: workqueue for safe page release 138 * @work: work_struct for safe page rele 145 * @work: work_struct for safe page release >> 146 * @inode: inode for z3fold pseudo filesystem 139 * 147 * 140 * This structure is allocated at pool creatio 148 * This structure is allocated at pool creation time and maintains metadata 141 * pertaining to a particular z3fold pool. 149 * pertaining to a particular z3fold pool. 142 */ 150 */ 143 struct z3fold_pool { 151 struct z3fold_pool { 144 const char *name; 152 const char *name; 145 spinlock_t lock; 153 spinlock_t lock; 146 spinlock_t stale_lock; 154 spinlock_t stale_lock; 147 struct list_head __percpu *unbuddied; !! 155 struct list_head *unbuddied; >> 156 struct list_head lru; 148 struct list_head stale; 157 struct list_head stale; 149 atomic64_t pages_nr; 158 atomic64_t pages_nr; 150 struct kmem_cache *c_handle; 159 struct kmem_cache *c_handle; >> 160 const struct z3fold_ops *ops; >> 161 struct zpool *zpool; >> 162 const struct zpool_ops *zpool_ops; 151 struct workqueue_struct *compact_wq; 163 struct workqueue_struct *compact_wq; 152 struct workqueue_struct *release_wq; 164 struct workqueue_struct *release_wq; 153 struct work_struct work; 165 struct work_struct work; >> 166 struct inode *inode; 154 }; 167 }; 155 168 156 /* 169 /* 157 * Internal z3fold page flags 170 * Internal z3fold page flags 158 */ 171 */ 159 enum z3fold_page_flags { 172 enum z3fold_page_flags { 160 PAGE_HEADLESS = 0, 173 PAGE_HEADLESS = 0, 161 MIDDLE_CHUNK_MAPPED, 174 MIDDLE_CHUNK_MAPPED, 162 NEEDS_COMPACTING, 175 NEEDS_COMPACTING, 163 PAGE_STALE, 176 PAGE_STALE, 164 PAGE_CLAIMED, /* by either reclaim or 177 PAGE_CLAIMED, /* by either reclaim or free */ 165 PAGE_MIGRATED, /* page is migrated and << 166 }; << 167 << 168 /* << 169 * handle flags, go under HANDLE_FLAG_MASK << 170 */ << 171 enum z3fold_handle_flags { << 172 HANDLES_NOFREE = 0, << 173 }; 178 }; 174 179 175 /* << 176 * Forward declarations << 177 */ << 178 static struct z3fold_header *__z3fold_alloc(st << 179 static void compact_page_work(struct work_stru << 180 << 181 /***************** 180 /***************** 182 * Helpers 181 * Helpers 183 *****************/ 182 *****************/ 184 183 185 /* Converts an allocation size in bytes to siz 184 /* Converts an allocation size in bytes to size in z3fold chunks */ 186 static int size_to_chunks(size_t size) 185 static int size_to_chunks(size_t size) 187 { 186 { 188 return (size + CHUNK_SIZE - 1) >> CHUN 187 return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; 189 } 188 } 190 189 191 #define for_each_unbuddied_list(_iter, _begin) 190 #define for_each_unbuddied_list(_iter, _begin) \ 192 for ((_iter) = (_begin); (_iter) < NCH 191 for ((_iter) = (_begin); (_iter) < NCHUNKS; (_iter)++) 193 192 >> 193 static void compact_page_work(struct work_struct *w); >> 194 194 static inline struct z3fold_buddy_slots *alloc 195 static inline struct z3fold_buddy_slots *alloc_slots(struct z3fold_pool *pool, 195 196 gfp_t gfp) 196 { 197 { 197 struct z3fold_buddy_slots *slots = kme !! 198 struct z3fold_buddy_slots *slots = kmem_cache_alloc(pool->c_handle, 198 !! 199 gfp); 199 200 200 if (slots) { 201 if (slots) { 201 /* It will be freed separately !! 202 memset(slots->slot, 0, sizeof(slots->slot)); 202 kmemleak_not_leak(slots); << 203 slots->pool = (unsigned long)p 203 slots->pool = (unsigned long)pool; 204 rwlock_init(&slots->lock); << 205 } 204 } 206 205 207 return slots; 206 return slots; 208 } 207 } 209 208 210 static inline struct z3fold_pool *slots_to_poo 209 static inline struct z3fold_pool *slots_to_pool(struct z3fold_buddy_slots *s) 211 { 210 { 212 return (struct z3fold_pool *)(s->pool 211 return (struct z3fold_pool *)(s->pool & ~HANDLE_FLAG_MASK); 213 } 212 } 214 213 215 static inline struct z3fold_buddy_slots *handl 214 static inline struct z3fold_buddy_slots *handle_to_slots(unsigned long handle) 216 { 215 { 217 return (struct z3fold_buddy_slots *)(h 216 return (struct z3fold_buddy_slots *)(handle & ~(SLOTS_ALIGN - 1)); 218 } 217 } 219 218 220 /* Lock a z3fold page */ !! 219 static inline void free_handle(unsigned long handle) 221 static inline void z3fold_page_lock(struct z3f << 222 { << 223 spin_lock(&zhdr->page_lock); << 224 } << 225 << 226 /* Try to lock a z3fold page */ << 227 static inline int z3fold_page_trylock(struct z << 228 { << 229 return spin_trylock(&zhdr->page_lock); << 230 } << 231 << 232 /* Unlock a z3fold page */ << 233 static inline void z3fold_page_unlock(struct z << 234 { << 235 spin_unlock(&zhdr->page_lock); << 236 } << 237 << 238 /* return locked z3fold page if it's not headl << 239 static inline struct z3fold_header *get_z3fold << 240 { << 241 struct z3fold_buddy_slots *slots; << 242 struct z3fold_header *zhdr; << 243 int locked = 0; << 244 << 245 if (!(handle & (1 << PAGE_HEADLESS))) << 246 slots = handle_to_slots(handle << 247 do { << 248 unsigned long addr; << 249 << 250 read_lock(&slots->lock << 251 addr = *(unsigned long << 252 zhdr = (struct z3fold_ << 253 locked = z3fold_page_t << 254 read_unlock(&slots->lo << 255 if (locked) { << 256 struct page *p << 257 << 258 if (!test_bit( << 259 break; << 260 z3fold_page_un << 261 } << 262 cpu_relax(); << 263 } while (true); << 264 } else { << 265 zhdr = (struct z3fold_header * << 266 } << 267 << 268 return zhdr; << 269 } << 270 << 271 static inline void put_z3fold_header(struct z3 << 272 { << 273 struct page *page = virt_to_page(zhdr) << 274 << 275 if (!test_bit(PAGE_HEADLESS, &page->pr << 276 z3fold_page_unlock(zhdr); << 277 } << 278 << 279 static inline void free_handle(unsigned long h << 280 { 220 { 281 struct z3fold_buddy_slots *slots; 221 struct z3fold_buddy_slots *slots; 282 int i; 222 int i; 283 bool is_free; 223 bool is_free; 284 224 285 if (WARN_ON(*(unsigned long *)handle = !! 225 if (handle & (1 << PAGE_HEADLESS)) 286 return; 226 return; 287 227 288 slots = handle_to_slots(handle); !! 228 WARN_ON(*(unsigned long *)handle == 0); 289 write_lock(&slots->lock); << 290 *(unsigned long *)handle = 0; 229 *(unsigned long *)handle = 0; 291 !! 230 slots = handle_to_slots(handle); 292 if (test_bit(HANDLES_NOFREE, &slots->p << 293 write_unlock(&slots->lock); << 294 return; /* simple case, nothin << 295 } << 296 << 297 if (zhdr->slots != slots) << 298 zhdr->foreign_handles--; << 299 << 300 is_free = true; 231 is_free = true; 301 for (i = 0; i <= BUDDY_MASK; i++) { 232 for (i = 0; i <= BUDDY_MASK; i++) { 302 if (slots->slot[i]) { 233 if (slots->slot[i]) { 303 is_free = false; 234 is_free = false; 304 break; 235 break; 305 } 236 } 306 } 237 } 307 write_unlock(&slots->lock); << 308 238 309 if (is_free) { 239 if (is_free) { 310 struct z3fold_pool *pool = slo 240 struct z3fold_pool *pool = slots_to_pool(slots); 311 241 312 if (zhdr->slots == slots) << 313 zhdr->slots = NULL; << 314 kmem_cache_free(pool->c_handle 242 kmem_cache_free(pool->c_handle, slots); 315 } 243 } 316 } 244 } 317 245 >> 246 static struct dentry *z3fold_do_mount(struct file_system_type *fs_type, >> 247 int flags, const char *dev_name, void *data) >> 248 { >> 249 static const struct dentry_operations ops = { >> 250 .d_dname = simple_dname, >> 251 }; >> 252 >> 253 return mount_pseudo(fs_type, "z3fold:", NULL, &ops, 0x33); >> 254 } >> 255 >> 256 static struct file_system_type z3fold_fs = { >> 257 .name = "z3fold", >> 258 .mount = z3fold_do_mount, >> 259 .kill_sb = kill_anon_super, >> 260 }; >> 261 >> 262 static struct vfsmount *z3fold_mnt; >> 263 static int z3fold_mount(void) >> 264 { >> 265 int ret = 0; >> 266 >> 267 z3fold_mnt = kern_mount(&z3fold_fs); >> 268 if (IS_ERR(z3fold_mnt)) >> 269 ret = PTR_ERR(z3fold_mnt); >> 270 >> 271 return ret; >> 272 } >> 273 >> 274 static void z3fold_unmount(void) >> 275 { >> 276 kern_unmount(z3fold_mnt); >> 277 } >> 278 >> 279 static const struct address_space_operations z3fold_aops; >> 280 static int z3fold_register_migration(struct z3fold_pool *pool) >> 281 { >> 282 pool->inode = alloc_anon_inode(z3fold_mnt->mnt_sb); >> 283 if (IS_ERR(pool->inode)) { >> 284 pool->inode = NULL; >> 285 return 1; >> 286 } >> 287 >> 288 pool->inode->i_mapping->private_data = pool; >> 289 pool->inode->i_mapping->a_ops = &z3fold_aops; >> 290 return 0; >> 291 } >> 292 >> 293 static void z3fold_unregister_migration(struct z3fold_pool *pool) >> 294 { >> 295 if (pool->inode) >> 296 iput(pool->inode); >> 297 } >> 298 318 /* Initializes the z3fold header of a newly al 299 /* Initializes the z3fold header of a newly allocated z3fold page */ 319 static struct z3fold_header *init_z3fold_page( 300 static struct z3fold_header *init_z3fold_page(struct page *page, bool headless, 320 struct 301 struct z3fold_pool *pool, gfp_t gfp) 321 { 302 { 322 struct z3fold_header *zhdr = page_addr 303 struct z3fold_header *zhdr = page_address(page); 323 struct z3fold_buddy_slots *slots; 304 struct z3fold_buddy_slots *slots; 324 305 >> 306 INIT_LIST_HEAD(&page->lru); 325 clear_bit(PAGE_HEADLESS, &page->privat 307 clear_bit(PAGE_HEADLESS, &page->private); 326 clear_bit(MIDDLE_CHUNK_MAPPED, &page-> 308 clear_bit(MIDDLE_CHUNK_MAPPED, &page->private); 327 clear_bit(NEEDS_COMPACTING, &page->pri 309 clear_bit(NEEDS_COMPACTING, &page->private); 328 clear_bit(PAGE_STALE, &page->private); 310 clear_bit(PAGE_STALE, &page->private); 329 clear_bit(PAGE_CLAIMED, &page->private 311 clear_bit(PAGE_CLAIMED, &page->private); 330 clear_bit(PAGE_MIGRATED, &page->privat << 331 if (headless) 312 if (headless) 332 return zhdr; 313 return zhdr; 333 314 334 slots = alloc_slots(pool, gfp); 315 slots = alloc_slots(pool, gfp); 335 if (!slots) 316 if (!slots) 336 return NULL; 317 return NULL; 337 318 338 memset(zhdr, 0, sizeof(*zhdr)); << 339 spin_lock_init(&zhdr->page_lock); 319 spin_lock_init(&zhdr->page_lock); 340 kref_init(&zhdr->refcount); 320 kref_init(&zhdr->refcount); >> 321 zhdr->first_chunks = 0; >> 322 zhdr->middle_chunks = 0; >> 323 zhdr->last_chunks = 0; >> 324 zhdr->first_num = 0; >> 325 zhdr->start_middle = 0; 341 zhdr->cpu = -1; 326 zhdr->cpu = -1; 342 zhdr->slots = slots; 327 zhdr->slots = slots; 343 zhdr->pool = pool; 328 zhdr->pool = pool; 344 INIT_LIST_HEAD(&zhdr->buddy); 329 INIT_LIST_HEAD(&zhdr->buddy); 345 INIT_WORK(&zhdr->work, compact_page_wo 330 INIT_WORK(&zhdr->work, compact_page_work); 346 return zhdr; 331 return zhdr; 347 } 332 } 348 333 349 /* Resets the struct page fields and frees the 334 /* Resets the struct page fields and frees the page */ 350 static void free_z3fold_page(struct page *page 335 static void free_z3fold_page(struct page *page, bool headless) 351 { 336 { 352 if (!headless) { 337 if (!headless) { 353 lock_page(page); 338 lock_page(page); 354 __ClearPageMovable(page); 339 __ClearPageMovable(page); 355 unlock_page(page); 340 unlock_page(page); 356 } 341 } >> 342 ClearPagePrivate(page); 357 __free_page(page); 343 __free_page(page); 358 } 344 } 359 345 >> 346 /* Lock a z3fold page */ >> 347 static inline void z3fold_page_lock(struct z3fold_header *zhdr) >> 348 { >> 349 spin_lock(&zhdr->page_lock); >> 350 } >> 351 >> 352 /* Try to lock a z3fold page */ >> 353 static inline int z3fold_page_trylock(struct z3fold_header *zhdr) >> 354 { >> 355 return spin_trylock(&zhdr->page_lock); >> 356 } >> 357 >> 358 /* Unlock a z3fold page */ >> 359 static inline void z3fold_page_unlock(struct z3fold_header *zhdr) >> 360 { >> 361 spin_unlock(&zhdr->page_lock); >> 362 } >> 363 360 /* Helper function to build the index */ 364 /* Helper function to build the index */ 361 static inline int __idx(struct z3fold_header * 365 static inline int __idx(struct z3fold_header *zhdr, enum buddy bud) 362 { 366 { 363 return (bud + zhdr->first_num) & BUDDY 367 return (bud + zhdr->first_num) & BUDDY_MASK; 364 } 368 } 365 369 366 /* 370 /* 367 * Encodes the handle of a particular buddy wi !! 371 * Encodes the handle of a particular buddy within a z3fold page 368 * Zhdr->page_lock should be held as this func !! 372 * Pool lock should be held as this function accesses first_num 369 * if bud != HEADLESS. << 370 */ 373 */ 371 static unsigned long __encode_handle(struct z3 374 static unsigned long __encode_handle(struct z3fold_header *zhdr, 372 struct z3fold_ 375 struct z3fold_buddy_slots *slots, 373 enum buddy bud 376 enum buddy bud) 374 { 377 { 375 unsigned long h = (unsigned long)zhdr; 378 unsigned long h = (unsigned long)zhdr; 376 int idx = 0; 379 int idx = 0; 377 380 378 /* 381 /* 379 * For a headless page, its handle is 382 * For a headless page, its handle is its pointer with the extra 380 * PAGE_HEADLESS bit set 383 * PAGE_HEADLESS bit set 381 */ 384 */ 382 if (bud == HEADLESS) 385 if (bud == HEADLESS) 383 return h | (1 << PAGE_HEADLESS 386 return h | (1 << PAGE_HEADLESS); 384 387 385 /* otherwise, return pointer to encode 388 /* otherwise, return pointer to encoded handle */ 386 idx = __idx(zhdr, bud); 389 idx = __idx(zhdr, bud); 387 h += idx; 390 h += idx; 388 if (bud == LAST) 391 if (bud == LAST) 389 h |= (zhdr->last_chunks << BUD 392 h |= (zhdr->last_chunks << BUDDY_SHIFT); 390 393 391 write_lock(&slots->lock); << 392 slots->slot[idx] = h; 394 slots->slot[idx] = h; 393 write_unlock(&slots->lock); << 394 return (unsigned long)&slots->slot[idx 395 return (unsigned long)&slots->slot[idx]; 395 } 396 } 396 397 397 static unsigned long encode_handle(struct z3fo 398 static unsigned long encode_handle(struct z3fold_header *zhdr, enum buddy bud) 398 { 399 { 399 return __encode_handle(zhdr, zhdr->slo 400 return __encode_handle(zhdr, zhdr->slots, bud); 400 } 401 } 401 402 >> 403 /* Returns the z3fold page where a given handle is stored */ >> 404 static inline struct z3fold_header *handle_to_z3fold_header(unsigned long h) >> 405 { >> 406 unsigned long addr = h; >> 407 >> 408 if (!(addr & (1 << PAGE_HEADLESS))) >> 409 addr = *(unsigned long *)h; >> 410 >> 411 return (struct z3fold_header *)(addr & PAGE_MASK); >> 412 } >> 413 402 /* only for LAST bud, returns zero otherwise * 414 /* only for LAST bud, returns zero otherwise */ 403 static unsigned short handle_to_chunks(unsigne 415 static unsigned short handle_to_chunks(unsigned long handle) 404 { 416 { 405 struct z3fold_buddy_slots *slots = han !! 417 unsigned long addr = *(unsigned long *)handle; 406 unsigned long addr; << 407 418 408 read_lock(&slots->lock); << 409 addr = *(unsigned long *)handle; << 410 read_unlock(&slots->lock); << 411 return (addr & ~PAGE_MASK) >> BUDDY_SH 419 return (addr & ~PAGE_MASK) >> BUDDY_SHIFT; 412 } 420 } 413 421 414 /* 422 /* 415 * (handle & BUDDY_MASK) < zhdr->first_num is 423 * (handle & BUDDY_MASK) < zhdr->first_num is possible in encode_handle 416 * but that doesn't matter. because the maski 424 * but that doesn't matter. because the masking will result in the 417 * correct buddy number. 425 * correct buddy number. 418 */ 426 */ 419 static enum buddy handle_to_buddy(unsigned lon 427 static enum buddy handle_to_buddy(unsigned long handle) 420 { 428 { 421 struct z3fold_header *zhdr; 429 struct z3fold_header *zhdr; 422 struct z3fold_buddy_slots *slots = han << 423 unsigned long addr; 430 unsigned long addr; 424 431 425 read_lock(&slots->lock); << 426 WARN_ON(handle & (1 << PAGE_HEADLESS)) 432 WARN_ON(handle & (1 << PAGE_HEADLESS)); 427 addr = *(unsigned long *)handle; 433 addr = *(unsigned long *)handle; 428 read_unlock(&slots->lock); << 429 zhdr = (struct z3fold_header *)(addr & 434 zhdr = (struct z3fold_header *)(addr & PAGE_MASK); 430 return (addr - zhdr->first_num) & BUDD 435 return (addr - zhdr->first_num) & BUDDY_MASK; 431 } 436 } 432 437 433 static inline struct z3fold_pool *zhdr_to_pool 438 static inline struct z3fold_pool *zhdr_to_pool(struct z3fold_header *zhdr) 434 { 439 { 435 return zhdr->pool; 440 return zhdr->pool; 436 } 441 } 437 442 438 static void __release_z3fold_page(struct z3fol 443 static void __release_z3fold_page(struct z3fold_header *zhdr, bool locked) 439 { 444 { 440 struct page *page = virt_to_page(zhdr) 445 struct page *page = virt_to_page(zhdr); 441 struct z3fold_pool *pool = zhdr_to_poo 446 struct z3fold_pool *pool = zhdr_to_pool(zhdr); 442 447 443 WARN_ON(!list_empty(&zhdr->buddy)); 448 WARN_ON(!list_empty(&zhdr->buddy)); 444 set_bit(PAGE_STALE, &page->private); 449 set_bit(PAGE_STALE, &page->private); 445 clear_bit(NEEDS_COMPACTING, &page->pri 450 clear_bit(NEEDS_COMPACTING, &page->private); 446 spin_lock(&pool->lock); 451 spin_lock(&pool->lock); >> 452 if (!list_empty(&page->lru)) >> 453 list_del_init(&page->lru); 447 spin_unlock(&pool->lock); 454 spin_unlock(&pool->lock); 448 << 449 if (locked) 455 if (locked) 450 z3fold_page_unlock(zhdr); 456 z3fold_page_unlock(zhdr); 451 << 452 spin_lock(&pool->stale_lock); 457 spin_lock(&pool->stale_lock); 453 list_add(&zhdr->buddy, &pool->stale); 458 list_add(&zhdr->buddy, &pool->stale); 454 queue_work(pool->release_wq, &pool->wo 459 queue_work(pool->release_wq, &pool->work); 455 spin_unlock(&pool->stale_lock); 460 spin_unlock(&pool->stale_lock); >> 461 } 456 462 457 atomic64_dec(&pool->pages_nr); !! 463 static void __attribute__((__unused__)) >> 464 release_z3fold_page(struct kref *ref) >> 465 { >> 466 struct z3fold_header *zhdr = container_of(ref, struct z3fold_header, >> 467 refcount); >> 468 __release_z3fold_page(zhdr, false); 458 } 469 } 459 470 460 static void release_z3fold_page_locked(struct 471 static void release_z3fold_page_locked(struct kref *ref) 461 { 472 { 462 struct z3fold_header *zhdr = container 473 struct z3fold_header *zhdr = container_of(ref, struct z3fold_header, 463 474 refcount); 464 WARN_ON(z3fold_page_trylock(zhdr)); 475 WARN_ON(z3fold_page_trylock(zhdr)); 465 __release_z3fold_page(zhdr, true); 476 __release_z3fold_page(zhdr, true); 466 } 477 } 467 478 468 static void release_z3fold_page_locked_list(st 479 static void release_z3fold_page_locked_list(struct kref *ref) 469 { 480 { 470 struct z3fold_header *zhdr = container 481 struct z3fold_header *zhdr = container_of(ref, struct z3fold_header, 471 482 refcount); 472 struct z3fold_pool *pool = zhdr_to_poo 483 struct z3fold_pool *pool = zhdr_to_pool(zhdr); 473 << 474 spin_lock(&pool->lock); 484 spin_lock(&pool->lock); 475 list_del_init(&zhdr->buddy); 485 list_del_init(&zhdr->buddy); 476 spin_unlock(&pool->lock); 486 spin_unlock(&pool->lock); 477 487 478 WARN_ON(z3fold_page_trylock(zhdr)); 488 WARN_ON(z3fold_page_trylock(zhdr)); 479 __release_z3fold_page(zhdr, true); 489 __release_z3fold_page(zhdr, true); 480 } 490 } 481 491 482 static inline int put_z3fold_locked(struct z3f << 483 { << 484 return kref_put(&zhdr->refcount, relea << 485 } << 486 << 487 static inline int put_z3fold_locked_list(struc << 488 { << 489 return kref_put(&zhdr->refcount, relea << 490 } << 491 << 492 static void free_pages_work(struct work_struct 492 static void free_pages_work(struct work_struct *w) 493 { 493 { 494 struct z3fold_pool *pool = container_o 494 struct z3fold_pool *pool = container_of(w, struct z3fold_pool, work); 495 495 496 spin_lock(&pool->stale_lock); 496 spin_lock(&pool->stale_lock); 497 while (!list_empty(&pool->stale)) { 497 while (!list_empty(&pool->stale)) { 498 struct z3fold_header *zhdr = l 498 struct z3fold_header *zhdr = list_first_entry(&pool->stale, 499 499 struct z3fold_header, buddy); 500 struct page *page = virt_to_pa 500 struct page *page = virt_to_page(zhdr); 501 501 502 list_del(&zhdr->buddy); 502 list_del(&zhdr->buddy); 503 if (WARN_ON(!test_bit(PAGE_STA 503 if (WARN_ON(!test_bit(PAGE_STALE, &page->private))) 504 continue; 504 continue; 505 spin_unlock(&pool->stale_lock) 505 spin_unlock(&pool->stale_lock); 506 cancel_work_sync(&zhdr->work); 506 cancel_work_sync(&zhdr->work); 507 free_z3fold_page(page, false); 507 free_z3fold_page(page, false); 508 cond_resched(); 508 cond_resched(); 509 spin_lock(&pool->stale_lock); 509 spin_lock(&pool->stale_lock); 510 } 510 } 511 spin_unlock(&pool->stale_lock); 511 spin_unlock(&pool->stale_lock); 512 } 512 } 513 513 514 /* 514 /* 515 * Returns the number of free chunks in a z3fo 515 * Returns the number of free chunks in a z3fold page. 516 * NB: can't be used with HEADLESS pages. 516 * NB: can't be used with HEADLESS pages. 517 */ 517 */ 518 static int num_free_chunks(struct z3fold_heade 518 static int num_free_chunks(struct z3fold_header *zhdr) 519 { 519 { 520 int nfree; 520 int nfree; 521 /* 521 /* 522 * If there is a middle object, pick u 522 * If there is a middle object, pick up the bigger free space 523 * either before or after it. Otherwis 523 * either before or after it. Otherwise just subtract the number 524 * of chunks occupied by the first and 524 * of chunks occupied by the first and the last objects. 525 */ 525 */ 526 if (zhdr->middle_chunks != 0) { 526 if (zhdr->middle_chunks != 0) { 527 int nfree_before = zhdr->first 527 int nfree_before = zhdr->first_chunks ? 528 0 : zhdr->start_middle 528 0 : zhdr->start_middle - ZHDR_CHUNKS; 529 int nfree_after = zhdr->last_c 529 int nfree_after = zhdr->last_chunks ? 530 0 : TOTAL_CHUNKS - 530 0 : TOTAL_CHUNKS - 531 (zhdr->start_m 531 (zhdr->start_middle + zhdr->middle_chunks); 532 nfree = max(nfree_before, nfre 532 nfree = max(nfree_before, nfree_after); 533 } else 533 } else 534 nfree = NCHUNKS - zhdr->first_ 534 nfree = NCHUNKS - zhdr->first_chunks - zhdr->last_chunks; 535 return nfree; 535 return nfree; 536 } 536 } 537 537 538 /* Add to the appropriate unbuddied list */ 538 /* Add to the appropriate unbuddied list */ 539 static inline void add_to_unbuddied(struct z3f 539 static inline void add_to_unbuddied(struct z3fold_pool *pool, 540 struct z3fold_ 540 struct z3fold_header *zhdr) 541 { 541 { 542 if (zhdr->first_chunks == 0 || zhdr->l 542 if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0 || 543 zhdr->middle_chunks == 543 zhdr->middle_chunks == 0) { 544 struct list_head *unbuddied; !! 544 struct list_head *unbuddied = get_cpu_ptr(pool->unbuddied); 545 int freechunks = num_free_chun << 546 545 547 migrate_disable(); !! 546 int freechunks = num_free_chunks(zhdr); 548 unbuddied = this_cpu_ptr(pool- << 549 spin_lock(&pool->lock); 547 spin_lock(&pool->lock); 550 list_add(&zhdr->buddy, &unbudd 548 list_add(&zhdr->buddy, &unbuddied[freechunks]); 551 spin_unlock(&pool->lock); 549 spin_unlock(&pool->lock); 552 zhdr->cpu = smp_processor_id() 550 zhdr->cpu = smp_processor_id(); 553 migrate_enable(); !! 551 put_cpu_ptr(pool->unbuddied); 554 } 552 } 555 } 553 } 556 554 557 static inline enum buddy get_free_buddy(struct << 558 { << 559 enum buddy bud = HEADLESS; << 560 << 561 if (zhdr->middle_chunks) { << 562 if (!zhdr->first_chunks && << 563 chunks <= zhdr->start_midd << 564 bud = FIRST; << 565 else if (!zhdr->last_chunks) << 566 bud = LAST; << 567 } else { << 568 if (!zhdr->first_chunks) << 569 bud = FIRST; << 570 else if (!zhdr->last_chunks) << 571 bud = LAST; << 572 else << 573 bud = MIDDLE; << 574 } << 575 << 576 return bud; << 577 } << 578 << 579 static inline void *mchunk_memmove(struct z3fo 555 static inline void *mchunk_memmove(struct z3fold_header *zhdr, 580 unsigned short 556 unsigned short dst_chunk) 581 { 557 { 582 void *beg = zhdr; 558 void *beg = zhdr; 583 return memmove(beg + (dst_chunk << CHU 559 return memmove(beg + (dst_chunk << CHUNK_SHIFT), 584 beg + (zhdr->start_midd 560 beg + (zhdr->start_middle << CHUNK_SHIFT), 585 zhdr->middle_chunks << 561 zhdr->middle_chunks << CHUNK_SHIFT); 586 } 562 } 587 563 588 static inline bool buddy_single(struct z3fold_ << 589 { << 590 return !((zhdr->first_chunks && zhdr-> << 591 (zhdr->first_chunks && << 592 (zhdr->middle_chunks & << 593 } << 594 << 595 static struct z3fold_header *compact_single_bu << 596 { << 597 struct z3fold_pool *pool = zhdr_to_poo << 598 void *p = zhdr; << 599 unsigned long old_handle = 0; << 600 size_t sz = 0; << 601 struct z3fold_header *new_zhdr = NULL; << 602 int first_idx = __idx(zhdr, FIRST); << 603 int middle_idx = __idx(zhdr, MIDDLE); << 604 int last_idx = __idx(zhdr, LAST); << 605 unsigned short *moved_chunks = NULL; << 606 << 607 /* << 608 * No need to protect slots here -- al << 609 * the page lock is already taken << 610 */ << 611 if (zhdr->first_chunks && zhdr->slots- << 612 p += ZHDR_SIZE_ALIGNED; << 613 sz = zhdr->first_chunks << CHU << 614 old_handle = (unsigned long)&z << 615 moved_chunks = &zhdr->first_ch << 616 } else if (zhdr->middle_chunks && zhdr << 617 p += zhdr->start_middle << CHU << 618 sz = zhdr->middle_chunks << CH << 619 old_handle = (unsigned long)&z << 620 moved_chunks = &zhdr->middle_c << 621 } else if (zhdr->last_chunks && zhdr-> << 622 p += PAGE_SIZE - (zhdr->last_c << 623 sz = zhdr->last_chunks << CHUN << 624 old_handle = (unsigned long)&z << 625 moved_chunks = &zhdr->last_chu << 626 } << 627 << 628 if (sz > 0) { << 629 enum buddy new_bud = HEADLESS; << 630 short chunks = size_to_chunks( << 631 void *q; << 632 << 633 new_zhdr = __z3fold_alloc(pool << 634 if (!new_zhdr) << 635 return NULL; << 636 << 637 if (WARN_ON(new_zhdr == zhdr)) << 638 goto out_fail; << 639 << 640 new_bud = get_free_buddy(new_z << 641 q = new_zhdr; << 642 switch (new_bud) { << 643 case FIRST: << 644 new_zhdr->first_chunks << 645 q += ZHDR_SIZE_ALIGNED << 646 break; << 647 case MIDDLE: << 648 new_zhdr->middle_chunk << 649 new_zhdr->start_middle << 650 new_zhdr->firs << 651 q += new_zhdr->start_m << 652 break; << 653 case LAST: << 654 new_zhdr->last_chunks << 655 q += PAGE_SIZE - (new_ << 656 break; << 657 default: << 658 goto out_fail; << 659 } << 660 new_zhdr->foreign_handles++; << 661 memcpy(q, p, sz); << 662 write_lock(&zhdr->slots->lock) << 663 *(unsigned long *)old_handle = << 664 __idx(new_zhdr, new_bu << 665 if (new_bud == LAST) << 666 *(unsigned long *)old_ << 667 (new_z << 668 write_unlock(&zhdr->slots->loc << 669 add_to_unbuddied(pool, new_zhd << 670 z3fold_page_unlock(new_zhdr); << 671 << 672 *moved_chunks = 0; << 673 } << 674 << 675 return new_zhdr; << 676 << 677 out_fail: << 678 if (new_zhdr && !put_z3fold_locked(new << 679 add_to_unbuddied(pool, new_zhd << 680 z3fold_page_unlock(new_zhdr); << 681 } << 682 return NULL; << 683 << 684 } << 685 << 686 #define BIG_CHUNK_GAP 3 564 #define BIG_CHUNK_GAP 3 687 /* Has to be called with lock held */ 565 /* Has to be called with lock held */ 688 static int z3fold_compact_page(struct z3fold_h 566 static int z3fold_compact_page(struct z3fold_header *zhdr) 689 { 567 { 690 struct page *page = virt_to_page(zhdr) 568 struct page *page = virt_to_page(zhdr); 691 569 692 if (test_bit(MIDDLE_CHUNK_MAPPED, &pag 570 if (test_bit(MIDDLE_CHUNK_MAPPED, &page->private)) 693 return 0; /* can't move middle 571 return 0; /* can't move middle chunk, it's used */ 694 572 695 if (unlikely(PageIsolated(page))) 573 if (unlikely(PageIsolated(page))) 696 return 0; 574 return 0; 697 575 698 if (zhdr->middle_chunks == 0) 576 if (zhdr->middle_chunks == 0) 699 return 0; /* nothing to compac 577 return 0; /* nothing to compact */ 700 578 701 if (zhdr->first_chunks == 0 && zhdr->l 579 if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) { 702 /* move to the beginning */ 580 /* move to the beginning */ 703 mchunk_memmove(zhdr, ZHDR_CHUN 581 mchunk_memmove(zhdr, ZHDR_CHUNKS); 704 zhdr->first_chunks = zhdr->mid 582 zhdr->first_chunks = zhdr->middle_chunks; 705 zhdr->middle_chunks = 0; 583 zhdr->middle_chunks = 0; 706 zhdr->start_middle = 0; 584 zhdr->start_middle = 0; 707 zhdr->first_num++; 585 zhdr->first_num++; 708 return 1; 586 return 1; 709 } 587 } 710 588 711 /* 589 /* 712 * moving data is expensive, so let's 590 * moving data is expensive, so let's only do that if 713 * there's substantial gain (at least 591 * there's substantial gain (at least BIG_CHUNK_GAP chunks) 714 */ 592 */ 715 if (zhdr->first_chunks != 0 && zhdr->l 593 if (zhdr->first_chunks != 0 && zhdr->last_chunks == 0 && 716 zhdr->start_middle - (zhdr->first_ 594 zhdr->start_middle - (zhdr->first_chunks + ZHDR_CHUNKS) >= 717 BIG_CHUNK_GAP) { 595 BIG_CHUNK_GAP) { 718 mchunk_memmove(zhdr, zhdr->fir 596 mchunk_memmove(zhdr, zhdr->first_chunks + ZHDR_CHUNKS); 719 zhdr->start_middle = zhdr->fir 597 zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS; 720 return 1; 598 return 1; 721 } else if (zhdr->last_chunks != 0 && z 599 } else if (zhdr->last_chunks != 0 && zhdr->first_chunks == 0 && 722 TOTAL_CHUNKS - (zhdr->last_ 600 TOTAL_CHUNKS - (zhdr->last_chunks + zhdr->start_middle 723 + zhdr 601 + zhdr->middle_chunks) >= 724 BIG_CHUNK_GAP) { 602 BIG_CHUNK_GAP) { 725 unsigned short new_start = TOT 603 unsigned short new_start = TOTAL_CHUNKS - zhdr->last_chunks - 726 zhdr->middle_chunks; 604 zhdr->middle_chunks; 727 mchunk_memmove(zhdr, new_start 605 mchunk_memmove(zhdr, new_start); 728 zhdr->start_middle = new_start 606 zhdr->start_middle = new_start; 729 return 1; 607 return 1; 730 } 608 } 731 609 732 return 0; 610 return 0; 733 } 611 } 734 612 735 static void do_compact_page(struct z3fold_head 613 static void do_compact_page(struct z3fold_header *zhdr, bool locked) 736 { 614 { 737 struct z3fold_pool *pool = zhdr_to_poo 615 struct z3fold_pool *pool = zhdr_to_pool(zhdr); 738 struct page *page; 616 struct page *page; 739 617 740 page = virt_to_page(zhdr); 618 page = virt_to_page(zhdr); 741 if (locked) 619 if (locked) 742 WARN_ON(z3fold_page_trylock(zh 620 WARN_ON(z3fold_page_trylock(zhdr)); 743 else 621 else 744 z3fold_page_lock(zhdr); 622 z3fold_page_lock(zhdr); 745 if (WARN_ON(!test_and_clear_bit(NEEDS_ 623 if (WARN_ON(!test_and_clear_bit(NEEDS_COMPACTING, &page->private))) { 746 z3fold_page_unlock(zhdr); 624 z3fold_page_unlock(zhdr); 747 return; 625 return; 748 } 626 } 749 spin_lock(&pool->lock); 627 spin_lock(&pool->lock); 750 list_del_init(&zhdr->buddy); 628 list_del_init(&zhdr->buddy); 751 spin_unlock(&pool->lock); 629 spin_unlock(&pool->lock); 752 630 753 if (put_z3fold_locked(zhdr)) !! 631 if (kref_put(&zhdr->refcount, release_z3fold_page_locked)) { 754 return; !! 632 atomic64_dec(&pool->pages_nr); 755 << 756 if (test_bit(PAGE_STALE, &page->privat << 757 test_and_set_bit(PAGE_CLAIMED, &pa << 758 z3fold_page_unlock(zhdr); << 759 return; 633 return; 760 } 634 } 761 635 762 if (!zhdr->foreign_handles && buddy_si !! 636 if (unlikely(PageIsolated(page) || 763 zhdr->mapped_count == 0 && compact !! 637 test_bit(PAGE_CLAIMED, &page->private) || 764 if (!put_z3fold_locked(zhdr)) !! 638 test_bit(PAGE_STALE, &page->private))) { 765 clear_bit(PAGE_CLAIMED !! 639 z3fold_page_unlock(zhdr); 766 z3fold_page_unlock(zhd << 767 } << 768 return; 640 return; 769 } 641 } 770 642 771 z3fold_compact_page(zhdr); 643 z3fold_compact_page(zhdr); 772 add_to_unbuddied(pool, zhdr); 644 add_to_unbuddied(pool, zhdr); 773 clear_bit(PAGE_CLAIMED, &page->private << 774 z3fold_page_unlock(zhdr); 645 z3fold_page_unlock(zhdr); 775 } 646 } 776 647 777 static void compact_page_work(struct work_stru 648 static void compact_page_work(struct work_struct *w) 778 { 649 { 779 struct z3fold_header *zhdr = container 650 struct z3fold_header *zhdr = container_of(w, struct z3fold_header, 780 651 work); 781 652 782 do_compact_page(zhdr, false); 653 do_compact_page(zhdr, false); 783 } 654 } 784 655 785 /* returns _locked_ z3fold page header or NULL 656 /* returns _locked_ z3fold page header or NULL */ 786 static inline struct z3fold_header *__z3fold_a 657 static inline struct z3fold_header *__z3fold_alloc(struct z3fold_pool *pool, 787 658 size_t size, bool can_sleep) 788 { 659 { 789 struct z3fold_header *zhdr = NULL; 660 struct z3fold_header *zhdr = NULL; 790 struct page *page; 661 struct page *page; 791 struct list_head *unbuddied; 662 struct list_head *unbuddied; 792 int chunks = size_to_chunks(size), i; 663 int chunks = size_to_chunks(size), i; 793 664 794 lookup: 665 lookup: 795 migrate_disable(); << 796 /* First, try to find an unbuddied z3f 666 /* First, try to find an unbuddied z3fold page. */ 797 unbuddied = this_cpu_ptr(pool->unbuddi !! 667 unbuddied = get_cpu_ptr(pool->unbuddied); 798 for_each_unbuddied_list(i, chunks) { 668 for_each_unbuddied_list(i, chunks) { 799 struct list_head *l = &unbuddi 669 struct list_head *l = &unbuddied[i]; 800 670 801 zhdr = list_first_entry_or_nul 671 zhdr = list_first_entry_or_null(READ_ONCE(l), 802 struct 672 struct z3fold_header, buddy); 803 673 804 if (!zhdr) 674 if (!zhdr) 805 continue; 675 continue; 806 676 807 /* Re-check under lock. */ 677 /* Re-check under lock. */ 808 spin_lock(&pool->lock); 678 spin_lock(&pool->lock); >> 679 l = &unbuddied[i]; 809 if (unlikely(zhdr != list_firs 680 if (unlikely(zhdr != list_first_entry(READ_ONCE(l), 810 681 struct z3fold_header, buddy)) || 811 !z3fold_page_trylock(zhdr) 682 !z3fold_page_trylock(zhdr)) { 812 spin_unlock(&pool->loc 683 spin_unlock(&pool->lock); 813 zhdr = NULL; 684 zhdr = NULL; 814 migrate_enable(); !! 685 put_cpu_ptr(pool->unbuddied); 815 if (can_sleep) 686 if (can_sleep) 816 cond_resched() 687 cond_resched(); 817 goto lookup; 688 goto lookup; 818 } 689 } 819 list_del_init(&zhdr->buddy); 690 list_del_init(&zhdr->buddy); 820 zhdr->cpu = -1; 691 zhdr->cpu = -1; 821 spin_unlock(&pool->lock); 692 spin_unlock(&pool->lock); 822 693 823 page = virt_to_page(zhdr); 694 page = virt_to_page(zhdr); 824 if (test_bit(NEEDS_COMPACTING, !! 695 if (test_bit(NEEDS_COMPACTING, &page->private)) { 825 test_bit(PAGE_CLAIMED, &pa << 826 z3fold_page_unlock(zhd 696 z3fold_page_unlock(zhdr); 827 zhdr = NULL; 697 zhdr = NULL; 828 migrate_enable(); !! 698 put_cpu_ptr(pool->unbuddied); 829 if (can_sleep) 699 if (can_sleep) 830 cond_resched() 700 cond_resched(); 831 goto lookup; 701 goto lookup; 832 } 702 } 833 703 834 /* 704 /* 835 * this page could not be remo 705 * this page could not be removed from its unbuddied 836 * list while pool lock was he 706 * list while pool lock was held, and then we've taken 837 * page lock so kref_put could 707 * page lock so kref_put could not be called before 838 * we got here, so it's safe t 708 * we got here, so it's safe to just call kref_get() 839 */ 709 */ 840 kref_get(&zhdr->refcount); 710 kref_get(&zhdr->refcount); 841 break; 711 break; 842 } 712 } 843 migrate_enable(); !! 713 put_cpu_ptr(pool->unbuddied); 844 714 845 if (!zhdr) { 715 if (!zhdr) { 846 int cpu; 716 int cpu; 847 717 848 /* look for _exact_ match on o 718 /* look for _exact_ match on other cpus' lists */ 849 for_each_online_cpu(cpu) { 719 for_each_online_cpu(cpu) { 850 struct list_head *l; 720 struct list_head *l; 851 721 852 unbuddied = per_cpu_pt 722 unbuddied = per_cpu_ptr(pool->unbuddied, cpu); 853 spin_lock(&pool->lock) 723 spin_lock(&pool->lock); 854 l = &unbuddied[chunks] 724 l = &unbuddied[chunks]; 855 725 856 zhdr = list_first_entr 726 zhdr = list_first_entry_or_null(READ_ONCE(l), 857 727 struct z3fold_header, buddy); 858 728 859 if (!zhdr || !z3fold_p 729 if (!zhdr || !z3fold_page_trylock(zhdr)) { 860 spin_unlock(&p 730 spin_unlock(&pool->lock); 861 zhdr = NULL; 731 zhdr = NULL; 862 continue; 732 continue; 863 } 733 } 864 list_del_init(&zhdr->b 734 list_del_init(&zhdr->buddy); 865 zhdr->cpu = -1; 735 zhdr->cpu = -1; 866 spin_unlock(&pool->loc 736 spin_unlock(&pool->lock); 867 737 868 page = virt_to_page(zh 738 page = virt_to_page(zhdr); 869 if (test_bit(NEEDS_COM !! 739 if (test_bit(NEEDS_COMPACTING, &page->private)) { 870 test_bit(PAGE_CLAI << 871 z3fold_page_un 740 z3fold_page_unlock(zhdr); 872 zhdr = NULL; 741 zhdr = NULL; 873 if (can_sleep) 742 if (can_sleep) 874 cond_r 743 cond_resched(); 875 continue; 744 continue; 876 } 745 } 877 kref_get(&zhdr->refcou 746 kref_get(&zhdr->refcount); 878 break; 747 break; 879 } 748 } 880 } 749 } 881 750 882 if (zhdr && !zhdr->slots) { << 883 zhdr->slots = alloc_slots(pool << 884 if (!zhdr->slots) << 885 goto out_fail; << 886 } << 887 return zhdr; 751 return zhdr; 888 << 889 out_fail: << 890 if (!put_z3fold_locked(zhdr)) { << 891 add_to_unbuddied(pool, zhdr); << 892 z3fold_page_unlock(zhdr); << 893 } << 894 return NULL; << 895 } 752 } 896 753 897 /* 754 /* 898 * API Functions 755 * API Functions 899 */ 756 */ 900 757 901 /** 758 /** 902 * z3fold_create_pool() - create a new z3fold 759 * z3fold_create_pool() - create a new z3fold pool 903 * @name: pool name 760 * @name: pool name 904 * @gfp: gfp flags when allocating the 761 * @gfp: gfp flags when allocating the z3fold pool structure >> 762 * @ops: user-defined operations for the z3fold pool 905 * 763 * 906 * Return: pointer to the new z3fold pool or N 764 * Return: pointer to the new z3fold pool or NULL if the metadata allocation 907 * failed. 765 * failed. 908 */ 766 */ 909 static struct z3fold_pool *z3fold_create_pool( !! 767 static struct z3fold_pool *z3fold_create_pool(const char *name, gfp_t gfp, >> 768 const struct z3fold_ops *ops) 910 { 769 { 911 struct z3fold_pool *pool = NULL; 770 struct z3fold_pool *pool = NULL; 912 int i, cpu; 771 int i, cpu; 913 772 914 pool = kzalloc(sizeof(struct z3fold_po 773 pool = kzalloc(sizeof(struct z3fold_pool), gfp); 915 if (!pool) 774 if (!pool) 916 goto out; 775 goto out; 917 pool->c_handle = kmem_cache_create("z3 776 pool->c_handle = kmem_cache_create("z3fold_handle", 918 sizeof(struct 777 sizeof(struct z3fold_buddy_slots), 919 SLOTS_ALIGN, 0 778 SLOTS_ALIGN, 0, NULL); 920 if (!pool->c_handle) 779 if (!pool->c_handle) 921 goto out_c; 780 goto out_c; 922 spin_lock_init(&pool->lock); 781 spin_lock_init(&pool->lock); 923 spin_lock_init(&pool->stale_lock); 782 spin_lock_init(&pool->stale_lock); 924 pool->unbuddied = __alloc_percpu(sizeo !! 783 pool->unbuddied = __alloc_percpu(sizeof(struct list_head)*NCHUNKS, 2); 925 __ali << 926 if (!pool->unbuddied) 784 if (!pool->unbuddied) 927 goto out_pool; 785 goto out_pool; 928 for_each_possible_cpu(cpu) { 786 for_each_possible_cpu(cpu) { 929 struct list_head *unbuddied = 787 struct list_head *unbuddied = 930 per_cpu_ptr(po 788 per_cpu_ptr(pool->unbuddied, cpu); 931 for_each_unbuddied_list(i, 0) 789 for_each_unbuddied_list(i, 0) 932 INIT_LIST_HEAD(&unbudd 790 INIT_LIST_HEAD(&unbuddied[i]); 933 } 791 } >> 792 INIT_LIST_HEAD(&pool->lru); 934 INIT_LIST_HEAD(&pool->stale); 793 INIT_LIST_HEAD(&pool->stale); 935 atomic64_set(&pool->pages_nr, 0); 794 atomic64_set(&pool->pages_nr, 0); 936 pool->name = name; 795 pool->name = name; 937 pool->compact_wq = create_singlethread 796 pool->compact_wq = create_singlethread_workqueue(pool->name); 938 if (!pool->compact_wq) 797 if (!pool->compact_wq) 939 goto out_unbuddied; 798 goto out_unbuddied; 940 pool->release_wq = create_singlethread 799 pool->release_wq = create_singlethread_workqueue(pool->name); 941 if (!pool->release_wq) 800 if (!pool->release_wq) 942 goto out_wq; 801 goto out_wq; >> 802 if (z3fold_register_migration(pool)) >> 803 goto out_rwq; 943 INIT_WORK(&pool->work, free_pages_work 804 INIT_WORK(&pool->work, free_pages_work); >> 805 pool->ops = ops; 944 return pool; 806 return pool; 945 807 >> 808 out_rwq: >> 809 destroy_workqueue(pool->release_wq); 946 out_wq: 810 out_wq: 947 destroy_workqueue(pool->compact_wq); 811 destroy_workqueue(pool->compact_wq); 948 out_unbuddied: 812 out_unbuddied: 949 free_percpu(pool->unbuddied); 813 free_percpu(pool->unbuddied); 950 out_pool: 814 out_pool: 951 kmem_cache_destroy(pool->c_handle); 815 kmem_cache_destroy(pool->c_handle); 952 out_c: 816 out_c: 953 kfree(pool); 817 kfree(pool); 954 out: 818 out: 955 return NULL; 819 return NULL; 956 } 820 } 957 821 958 /** 822 /** 959 * z3fold_destroy_pool() - destroys an existin 823 * z3fold_destroy_pool() - destroys an existing z3fold pool 960 * @pool: the z3fold pool to be destroye 824 * @pool: the z3fold pool to be destroyed 961 * 825 * 962 * The pool should be emptied before this func 826 * The pool should be emptied before this function is called. 963 */ 827 */ 964 static void z3fold_destroy_pool(struct z3fold_ 828 static void z3fold_destroy_pool(struct z3fold_pool *pool) 965 { 829 { 966 kmem_cache_destroy(pool->c_handle); 830 kmem_cache_destroy(pool->c_handle); 967 831 968 /* 832 /* 969 * We need to destroy pool->compact_wq 833 * We need to destroy pool->compact_wq before pool->release_wq, 970 * as any pending work on pool->compac 834 * as any pending work on pool->compact_wq will call 971 * queue_work(pool->release_wq, &pool- 835 * queue_work(pool->release_wq, &pool->work). 972 * 836 * 973 * There are still outstanding pages u 837 * There are still outstanding pages until both workqueues are drained, 974 * so we cannot unregister migration u 838 * so we cannot unregister migration until then. 975 */ 839 */ 976 840 977 destroy_workqueue(pool->compact_wq); 841 destroy_workqueue(pool->compact_wq); 978 destroy_workqueue(pool->release_wq); 842 destroy_workqueue(pool->release_wq); 979 free_percpu(pool->unbuddied); !! 843 z3fold_unregister_migration(pool); 980 kfree(pool); 844 kfree(pool); 981 } 845 } 982 846 983 static const struct movable_operations z3fold_ << 984 << 985 /** 847 /** 986 * z3fold_alloc() - allocates a region of a gi 848 * z3fold_alloc() - allocates a region of a given size 987 * @pool: z3fold pool from which to allo 849 * @pool: z3fold pool from which to allocate 988 * @size: size in bytes of the desired a 850 * @size: size in bytes of the desired allocation 989 * @gfp: gfp flags used if the pool nee 851 * @gfp: gfp flags used if the pool needs to grow 990 * @handle: handle of the new allocation 852 * @handle: handle of the new allocation 991 * 853 * 992 * This function will attempt to find a free r 854 * This function will attempt to find a free region in the pool large enough to 993 * satisfy the allocation request. A search o 855 * satisfy the allocation request. A search of the unbuddied lists is 994 * performed first. If no suitable free region 856 * performed first. If no suitable free region is found, then a new page is 995 * allocated and added to the pool to satisfy 857 * allocated and added to the pool to satisfy the request. 996 * 858 * >> 859 * gfp should not set __GFP_HIGHMEM as highmem pages cannot be used >> 860 * as z3fold pool pages. >> 861 * 997 * Return: 0 if success and handle is set, oth 862 * Return: 0 if success and handle is set, otherwise -EINVAL if the size or 998 * gfp arguments are invalid or -ENOMEM if the 863 * gfp arguments are invalid or -ENOMEM if the pool was unable to allocate 999 * a new page. 864 * a new page. 1000 */ 865 */ 1001 static int z3fold_alloc(struct z3fold_pool *p 866 static int z3fold_alloc(struct z3fold_pool *pool, size_t size, gfp_t gfp, 1002 unsigned long *handle 867 unsigned long *handle) 1003 { 868 { 1004 int chunks = size_to_chunks(size); 869 int chunks = size_to_chunks(size); 1005 struct z3fold_header *zhdr = NULL; 870 struct z3fold_header *zhdr = NULL; 1006 struct page *page = NULL; 871 struct page *page = NULL; 1007 enum buddy bud; 872 enum buddy bud; 1008 bool can_sleep = gfpflags_allow_block 873 bool can_sleep = gfpflags_allow_blocking(gfp); 1009 874 1010 if (!size || (gfp & __GFP_HIGHMEM)) 875 if (!size || (gfp & __GFP_HIGHMEM)) 1011 return -EINVAL; 876 return -EINVAL; 1012 877 1013 if (size > PAGE_SIZE) 878 if (size > PAGE_SIZE) 1014 return -ENOSPC; 879 return -ENOSPC; 1015 880 1016 if (size > PAGE_SIZE - ZHDR_SIZE_ALIG 881 if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED - CHUNK_SIZE) 1017 bud = HEADLESS; 882 bud = HEADLESS; 1018 else { 883 else { 1019 retry: 884 retry: 1020 zhdr = __z3fold_alloc(pool, s 885 zhdr = __z3fold_alloc(pool, size, can_sleep); 1021 if (zhdr) { 886 if (zhdr) { 1022 bud = get_free_buddy( !! 887 if (zhdr->first_chunks == 0) { 1023 if (bud == HEADLESS) !! 888 if (zhdr->middle_chunks != 0 && 1024 if (!put_z3fo !! 889 chunks >= zhdr->start_middle) >> 890 bud = LAST; >> 891 else >> 892 bud = FIRST; >> 893 } else if (zhdr->last_chunks == 0) >> 894 bud = LAST; >> 895 else if (zhdr->middle_chunks == 0) >> 896 bud = MIDDLE; >> 897 else { >> 898 if (kref_put(&zhdr->refcount, >> 899 release_z3fold_page_locked)) >> 900 atomic64_dec(&pool->pages_nr); >> 901 else 1025 z3fol 902 z3fold_page_unlock(zhdr); 1026 pr_err("No fr 903 pr_err("No free chunks in unbuddied\n"); 1027 WARN_ON(1); 904 WARN_ON(1); 1028 goto retry; 905 goto retry; 1029 } 906 } 1030 page = virt_to_page(z 907 page = virt_to_page(zhdr); 1031 goto found; 908 goto found; 1032 } 909 } 1033 bud = FIRST; 910 bud = FIRST; 1034 } 911 } 1035 912 1036 page = alloc_page(gfp); !! 913 page = NULL; >> 914 if (can_sleep) { >> 915 spin_lock(&pool->stale_lock); >> 916 zhdr = list_first_entry_or_null(&pool->stale, >> 917 struct z3fold_header, buddy); >> 918 /* >> 919 * Before allocating a page, let's see if we can take one from >> 920 * the stale pages list. cancel_work_sync() can sleep so we >> 921 * limit this case to the contexts where we can sleep >> 922 */ >> 923 if (zhdr) { >> 924 list_del(&zhdr->buddy); >> 925 spin_unlock(&pool->stale_lock); >> 926 cancel_work_sync(&zhdr->work); >> 927 page = virt_to_page(zhdr); >> 928 } else { >> 929 spin_unlock(&pool->stale_lock); >> 930 } >> 931 } >> 932 if (!page) >> 933 page = alloc_page(gfp); >> 934 1037 if (!page) 935 if (!page) 1038 return -ENOMEM; 936 return -ENOMEM; 1039 937 1040 zhdr = init_z3fold_page(page, bud == 938 zhdr = init_z3fold_page(page, bud == HEADLESS, pool, gfp); 1041 if (!zhdr) { 939 if (!zhdr) { 1042 __free_page(page); 940 __free_page(page); 1043 return -ENOMEM; 941 return -ENOMEM; 1044 } 942 } 1045 atomic64_inc(&pool->pages_nr); 943 atomic64_inc(&pool->pages_nr); 1046 944 1047 if (bud == HEADLESS) { 945 if (bud == HEADLESS) { 1048 set_bit(PAGE_HEADLESS, &page- 946 set_bit(PAGE_HEADLESS, &page->private); 1049 goto headless; 947 goto headless; 1050 } 948 } 1051 if (can_sleep) { 949 if (can_sleep) { 1052 lock_page(page); 950 lock_page(page); 1053 __SetPageMovable(page, &z3fol !! 951 __SetPageMovable(page, pool->inode->i_mapping); 1054 unlock_page(page); 952 unlock_page(page); 1055 } else { 953 } else { 1056 WARN_ON(!trylock_page(page)); !! 954 if (trylock_page(page)) { 1057 __SetPageMovable(page, &z3fol !! 955 __SetPageMovable(page, pool->inode->i_mapping); 1058 unlock_page(page); !! 956 unlock_page(page); >> 957 } 1059 } 958 } 1060 z3fold_page_lock(zhdr); 959 z3fold_page_lock(zhdr); 1061 960 1062 found: 961 found: 1063 if (bud == FIRST) 962 if (bud == FIRST) 1064 zhdr->first_chunks = chunks; 963 zhdr->first_chunks = chunks; 1065 else if (bud == LAST) 964 else if (bud == LAST) 1066 zhdr->last_chunks = chunks; 965 zhdr->last_chunks = chunks; 1067 else { 966 else { 1068 zhdr->middle_chunks = chunks; 967 zhdr->middle_chunks = chunks; 1069 zhdr->start_middle = zhdr->fi 968 zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS; 1070 } 969 } 1071 add_to_unbuddied(pool, zhdr); 970 add_to_unbuddied(pool, zhdr); 1072 971 1073 headless: 972 headless: 1074 spin_lock(&pool->lock); 973 spin_lock(&pool->lock); >> 974 /* Add/move z3fold page to beginning of LRU */ >> 975 if (!list_empty(&page->lru)) >> 976 list_del(&page->lru); >> 977 >> 978 list_add(&page->lru, &pool->lru); >> 979 1075 *handle = encode_handle(zhdr, bud); 980 *handle = encode_handle(zhdr, bud); 1076 spin_unlock(&pool->lock); 981 spin_unlock(&pool->lock); 1077 if (bud != HEADLESS) 982 if (bud != HEADLESS) 1078 z3fold_page_unlock(zhdr); 983 z3fold_page_unlock(zhdr); 1079 984 1080 return 0; 985 return 0; 1081 } 986 } 1082 987 1083 /** 988 /** 1084 * z3fold_free() - frees the allocation assoc 989 * z3fold_free() - frees the allocation associated with the given handle 1085 * @pool: pool in which the allocation 990 * @pool: pool in which the allocation resided 1086 * @handle: handle associated with the al 991 * @handle: handle associated with the allocation returned by z3fold_alloc() 1087 * 992 * 1088 * In the case that the z3fold page in which 993 * In the case that the z3fold page in which the allocation resides is under 1089 * reclaim, as indicated by the PAGE_CLAIMED !! 994 * reclaim, as indicated by the PG_reclaim flag being set, this function 1090 * only sets the first|middle|last_chunks to !! 995 * only sets the first|last_chunks to 0. The page is actually freed 1091 * once all buddies are evicted (see z3fold_r !! 996 * once both buddies are evicted (see z3fold_reclaim_page() below). 1092 */ 997 */ 1093 static void z3fold_free(struct z3fold_pool *p 998 static void z3fold_free(struct z3fold_pool *pool, unsigned long handle) 1094 { 999 { 1095 struct z3fold_header *zhdr; 1000 struct z3fold_header *zhdr; 1096 struct page *page; 1001 struct page *page; 1097 enum buddy bud; 1002 enum buddy bud; 1098 bool page_claimed; << 1099 1003 1100 zhdr = get_z3fold_header(handle); !! 1004 zhdr = handle_to_z3fold_header(handle); 1101 page = virt_to_page(zhdr); 1005 page = virt_to_page(zhdr); 1102 page_claimed = test_and_set_bit(PAGE_ << 1103 1006 1104 if (test_bit(PAGE_HEADLESS, &page->pr 1007 if (test_bit(PAGE_HEADLESS, &page->private)) { 1105 /* if a headless page is unde 1008 /* if a headless page is under reclaim, just leave. 1106 * NB: we use test_and_set_bi 1009 * NB: we use test_and_set_bit for a reason: if the bit 1107 * has not been set before, w 1010 * has not been set before, we release this page 1108 * immediately so we don't ca 1011 * immediately so we don't care about its value any more. 1109 */ 1012 */ 1110 if (!page_claimed) { !! 1013 if (!test_and_set_bit(PAGE_CLAIMED, &page->private)) { 1111 put_z3fold_header(zhd !! 1014 spin_lock(&pool->lock); >> 1015 list_del(&page->lru); >> 1016 spin_unlock(&pool->lock); 1112 free_z3fold_page(page 1017 free_z3fold_page(page, true); 1113 atomic64_dec(&pool->p 1018 atomic64_dec(&pool->pages_nr); 1114 } 1019 } 1115 return; 1020 return; 1116 } 1021 } 1117 1022 1118 /* Non-headless case */ 1023 /* Non-headless case */ >> 1024 z3fold_page_lock(zhdr); 1119 bud = handle_to_buddy(handle); 1025 bud = handle_to_buddy(handle); 1120 1026 1121 switch (bud) { 1027 switch (bud) { 1122 case FIRST: 1028 case FIRST: 1123 zhdr->first_chunks = 0; 1029 zhdr->first_chunks = 0; 1124 break; 1030 break; 1125 case MIDDLE: 1031 case MIDDLE: 1126 zhdr->middle_chunks = 0; 1032 zhdr->middle_chunks = 0; 1127 break; 1033 break; 1128 case LAST: 1034 case LAST: 1129 zhdr->last_chunks = 0; 1035 zhdr->last_chunks = 0; 1130 break; 1036 break; 1131 default: 1037 default: 1132 pr_err("%s: unknown bud %d\n" 1038 pr_err("%s: unknown bud %d\n", __func__, bud); 1133 WARN_ON(1); 1039 WARN_ON(1); 1134 put_z3fold_header(zhdr); !! 1040 z3fold_page_unlock(zhdr); 1135 return; 1041 return; 1136 } 1042 } 1137 1043 1138 if (!page_claimed) !! 1044 free_handle(handle); 1139 free_handle(handle, zhdr); !! 1045 if (kref_put(&zhdr->refcount, release_z3fold_page_locked_list)) { 1140 if (put_z3fold_locked_list(zhdr)) !! 1046 atomic64_dec(&pool->pages_nr); 1141 return; 1047 return; 1142 if (page_claimed) { !! 1048 } 1143 /* the page has not been clai !! 1049 if (test_bit(PAGE_CLAIMED, &page->private)) { 1144 put_z3fold_header(zhdr); !! 1050 z3fold_page_unlock(zhdr); 1145 return; 1051 return; 1146 } 1052 } 1147 if (test_and_set_bit(NEEDS_COMPACTING !! 1053 if (unlikely(PageIsolated(page)) || 1148 clear_bit(PAGE_CLAIMED, &page !! 1054 test_and_set_bit(NEEDS_COMPACTING, &page->private)) { 1149 put_z3fold_header(zhdr); !! 1055 z3fold_page_unlock(zhdr); 1150 return; 1056 return; 1151 } 1057 } 1152 if (zhdr->cpu < 0 || !cpu_online(zhdr 1058 if (zhdr->cpu < 0 || !cpu_online(zhdr->cpu)) { >> 1059 spin_lock(&pool->lock); >> 1060 list_del_init(&zhdr->buddy); >> 1061 spin_unlock(&pool->lock); 1153 zhdr->cpu = -1; 1062 zhdr->cpu = -1; 1154 kref_get(&zhdr->refcount); 1063 kref_get(&zhdr->refcount); 1155 clear_bit(PAGE_CLAIMED, &page << 1156 do_compact_page(zhdr, true); 1064 do_compact_page(zhdr, true); 1157 return; 1065 return; 1158 } 1066 } 1159 kref_get(&zhdr->refcount); 1067 kref_get(&zhdr->refcount); 1160 clear_bit(PAGE_CLAIMED, &page->privat << 1161 queue_work_on(zhdr->cpu, pool->compac 1068 queue_work_on(zhdr->cpu, pool->compact_wq, &zhdr->work); 1162 put_z3fold_header(zhdr); !! 1069 z3fold_page_unlock(zhdr); >> 1070 } >> 1071 >> 1072 /** >> 1073 * z3fold_reclaim_page() - evicts allocations from a pool page and frees it >> 1074 * @pool: pool from which a page will attempt to be evicted >> 1075 * @retries: number of pages on the LRU list for which eviction will >> 1076 * be attempted before failing >> 1077 * >> 1078 * z3fold reclaim is different from normal system reclaim in that it is done >> 1079 * from the bottom, up. This is because only the bottom layer, z3fold, has >> 1080 * information on how the allocations are organized within each z3fold page. >> 1081 * This has the potential to create interesting locking situations between >> 1082 * z3fold and the user, however. >> 1083 * >> 1084 * To avoid these, this is how z3fold_reclaim_page() should be called: >> 1085 * >> 1086 * The user detects a page should be reclaimed and calls z3fold_reclaim_page(). >> 1087 * z3fold_reclaim_page() will remove a z3fold page from the pool LRU list and >> 1088 * call the user-defined eviction handler with the pool and handle as >> 1089 * arguments. >> 1090 * >> 1091 * If the handle can not be evicted, the eviction handler should return >> 1092 * non-zero. z3fold_reclaim_page() will add the z3fold page back to the >> 1093 * appropriate list and try the next z3fold page on the LRU up to >> 1094 * a user defined number of retries. >> 1095 * >> 1096 * If the handle is successfully evicted, the eviction handler should >> 1097 * return 0 _and_ should have called z3fold_free() on the handle. z3fold_free() >> 1098 * contains logic to delay freeing the page if the page is under reclaim, >> 1099 * as indicated by the setting of the PG_reclaim flag on the underlying page. >> 1100 * >> 1101 * If all buddies in the z3fold page are successfully evicted, then the >> 1102 * z3fold page can be freed. >> 1103 * >> 1104 * Returns: 0 if page is successfully freed, otherwise -EINVAL if there are >> 1105 * no pages to evict or an eviction handler is not registered, -EAGAIN if >> 1106 * the retry limit was hit. >> 1107 */ >> 1108 static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries) >> 1109 { >> 1110 int i, ret = 0; >> 1111 struct z3fold_header *zhdr = NULL; >> 1112 struct page *page = NULL; >> 1113 struct list_head *pos; >> 1114 struct z3fold_buddy_slots slots; >> 1115 unsigned long first_handle = 0, middle_handle = 0, last_handle = 0; >> 1116 >> 1117 spin_lock(&pool->lock); >> 1118 if (!pool->ops || !pool->ops->evict || retries == 0) { >> 1119 spin_unlock(&pool->lock); >> 1120 return -EINVAL; >> 1121 } >> 1122 for (i = 0; i < retries; i++) { >> 1123 if (list_empty(&pool->lru)) { >> 1124 spin_unlock(&pool->lock); >> 1125 return -EINVAL; >> 1126 } >> 1127 list_for_each_prev(pos, &pool->lru) { >> 1128 page = list_entry(pos, struct page, lru); >> 1129 >> 1130 /* this bit could have been set by free, in which case >> 1131 * we pass over to the next page in the pool. >> 1132 */ >> 1133 if (test_and_set_bit(PAGE_CLAIMED, &page->private)) { >> 1134 page = NULL; >> 1135 continue; >> 1136 } >> 1137 >> 1138 if (unlikely(PageIsolated(page))) { >> 1139 clear_bit(PAGE_CLAIMED, &page->private); >> 1140 page = NULL; >> 1141 continue; >> 1142 } >> 1143 zhdr = page_address(page); >> 1144 if (test_bit(PAGE_HEADLESS, &page->private)) >> 1145 break; >> 1146 >> 1147 if (!z3fold_page_trylock(zhdr)) { >> 1148 clear_bit(PAGE_CLAIMED, &page->private); >> 1149 zhdr = NULL; >> 1150 continue; /* can't evict at this point */ >> 1151 } >> 1152 kref_get(&zhdr->refcount); >> 1153 list_del_init(&zhdr->buddy); >> 1154 zhdr->cpu = -1; >> 1155 break; >> 1156 } >> 1157 >> 1158 if (!zhdr) >> 1159 break; >> 1160 >> 1161 list_del_init(&page->lru); >> 1162 spin_unlock(&pool->lock); >> 1163 >> 1164 if (!test_bit(PAGE_HEADLESS, &page->private)) { >> 1165 /* >> 1166 * We need encode the handles before unlocking, and >> 1167 * use our local slots structure because z3fold_free >> 1168 * can zero out zhdr->slots and we can't do much >> 1169 * about that >> 1170 */ >> 1171 first_handle = 0; >> 1172 last_handle = 0; >> 1173 middle_handle = 0; >> 1174 if (zhdr->first_chunks) >> 1175 first_handle = __encode_handle(zhdr, &slots, >> 1176 FIRST); >> 1177 if (zhdr->middle_chunks) >> 1178 middle_handle = __encode_handle(zhdr, &slots, >> 1179 MIDDLE); >> 1180 if (zhdr->last_chunks) >> 1181 last_handle = __encode_handle(zhdr, &slots, >> 1182 LAST); >> 1183 /* >> 1184 * it's safe to unlock here because we hold a >> 1185 * reference to this page >> 1186 */ >> 1187 z3fold_page_unlock(zhdr); >> 1188 } else { >> 1189 first_handle = __encode_handle(zhdr, &slots, HEADLESS); >> 1190 last_handle = middle_handle = 0; >> 1191 } >> 1192 >> 1193 /* Issue the eviction callback(s) */ >> 1194 if (middle_handle) { >> 1195 ret = pool->ops->evict(pool, middle_handle); >> 1196 if (ret) >> 1197 goto next; >> 1198 } >> 1199 if (first_handle) { >> 1200 ret = pool->ops->evict(pool, first_handle); >> 1201 if (ret) >> 1202 goto next; >> 1203 } >> 1204 if (last_handle) { >> 1205 ret = pool->ops->evict(pool, last_handle); >> 1206 if (ret) >> 1207 goto next; >> 1208 } >> 1209 next: >> 1210 if (test_bit(PAGE_HEADLESS, &page->private)) { >> 1211 if (ret == 0) { >> 1212 free_z3fold_page(page, true); >> 1213 atomic64_dec(&pool->pages_nr); >> 1214 return 0; >> 1215 } >> 1216 spin_lock(&pool->lock); >> 1217 list_add(&page->lru, &pool->lru); >> 1218 spin_unlock(&pool->lock); >> 1219 clear_bit(PAGE_CLAIMED, &page->private); >> 1220 } else { >> 1221 z3fold_page_lock(zhdr); >> 1222 if (kref_put(&zhdr->refcount, >> 1223 release_z3fold_page_locked)) { >> 1224 atomic64_dec(&pool->pages_nr); >> 1225 return 0; >> 1226 } >> 1227 /* >> 1228 * if we are here, the page is still not completely >> 1229 * free. Take the global pool lock then to be able >> 1230 * to add it back to the lru list >> 1231 */ >> 1232 spin_lock(&pool->lock); >> 1233 list_add(&page->lru, &pool->lru); >> 1234 spin_unlock(&pool->lock); >> 1235 z3fold_page_unlock(zhdr); >> 1236 clear_bit(PAGE_CLAIMED, &page->private); >> 1237 } >> 1238 >> 1239 /* We started off locked to we need to lock the pool back */ >> 1240 spin_lock(&pool->lock); >> 1241 } >> 1242 spin_unlock(&pool->lock); >> 1243 return -EAGAIN; 1163 } 1244 } 1164 1245 1165 /** 1246 /** 1166 * z3fold_map() - maps the allocation associa 1247 * z3fold_map() - maps the allocation associated with the given handle 1167 * @pool: pool in which the allocation 1248 * @pool: pool in which the allocation resides 1168 * @handle: handle associated with the al 1249 * @handle: handle associated with the allocation to be mapped 1169 * 1250 * 1170 * Extracts the buddy number from handle and 1251 * Extracts the buddy number from handle and constructs the pointer to the 1171 * correct starting chunk within the page. 1252 * correct starting chunk within the page. 1172 * 1253 * 1173 * Returns: a pointer to the mapped allocatio 1254 * Returns: a pointer to the mapped allocation 1174 */ 1255 */ 1175 static void *z3fold_map(struct z3fold_pool *p 1256 static void *z3fold_map(struct z3fold_pool *pool, unsigned long handle) 1176 { 1257 { 1177 struct z3fold_header *zhdr; 1258 struct z3fold_header *zhdr; 1178 struct page *page; 1259 struct page *page; 1179 void *addr; 1260 void *addr; 1180 enum buddy buddy; 1261 enum buddy buddy; 1181 1262 1182 zhdr = get_z3fold_header(handle); !! 1263 zhdr = handle_to_z3fold_header(handle); 1183 addr = zhdr; 1264 addr = zhdr; 1184 page = virt_to_page(zhdr); 1265 page = virt_to_page(zhdr); 1185 1266 1186 if (test_bit(PAGE_HEADLESS, &page->pr 1267 if (test_bit(PAGE_HEADLESS, &page->private)) 1187 goto out; 1268 goto out; 1188 1269 >> 1270 z3fold_page_lock(zhdr); 1189 buddy = handle_to_buddy(handle); 1271 buddy = handle_to_buddy(handle); 1190 switch (buddy) { 1272 switch (buddy) { 1191 case FIRST: 1273 case FIRST: 1192 addr += ZHDR_SIZE_ALIGNED; 1274 addr += ZHDR_SIZE_ALIGNED; 1193 break; 1275 break; 1194 case MIDDLE: 1276 case MIDDLE: 1195 addr += zhdr->start_middle << 1277 addr += zhdr->start_middle << CHUNK_SHIFT; 1196 set_bit(MIDDLE_CHUNK_MAPPED, 1278 set_bit(MIDDLE_CHUNK_MAPPED, &page->private); 1197 break; 1279 break; 1198 case LAST: 1280 case LAST: 1199 addr += PAGE_SIZE - (handle_t 1281 addr += PAGE_SIZE - (handle_to_chunks(handle) << CHUNK_SHIFT); 1200 break; 1282 break; 1201 default: 1283 default: 1202 pr_err("unknown buddy id %d\n 1284 pr_err("unknown buddy id %d\n", buddy); 1203 WARN_ON(1); 1285 WARN_ON(1); 1204 addr = NULL; 1286 addr = NULL; 1205 break; 1287 break; 1206 } 1288 } 1207 1289 1208 if (addr) 1290 if (addr) 1209 zhdr->mapped_count++; 1291 zhdr->mapped_count++; >> 1292 z3fold_page_unlock(zhdr); 1210 out: 1293 out: 1211 put_z3fold_header(zhdr); << 1212 return addr; 1294 return addr; 1213 } 1295 } 1214 1296 1215 /** 1297 /** 1216 * z3fold_unmap() - unmaps the allocation ass 1298 * z3fold_unmap() - unmaps the allocation associated with the given handle 1217 * @pool: pool in which the allocation 1299 * @pool: pool in which the allocation resides 1218 * @handle: handle associated with the al 1300 * @handle: handle associated with the allocation to be unmapped 1219 */ 1301 */ 1220 static void z3fold_unmap(struct z3fold_pool * 1302 static void z3fold_unmap(struct z3fold_pool *pool, unsigned long handle) 1221 { 1303 { 1222 struct z3fold_header *zhdr; 1304 struct z3fold_header *zhdr; 1223 struct page *page; 1305 struct page *page; 1224 enum buddy buddy; 1306 enum buddy buddy; 1225 1307 1226 zhdr = get_z3fold_header(handle); !! 1308 zhdr = handle_to_z3fold_header(handle); 1227 page = virt_to_page(zhdr); 1309 page = virt_to_page(zhdr); 1228 1310 1229 if (test_bit(PAGE_HEADLESS, &page->pr 1311 if (test_bit(PAGE_HEADLESS, &page->private)) 1230 return; 1312 return; 1231 1313 >> 1314 z3fold_page_lock(zhdr); 1232 buddy = handle_to_buddy(handle); 1315 buddy = handle_to_buddy(handle); 1233 if (buddy == MIDDLE) 1316 if (buddy == MIDDLE) 1234 clear_bit(MIDDLE_CHUNK_MAPPED 1317 clear_bit(MIDDLE_CHUNK_MAPPED, &page->private); 1235 zhdr->mapped_count--; 1318 zhdr->mapped_count--; 1236 put_z3fold_header(zhdr); !! 1319 z3fold_page_unlock(zhdr); 1237 } 1320 } 1238 1321 1239 /** 1322 /** 1240 * z3fold_get_pool_pages() - gets the z3fold !! 1323 * z3fold_get_pool_size() - gets the z3fold pool size in pages 1241 * @pool: pool whose size is being quer 1324 * @pool: pool whose size is being queried 1242 * 1325 * 1243 * Returns: size in pages of the given pool. 1326 * Returns: size in pages of the given pool. 1244 */ 1327 */ 1245 static u64 z3fold_get_pool_pages(struct z3fol !! 1328 static u64 z3fold_get_pool_size(struct z3fold_pool *pool) 1246 { 1329 { 1247 return atomic64_read(&pool->pages_nr) 1330 return atomic64_read(&pool->pages_nr); 1248 } 1331 } 1249 1332 1250 static bool z3fold_page_isolate(struct page * 1333 static bool z3fold_page_isolate(struct page *page, isolate_mode_t mode) 1251 { 1334 { 1252 struct z3fold_header *zhdr; 1335 struct z3fold_header *zhdr; 1253 struct z3fold_pool *pool; 1336 struct z3fold_pool *pool; 1254 1337 >> 1338 VM_BUG_ON_PAGE(!PageMovable(page), page); 1255 VM_BUG_ON_PAGE(PageIsolated(page), pa 1339 VM_BUG_ON_PAGE(PageIsolated(page), page); 1256 1340 1257 if (test_bit(PAGE_HEADLESS, &page->pr !! 1341 if (test_bit(PAGE_HEADLESS, &page->private) || >> 1342 test_bit(PAGE_CLAIMED, &page->private)) 1258 return false; 1343 return false; 1259 1344 1260 zhdr = page_address(page); 1345 zhdr = page_address(page); 1261 z3fold_page_lock(zhdr); 1346 z3fold_page_lock(zhdr); 1262 if (test_bit(NEEDS_COMPACTING, &page- 1347 if (test_bit(NEEDS_COMPACTING, &page->private) || 1263 test_bit(PAGE_STALE, &page->priva 1348 test_bit(PAGE_STALE, &page->private)) 1264 goto out; 1349 goto out; 1265 1350 1266 if (zhdr->mapped_count != 0 || zhdr-> << 1267 goto out; << 1268 << 1269 if (test_and_set_bit(PAGE_CLAIMED, &p << 1270 goto out; << 1271 pool = zhdr_to_pool(zhdr); 1351 pool = zhdr_to_pool(zhdr); 1272 spin_lock(&pool->lock); << 1273 if (!list_empty(&zhdr->buddy)) << 1274 list_del_init(&zhdr->buddy); << 1275 spin_unlock(&pool->lock); << 1276 << 1277 kref_get(&zhdr->refcount); << 1278 z3fold_page_unlock(zhdr); << 1279 return true; << 1280 1352 >> 1353 if (zhdr->mapped_count == 0) { >> 1354 kref_get(&zhdr->refcount); >> 1355 if (!list_empty(&zhdr->buddy)) >> 1356 list_del_init(&zhdr->buddy); >> 1357 spin_lock(&pool->lock); >> 1358 if (!list_empty(&page->lru)) >> 1359 list_del(&page->lru); >> 1360 spin_unlock(&pool->lock); >> 1361 z3fold_page_unlock(zhdr); >> 1362 return true; >> 1363 } 1281 out: 1364 out: 1282 z3fold_page_unlock(zhdr); 1365 z3fold_page_unlock(zhdr); 1283 return false; 1366 return false; 1284 } 1367 } 1285 1368 1286 static int z3fold_page_migrate(struct page *n !! 1369 static int z3fold_page_migrate(struct address_space *mapping, struct page *newpage, 1287 enum migrate_mode mode) !! 1370 struct page *page, enum migrate_mode mode) 1288 { 1371 { 1289 struct z3fold_header *zhdr, *new_zhdr 1372 struct z3fold_header *zhdr, *new_zhdr; 1290 struct z3fold_pool *pool; 1373 struct z3fold_pool *pool; >> 1374 struct address_space *new_mapping; 1291 1375 >> 1376 VM_BUG_ON_PAGE(!PageMovable(page), page); 1292 VM_BUG_ON_PAGE(!PageIsolated(page), p 1377 VM_BUG_ON_PAGE(!PageIsolated(page), page); 1293 VM_BUG_ON_PAGE(!test_bit(PAGE_CLAIMED << 1294 VM_BUG_ON_PAGE(!PageLocked(newpage), 1378 VM_BUG_ON_PAGE(!PageLocked(newpage), newpage); 1295 1379 1296 zhdr = page_address(page); 1380 zhdr = page_address(page); 1297 pool = zhdr_to_pool(zhdr); 1381 pool = zhdr_to_pool(zhdr); 1298 1382 1299 if (!z3fold_page_trylock(zhdr)) !! 1383 if (!z3fold_page_trylock(zhdr)) { 1300 return -EAGAIN; 1384 return -EAGAIN; 1301 if (zhdr->mapped_count != 0 || zhdr-> !! 1385 } 1302 clear_bit(PAGE_CLAIMED, &page !! 1386 if (zhdr->mapped_count != 0) { 1303 z3fold_page_unlock(zhdr); 1387 z3fold_page_unlock(zhdr); 1304 return -EBUSY; 1388 return -EBUSY; 1305 } 1389 } 1306 if (work_pending(&zhdr->work)) { 1390 if (work_pending(&zhdr->work)) { 1307 z3fold_page_unlock(zhdr); 1391 z3fold_page_unlock(zhdr); 1308 return -EAGAIN; 1392 return -EAGAIN; 1309 } 1393 } 1310 new_zhdr = page_address(newpage); 1394 new_zhdr = page_address(newpage); 1311 memcpy(new_zhdr, zhdr, PAGE_SIZE); 1395 memcpy(new_zhdr, zhdr, PAGE_SIZE); 1312 newpage->private = page->private; 1396 newpage->private = page->private; 1313 set_bit(PAGE_MIGRATED, &page->private !! 1397 page->private = 0; 1314 z3fold_page_unlock(zhdr); 1398 z3fold_page_unlock(zhdr); 1315 spin_lock_init(&new_zhdr->page_lock); 1399 spin_lock_init(&new_zhdr->page_lock); 1316 INIT_WORK(&new_zhdr->work, compact_pa 1400 INIT_WORK(&new_zhdr->work, compact_page_work); 1317 /* 1401 /* 1318 * z3fold_page_isolate() ensures that 1402 * z3fold_page_isolate() ensures that new_zhdr->buddy is empty, 1319 * so we only have to reinitialize it 1403 * so we only have to reinitialize it. 1320 */ 1404 */ 1321 INIT_LIST_HEAD(&new_zhdr->buddy); 1405 INIT_LIST_HEAD(&new_zhdr->buddy); >> 1406 new_mapping = page_mapping(page); 1322 __ClearPageMovable(page); 1407 __ClearPageMovable(page); >> 1408 ClearPagePrivate(page); 1323 1409 1324 get_page(newpage); 1410 get_page(newpage); 1325 z3fold_page_lock(new_zhdr); 1411 z3fold_page_lock(new_zhdr); 1326 if (new_zhdr->first_chunks) 1412 if (new_zhdr->first_chunks) 1327 encode_handle(new_zhdr, FIRST 1413 encode_handle(new_zhdr, FIRST); 1328 if (new_zhdr->last_chunks) 1414 if (new_zhdr->last_chunks) 1329 encode_handle(new_zhdr, LAST) 1415 encode_handle(new_zhdr, LAST); 1330 if (new_zhdr->middle_chunks) 1416 if (new_zhdr->middle_chunks) 1331 encode_handle(new_zhdr, MIDDL 1417 encode_handle(new_zhdr, MIDDLE); 1332 set_bit(NEEDS_COMPACTING, &newpage->p 1418 set_bit(NEEDS_COMPACTING, &newpage->private); 1333 new_zhdr->cpu = smp_processor_id(); 1419 new_zhdr->cpu = smp_processor_id(); 1334 __SetPageMovable(newpage, &z3fold_mop !! 1420 spin_lock(&pool->lock); >> 1421 list_add(&newpage->lru, &pool->lru); >> 1422 spin_unlock(&pool->lock); >> 1423 __SetPageMovable(newpage, new_mapping); 1335 z3fold_page_unlock(new_zhdr); 1424 z3fold_page_unlock(new_zhdr); 1336 1425 1337 queue_work_on(new_zhdr->cpu, pool->co 1426 queue_work_on(new_zhdr->cpu, pool->compact_wq, &new_zhdr->work); 1338 1427 1339 /* PAGE_CLAIMED and PAGE_MIGRATED are !! 1428 page_mapcount_reset(page); 1340 page->private = 0; << 1341 put_page(page); 1429 put_page(page); 1342 return 0; 1430 return 0; 1343 } 1431 } 1344 1432 1345 static void z3fold_page_putback(struct page * 1433 static void z3fold_page_putback(struct page *page) 1346 { 1434 { 1347 struct z3fold_header *zhdr; 1435 struct z3fold_header *zhdr; 1348 struct z3fold_pool *pool; 1436 struct z3fold_pool *pool; 1349 1437 1350 zhdr = page_address(page); 1438 zhdr = page_address(page); 1351 pool = zhdr_to_pool(zhdr); 1439 pool = zhdr_to_pool(zhdr); 1352 1440 1353 z3fold_page_lock(zhdr); 1441 z3fold_page_lock(zhdr); 1354 if (!list_empty(&zhdr->buddy)) 1442 if (!list_empty(&zhdr->buddy)) 1355 list_del_init(&zhdr->buddy); 1443 list_del_init(&zhdr->buddy); 1356 INIT_LIST_HEAD(&page->lru); 1444 INIT_LIST_HEAD(&page->lru); 1357 if (put_z3fold_locked(zhdr)) !! 1445 if (kref_put(&zhdr->refcount, release_z3fold_page_locked)) { >> 1446 atomic64_dec(&pool->pages_nr); 1358 return; 1447 return; 1359 if (list_empty(&zhdr->buddy)) !! 1448 } 1360 add_to_unbuddied(pool, zhdr); !! 1449 spin_lock(&pool->lock); 1361 clear_bit(PAGE_CLAIMED, &page->privat !! 1450 list_add(&page->lru, &pool->lru); >> 1451 spin_unlock(&pool->lock); 1362 z3fold_page_unlock(zhdr); 1452 z3fold_page_unlock(zhdr); 1363 } 1453 } 1364 1454 1365 static const struct movable_operations z3fold !! 1455 static const struct address_space_operations z3fold_aops = { 1366 .isolate_page = z3fold_page_isolate, 1456 .isolate_page = z3fold_page_isolate, 1367 .migrate_page = z3fold_page_migrate, !! 1457 .migratepage = z3fold_page_migrate, 1368 .putback_page = z3fold_page_putback, 1458 .putback_page = z3fold_page_putback, 1369 }; 1459 }; 1370 1460 1371 /***************** 1461 /***************** 1372 * zpool 1462 * zpool 1373 ****************/ 1463 ****************/ 1374 1464 1375 static void *z3fold_zpool_create(const char * !! 1465 static int z3fold_zpool_evict(struct z3fold_pool *pool, unsigned long handle) 1376 { 1466 { 1377 return z3fold_create_pool(name, gfp); !! 1467 if (pool->zpool && pool->zpool_ops && pool->zpool_ops->evict) >> 1468 return pool->zpool_ops->evict(pool->zpool, handle); >> 1469 else >> 1470 return -ENOENT; >> 1471 } >> 1472 >> 1473 static const struct z3fold_ops z3fold_zpool_ops = { >> 1474 .evict = z3fold_zpool_evict >> 1475 }; >> 1476 >> 1477 static void *z3fold_zpool_create(const char *name, gfp_t gfp, >> 1478 const struct zpool_ops *zpool_ops, >> 1479 struct zpool *zpool) >> 1480 { >> 1481 struct z3fold_pool *pool; >> 1482 >> 1483 pool = z3fold_create_pool(name, gfp, >> 1484 zpool_ops ? &z3fold_zpool_ops : NULL); >> 1485 if (pool) { >> 1486 pool->zpool = zpool; >> 1487 pool->zpool_ops = zpool_ops; >> 1488 } >> 1489 return pool; 1378 } 1490 } 1379 1491 1380 static void z3fold_zpool_destroy(void *pool) 1492 static void z3fold_zpool_destroy(void *pool) 1381 { 1493 { 1382 z3fold_destroy_pool(pool); 1494 z3fold_destroy_pool(pool); 1383 } 1495 } 1384 1496 1385 static int z3fold_zpool_malloc(void *pool, si 1497 static int z3fold_zpool_malloc(void *pool, size_t size, gfp_t gfp, 1386 unsigned long *handle 1498 unsigned long *handle) 1387 { 1499 { 1388 return z3fold_alloc(pool, size, gfp, 1500 return z3fold_alloc(pool, size, gfp, handle); 1389 } 1501 } 1390 static void z3fold_zpool_free(void *pool, uns 1502 static void z3fold_zpool_free(void *pool, unsigned long handle) 1391 { 1503 { 1392 z3fold_free(pool, handle); 1504 z3fold_free(pool, handle); 1393 } 1505 } 1394 1506 >> 1507 static int z3fold_zpool_shrink(void *pool, unsigned int pages, >> 1508 unsigned int *reclaimed) >> 1509 { >> 1510 unsigned int total = 0; >> 1511 int ret = -EINVAL; >> 1512 >> 1513 while (total < pages) { >> 1514 ret = z3fold_reclaim_page(pool, 8); >> 1515 if (ret < 0) >> 1516 break; >> 1517 total++; >> 1518 } >> 1519 >> 1520 if (reclaimed) >> 1521 *reclaimed = total; >> 1522 >> 1523 return ret; >> 1524 } >> 1525 1395 static void *z3fold_zpool_map(void *pool, uns 1526 static void *z3fold_zpool_map(void *pool, unsigned long handle, 1396 enum zpool_mapmode mm 1527 enum zpool_mapmode mm) 1397 { 1528 { 1398 return z3fold_map(pool, handle); 1529 return z3fold_map(pool, handle); 1399 } 1530 } 1400 static void z3fold_zpool_unmap(void *pool, un 1531 static void z3fold_zpool_unmap(void *pool, unsigned long handle) 1401 { 1532 { 1402 z3fold_unmap(pool, handle); 1533 z3fold_unmap(pool, handle); 1403 } 1534 } 1404 1535 1405 static u64 z3fold_zpool_total_pages(void *poo !! 1536 static u64 z3fold_zpool_total_size(void *pool) 1406 { 1537 { 1407 return z3fold_get_pool_pages(pool); !! 1538 return z3fold_get_pool_size(pool) * PAGE_SIZE; 1408 } 1539 } 1409 1540 1410 static struct zpool_driver z3fold_zpool_drive 1541 static struct zpool_driver z3fold_zpool_driver = { 1411 .type = "z3fold", 1542 .type = "z3fold", 1412 .sleep_mapped = true, << 1413 .owner = THIS_MODULE, 1543 .owner = THIS_MODULE, 1414 .create = z3fold_zpool_create, 1544 .create = z3fold_zpool_create, 1415 .destroy = z3fold_zpool_destroy, 1545 .destroy = z3fold_zpool_destroy, 1416 .malloc = z3fold_zpool_malloc, 1546 .malloc = z3fold_zpool_malloc, 1417 .free = z3fold_zpool_free, 1547 .free = z3fold_zpool_free, >> 1548 .shrink = z3fold_zpool_shrink, 1418 .map = z3fold_zpool_map, 1549 .map = z3fold_zpool_map, 1419 .unmap = z3fold_zpool_unmap, 1550 .unmap = z3fold_zpool_unmap, 1420 .total_pages = z3fold_zpool_total_pa !! 1551 .total_size = z3fold_zpool_total_size, 1421 }; 1552 }; 1422 1553 1423 MODULE_ALIAS("zpool-z3fold"); 1554 MODULE_ALIAS("zpool-z3fold"); 1424 1555 1425 static int __init init_z3fold(void) 1556 static int __init init_z3fold(void) 1426 { 1557 { 1427 /* !! 1558 int ret; 1428 * Make sure the z3fold header is not !! 1559 1429 * there has remaining spaces for its !! 1560 /* Make sure the z3fold header is not larger than the page size */ 1430 */ !! 1561 BUILD_BUG_ON(ZHDR_SIZE_ALIGNED > PAGE_SIZE); 1431 BUILD_BUG_ON(ZHDR_SIZE_ALIGNED > PAGE !! 1562 ret = z3fold_mount(); >> 1563 if (ret) >> 1564 return ret; >> 1565 1432 zpool_register_driver(&z3fold_zpool_d 1566 zpool_register_driver(&z3fold_zpool_driver); 1433 1567 1434 return 0; 1568 return 0; 1435 } 1569 } 1436 1570 1437 static void __exit exit_z3fold(void) 1571 static void __exit exit_z3fold(void) 1438 { 1572 { >> 1573 z3fold_unmount(); 1439 zpool_unregister_driver(&z3fold_zpool 1574 zpool_unregister_driver(&z3fold_zpool_driver); 1440 } 1575 } 1441 1576 1442 module_init(init_z3fold); 1577 module_init(init_z3fold); 1443 module_exit(exit_z3fold); 1578 module_exit(exit_z3fold); 1444 1579 1445 MODULE_LICENSE("GPL"); 1580 MODULE_LICENSE("GPL"); 1446 MODULE_AUTHOR("Vitaly Wool <vitalywool@gmail. 1581 MODULE_AUTHOR("Vitaly Wool <vitalywool@gmail.com>"); 1447 MODULE_DESCRIPTION("3-Fold Allocator for Comp 1582 MODULE_DESCRIPTION("3-Fold Allocator for Compressed Pages"); 1448 1583
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.