[RFC v2 32/43] shmem: preserve shmem files a chunk at a time
From: Anthony Yznaga
Date: Tue Mar 30 2021 - 17:29:01 EST
To prepare for multithreading the work to preserve a shmem file,
divide the work into subranges of the total index range of the file.
The chunk size is a rather arbitrary 256k indices.
Signed-off-by: Anthony Yznaga <anthony.yznaga@xxxxxxxxxx>
---
mm/shmem_pkram.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/mm/shmem_pkram.c b/mm/shmem_pkram.c
index 8682b0c002c0..e52722b3a709 100644
--- a/mm/shmem_pkram.c
+++ b/mm/shmem_pkram.c
@@ -74,16 +74,14 @@ static int save_page(struct page *page, struct pkram_access *pa)
return err;
}
-static int save_file_content(struct pkram_stream *ps, struct address_space *mapping)
+static int save_file_content_range(struct pkram_access *pa,
+ struct address_space *mapping,
+ unsigned long start, unsigned long end)
{
- PKRAM_ACCESS(pa, ps, pages);
struct pagevec pvec;
- unsigned long start, end;
int err = 0;
int i;
- start = 0;
- end = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE);
pagevec_init(&pvec);
for ( ; ; ) {
pvec.nr = find_get_pages_range(mapping, &start, end,
@@ -95,7 +93,7 @@ static int save_file_content(struct pkram_stream *ps, struct address_space *mapp
lock_page(page);
BUG_ON(page->mapping != mapping);
- err = save_page(page, &pa);
+ err = save_page(page, pa);
if (PageCompound(page)) {
start = page->index + compound_nr(page);
i += compound_nr(page);
@@ -113,10 +111,62 @@ static int save_file_content(struct pkram_stream *ps, struct address_space *mapp
cond_resched();
}
- pkram_finish_access(&pa, err == 0);
return err;
}
+struct shmem_pkram_arg {
+ struct pkram_stream *ps;
+ struct address_space *mapping;
+ struct mm_struct *mm;
+ atomic64_t next;
+};
+
+unsigned long shmem_pkram_max_index_range = 512 * 512;
+
+static int get_save_range(unsigned long max, atomic64_t *next, unsigned long *start, unsigned long *end)
+{
+ unsigned long index;
+
+ index = atomic64_fetch_add(shmem_pkram_max_index_range, next);
+ if (index >= max)
+ return -ENODATA;
+
+ *start = index;
+ *end = index + shmem_pkram_max_index_range - 1;
+
+ return 0;
+}
+
+static int do_save_file_content(struct pkram_stream *ps,
+ struct address_space *mapping,
+ atomic64_t *next)
+{
+ PKRAM_ACCESS(pa, ps, pages);
+ unsigned long start, end, max;
+ int ret;
+
+ max = DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE);
+
+ do {
+ ret = get_save_range(max, next, &start, &end);
+ if (!ret)
+ ret = save_file_content_range(&pa, mapping, start, end);
+ } while (!ret);
+
+ if (ret == -ENODATA)
+ ret = 0;
+
+ pkram_finish_access(&pa, ret == 0);
+ return ret;
+}
+
+static int save_file_content(struct pkram_stream *ps, struct address_space *mapping)
+{
+ struct shmem_pkram_arg arg = { ps, mapping, NULL, ATOMIC64_INIT(0) };
+
+ return do_save_file_content(arg.ps, arg.mapping, &arg.next);
+}
+
static int save_file(struct dentry *dentry, struct pkram_stream *ps)
{
PKRAM_ACCESS(pa_bytes, ps, bytes);
--
1.8.3.1