erofs: try to leave (de)compressed_pages on stack if possible
For the most cases, small pclusters can be decompressed with page arrays on stack. Try to leave both (de)compressed_pages on stack if possible as before. Acked-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20220715154203.48093-14-hsiangkao@linux.alibaba.com
This commit is contained in:
parent
4f05687fd7
commit
fe3e5914e6
1 changed files with 21 additions and 13 deletions
|
@ -858,6 +858,7 @@ struct z_erofs_decompress_backend {
|
||||||
struct page **compressed_pages;
|
struct page **compressed_pages;
|
||||||
|
|
||||||
struct page **pagepool;
|
struct page **pagepool;
|
||||||
|
unsigned int onstack_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int z_erofs_parse_out_bvecs(struct z_erofs_decompress_backend *be)
|
static int z_erofs_parse_out_bvecs(struct z_erofs_decompress_backend *be)
|
||||||
|
@ -904,14 +905,9 @@ static int z_erofs_parse_in_bvecs(struct z_erofs_decompress_backend *be,
|
||||||
{
|
{
|
||||||
struct z_erofs_pcluster *pcl = be->pcl;
|
struct z_erofs_pcluster *pcl = be->pcl;
|
||||||
unsigned int pclusterpages = z_erofs_pclusterpages(pcl);
|
unsigned int pclusterpages = z_erofs_pclusterpages(pcl);
|
||||||
struct page **compressed_pages;
|
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
|
|
||||||
/* XXX: will have a better approach in the following commits */
|
|
||||||
compressed_pages = kmalloc_array(pclusterpages, sizeof(struct page *),
|
|
||||||
GFP_KERNEL | __GFP_NOFAIL);
|
|
||||||
*overlapped = false;
|
*overlapped = false;
|
||||||
|
|
||||||
for (i = 0; i < pclusterpages; ++i) {
|
for (i = 0; i < pclusterpages; ++i) {
|
||||||
struct z_erofs_bvec *bvec = &pcl->compressed_bvecs[i];
|
struct z_erofs_bvec *bvec = &pcl->compressed_bvecs[i];
|
||||||
struct page *page = bvec->page;
|
struct page *page = bvec->page;
|
||||||
|
@ -922,7 +918,7 @@ static int z_erofs_parse_in_bvecs(struct z_erofs_decompress_backend *be,
|
||||||
DBG_BUGON(1);
|
DBG_BUGON(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
compressed_pages[i] = page;
|
be->compressed_pages[i] = page;
|
||||||
|
|
||||||
if (z_erofs_is_inline_pcluster(pcl)) {
|
if (z_erofs_is_inline_pcluster(pcl)) {
|
||||||
if (!PageUptodate(page))
|
if (!PageUptodate(page))
|
||||||
|
@ -953,11 +949,8 @@ static int z_erofs_parse_in_bvecs(struct z_erofs_decompress_backend *be,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err)
|
||||||
kfree(compressed_pages);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
be->compressed_pages = compressed_pages;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -976,15 +969,28 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,
|
||||||
mutex_lock(&pcl->lock);
|
mutex_lock(&pcl->lock);
|
||||||
nr_pages = pcl->nr_pages;
|
nr_pages = pcl->nr_pages;
|
||||||
|
|
||||||
|
/* allocate (de)compressed page arrays if cannot be kept on stack */
|
||||||
|
be->decompressed_pages = NULL;
|
||||||
|
be->compressed_pages = NULL;
|
||||||
|
be->onstack_used = 0;
|
||||||
if (nr_pages <= Z_EROFS_ONSTACK_PAGES) {
|
if (nr_pages <= Z_EROFS_ONSTACK_PAGES) {
|
||||||
be->decompressed_pages = be->onstack_pages;
|
be->decompressed_pages = be->onstack_pages;
|
||||||
|
be->onstack_used = nr_pages;
|
||||||
memset(be->decompressed_pages, 0,
|
memset(be->decompressed_pages, 0,
|
||||||
sizeof(struct page *) * nr_pages);
|
sizeof(struct page *) * nr_pages);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (pclusterpages + be->onstack_used <= Z_EROFS_ONSTACK_PAGES)
|
||||||
|
be->compressed_pages = be->onstack_pages + be->onstack_used;
|
||||||
|
|
||||||
|
if (!be->decompressed_pages)
|
||||||
be->decompressed_pages =
|
be->decompressed_pages =
|
||||||
kvcalloc(nr_pages, sizeof(struct page *),
|
kvcalloc(nr_pages, sizeof(struct page *),
|
||||||
GFP_KERNEL | __GFP_NOFAIL);
|
GFP_KERNEL | __GFP_NOFAIL);
|
||||||
}
|
if (!be->compressed_pages)
|
||||||
|
be->compressed_pages =
|
||||||
|
kvcalloc(pclusterpages, sizeof(struct page *),
|
||||||
|
GFP_KERNEL | __GFP_NOFAIL);
|
||||||
|
|
||||||
err2 = z_erofs_parse_out_bvecs(be);
|
err2 = z_erofs_parse_out_bvecs(be);
|
||||||
if (err2)
|
if (err2)
|
||||||
|
@ -1041,7 +1047,9 @@ out:
|
||||||
WRITE_ONCE(pcl->compressed_bvecs[i].page, NULL);
|
WRITE_ONCE(pcl->compressed_bvecs[i].page, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kfree(be->compressed_pages);
|
if (be->compressed_pages < be->onstack_pages ||
|
||||||
|
be->compressed_pages >= be->onstack_pages + Z_EROFS_ONSTACK_PAGES)
|
||||||
|
kvfree(be->compressed_pages);
|
||||||
|
|
||||||
for (i = 0; i < nr_pages; ++i) {
|
for (i = 0; i < nr_pages; ++i) {
|
||||||
page = be->decompressed_pages[i];
|
page = be->decompressed_pages[i];
|
||||||
|
|
Loading…
Add table
Reference in a new issue