[RHEL7,COMMIT] mm/filemap: add pfcache support to filemap_map_pages

Submitted by Konstantin Khorenko on Feb. 27, 2020, 4:07 p.m.

Details

Message ID 202002271607.01RG7YcX026066@finist-ce7.sw.ru
State New
Series "Series without cover letter"
Headers show

Commit Message

Konstantin Khorenko Feb. 27, 2020, 4:07 p.m.
The commit is pushed to "branch-rh7-3.10.0-1062.12.1.vz7.131.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1062.12.1.vz7.131.4
------>
commit ca93980eca446b3ef001746da00f6914981ce3fe
Author: Andrey Ryabinin <aryabinin@virtuozzo.com>
Date:   Thu Feb 27 19:07:34 2020 +0300

    mm/filemap: add pfcache support to filemap_map_pages
    
    Make filemap_map_pages to map pages from pfcache if that's available.
    
    https://jira.sw.ru/browse/PSBM-101300
    Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 mm/filemap.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/mm/filemap.c b/mm/filemap.c
index bbddfeb2675d6..af1618bf97a68 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2409,11 +2409,11 @@  int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 }
 EXPORT_SYMBOL(filemap_fault);
 
-void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
+static void __filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf,
+				struct file *file)
 {
 	struct radix_tree_iter iter;
 	void **slot;
-	struct file *file = vma->vm_file;
 	struct address_space *mapping = file->f_mapping;
 	loff_t size;
 	struct page *page;
@@ -2421,7 +2421,6 @@  void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
 	unsigned long addr;
 	pte_t *pte;
 
-	rcu_read_lock();
 	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, vmf->pgoff) {
 		if (iter.index > vmf->max_pgoff)
 			break;
@@ -2477,7 +2476,25 @@  void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
 		if (iter.index == vmf->max_pgoff)
 			break;
 	}
+}
+
+void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct file *file = vma->vm_file;
+	struct file *peer_file;
+
+	rcu_read_lock();
+	__filemap_map_pages(vma, vmf, file);
+
+	peer_file = rcu_dereference(file->f_mapping->i_peer_file);
+	if (peer_file && atomic_long_inc_not_zero(&peer_file->f_count))
+		__filemap_map_pages(vma, vmf, peer_file);
+	else
+		peer_file = NULL;
 	rcu_read_unlock();
+
+	if (peer_file)
+		fput(peer_file);
 }
 EXPORT_SYMBOL(filemap_map_pages);