152488734SGao Xiang // SPDX-License-Identifier: GPL-2.0-only 252488734SGao Xiang /* 352488734SGao Xiang * Copyright (C) Gao Xiang <xiang@kernel.org> 452488734SGao Xiang * 552488734SGao Xiang * For low-latency decompression algorithms (e.g. lz4), reserve consecutive 652488734SGao Xiang * per-CPU virtual memory (in pages) in advance to store such inplace I/O 752488734SGao Xiang * data if inplace decompression is failed (due to unmet inplace margin for 852488734SGao Xiang * example). 952488734SGao Xiang */ 1052488734SGao Xiang #include "internal.h" 1152488734SGao Xiang 1252488734SGao Xiang struct erofs_pcpubuf { 1352488734SGao Xiang raw_spinlock_t lock; 1452488734SGao Xiang void *ptr; 1552488734SGao Xiang struct page **pages; 1652488734SGao Xiang unsigned int nrpages; 1752488734SGao Xiang }; 1852488734SGao Xiang 1952488734SGao Xiang static DEFINE_PER_CPU(struct erofs_pcpubuf, erofs_pcb); 2052488734SGao Xiang 2152488734SGao Xiang void *erofs_get_pcpubuf(unsigned int requiredpages) 2252488734SGao Xiang __acquires(pcb->lock) 2352488734SGao Xiang { 2452488734SGao Xiang struct erofs_pcpubuf *pcb = &get_cpu_var(erofs_pcb); 2552488734SGao Xiang 2652488734SGao Xiang raw_spin_lock(&pcb->lock); 2752488734SGao Xiang /* check if the per-CPU buffer is too small */ 2852488734SGao Xiang if (requiredpages > pcb->nrpages) { 2952488734SGao Xiang raw_spin_unlock(&pcb->lock); 3052488734SGao Xiang put_cpu_var(erofs_pcb); 3152488734SGao Xiang /* (for sparse checker) pretend pcb->lock is still taken */ 3252488734SGao Xiang __acquire(pcb->lock); 3352488734SGao Xiang return NULL; 3452488734SGao Xiang } 3552488734SGao Xiang return pcb->ptr; 3652488734SGao Xiang } 3752488734SGao Xiang 3852488734SGao Xiang void erofs_put_pcpubuf(void *ptr) __releases(pcb->lock) 3952488734SGao Xiang { 4052488734SGao Xiang struct erofs_pcpubuf *pcb = &per_cpu(erofs_pcb, smp_processor_id()); 4152488734SGao Xiang 4252488734SGao Xiang DBG_BUGON(pcb->ptr != ptr); 4352488734SGao Xiang raw_spin_unlock(&pcb->lock); 4452488734SGao Xiang put_cpu_var(erofs_pcb); 4552488734SGao Xiang } 4652488734SGao Xiang 4752488734SGao Xiang /* the next step: support per-CPU page buffers hotplug */ 4852488734SGao Xiang int erofs_pcpubuf_growsize(unsigned int nrpages) 4952488734SGao Xiang { 5052488734SGao Xiang static DEFINE_MUTEX(pcb_resize_mutex); 5152488734SGao Xiang static unsigned int pcb_nrpages; 52*eaa9172aSGao Xiang struct page *pagepool = NULL; 5352488734SGao Xiang int delta, cpu, ret, i; 5452488734SGao Xiang 5552488734SGao Xiang mutex_lock(&pcb_resize_mutex); 5652488734SGao Xiang delta = nrpages - pcb_nrpages; 5752488734SGao Xiang ret = 0; 5852488734SGao Xiang /* avoid shrinking pcpubuf, since no idea how many fses rely on */ 5952488734SGao Xiang if (delta <= 0) 6052488734SGao Xiang goto out; 6152488734SGao Xiang 6252488734SGao Xiang for_each_possible_cpu(cpu) { 6352488734SGao Xiang struct erofs_pcpubuf *pcb = &per_cpu(erofs_pcb, cpu); 6452488734SGao Xiang struct page **pages, **oldpages; 6552488734SGao Xiang void *ptr, *old_ptr; 6652488734SGao Xiang 6752488734SGao Xiang pages = kmalloc_array(nrpages, sizeof(*pages), GFP_KERNEL); 6852488734SGao Xiang if (!pages) { 6952488734SGao Xiang ret = -ENOMEM; 7052488734SGao Xiang break; 7152488734SGao Xiang } 7252488734SGao Xiang 7352488734SGao Xiang for (i = 0; i < nrpages; ++i) { 7452488734SGao Xiang pages[i] = erofs_allocpage(&pagepool, GFP_KERNEL); 7552488734SGao Xiang if (!pages[i]) { 7652488734SGao Xiang ret = -ENOMEM; 7752488734SGao Xiang oldpages = pages; 7852488734SGao Xiang goto free_pagearray; 7952488734SGao Xiang } 8052488734SGao Xiang } 8152488734SGao Xiang ptr = vmap(pages, nrpages, VM_MAP, PAGE_KERNEL); 8252488734SGao Xiang if (!ptr) { 8352488734SGao Xiang ret = -ENOMEM; 8452488734SGao Xiang oldpages = pages; 8552488734SGao Xiang goto free_pagearray; 8652488734SGao Xiang } 8752488734SGao Xiang raw_spin_lock(&pcb->lock); 8852488734SGao Xiang old_ptr = pcb->ptr; 8952488734SGao Xiang pcb->ptr = ptr; 9052488734SGao Xiang oldpages = pcb->pages; 9152488734SGao Xiang pcb->pages = pages; 9252488734SGao Xiang i = pcb->nrpages; 9352488734SGao Xiang pcb->nrpages = nrpages; 9452488734SGao Xiang raw_spin_unlock(&pcb->lock); 9552488734SGao Xiang 9652488734SGao Xiang if (!oldpages) { 9752488734SGao Xiang DBG_BUGON(old_ptr); 9852488734SGao Xiang continue; 9952488734SGao Xiang } 10052488734SGao Xiang 10152488734SGao Xiang if (old_ptr) 10252488734SGao Xiang vunmap(old_ptr); 10352488734SGao Xiang free_pagearray: 10452488734SGao Xiang while (i) 105*eaa9172aSGao Xiang erofs_pagepool_add(&pagepool, oldpages[--i]); 10652488734SGao Xiang kfree(oldpages); 10752488734SGao Xiang if (ret) 10852488734SGao Xiang break; 10952488734SGao Xiang } 11052488734SGao Xiang pcb_nrpages = nrpages; 111*eaa9172aSGao Xiang erofs_release_pages(&pagepool); 11252488734SGao Xiang out: 11352488734SGao Xiang mutex_unlock(&pcb_resize_mutex); 11452488734SGao Xiang return ret; 11552488734SGao Xiang } 11652488734SGao Xiang 11752488734SGao Xiang void erofs_pcpubuf_init(void) 11852488734SGao Xiang { 11952488734SGao Xiang int cpu; 12052488734SGao Xiang 12152488734SGao Xiang for_each_possible_cpu(cpu) { 12252488734SGao Xiang struct erofs_pcpubuf *pcb = &per_cpu(erofs_pcb, cpu); 12352488734SGao Xiang 12452488734SGao Xiang raw_spin_lock_init(&pcb->lock); 12552488734SGao Xiang } 12652488734SGao Xiang } 12752488734SGao Xiang 12852488734SGao Xiang void erofs_pcpubuf_exit(void) 12952488734SGao Xiang { 13052488734SGao Xiang int cpu, i; 13152488734SGao Xiang 13252488734SGao Xiang for_each_possible_cpu(cpu) { 13352488734SGao Xiang struct erofs_pcpubuf *pcb = &per_cpu(erofs_pcb, cpu); 13452488734SGao Xiang 13552488734SGao Xiang if (pcb->ptr) { 13652488734SGao Xiang vunmap(pcb->ptr); 13752488734SGao Xiang pcb->ptr = NULL; 13852488734SGao Xiang } 13952488734SGao Xiang if (!pcb->pages) 14052488734SGao Xiang continue; 14152488734SGao Xiang 14252488734SGao Xiang for (i = 0; i < pcb->nrpages; ++i) 14352488734SGao Xiang if (pcb->pages[i]) 14452488734SGao Xiang put_page(pcb->pages[i]); 14552488734SGao Xiang kfree(pcb->pages); 14652488734SGao Xiang pcb->pages = NULL; 14752488734SGao Xiang } 14852488734SGao Xiang } 149