[RFC v2 32/43] shmem: preserve shmem files a chunk at a time

Anthony Yznaga anthony.yznaga at oracle.com
Tue Mar 30 22:36:07 BST 2021


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 at oracle.com>
---
 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




More information about the kexec mailing list