All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: willy@infradead.org
Cc: dhowells@redhat.com, linux-fsdevel@vger.kernel.org,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 4/6] mm: Pass readahead_control into page_cache_{sync,async}_readahead() [ver #2]
Date: Wed, 02 Sep 2020 16:44:45 +0100	[thread overview]
Message-ID: <159906148519.663183.14012026331551396649.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <159906145700.663183.3678164182141075453.stgit@warthog.procyon.org.uk>

Pass struct readahead_control into the page_cache_{sync,async}_readahead()
functions in preparation for making do_sync_mmap_readahead() pass down an
RAC struct.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/btrfs/free-space-cache.c |    4 +++-
 fs/btrfs/ioctl.c            |    9 ++++++---
 fs/btrfs/relocation.c       |   10 ++++++----
 fs/btrfs/send.c             |   16 ++++++++++------
 fs/ext4/dir.c               |   11 ++++++-----
 fs/f2fs/dir.c               |    8 ++++++--
 include/linux/pagemap.h     |    7 +++----
 mm/filemap.c                |   26 ++++++++++++++------------
 mm/khugepaged.c             |    4 ++--
 mm/readahead.c              |   34 +++++++++++++---------------------
 10 files changed, 69 insertions(+), 60 deletions(-)

diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index dc82fd0c80cb..c64af32453b6 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -288,6 +288,8 @@ static void readahead_cache(struct inode *inode)
 	struct file_ra_state *ra;
 	unsigned long last_index;
 
+	DEFINE_READAHEAD(rac, NULL, inode->i_mapping, 0);
+
 	ra = kzalloc(sizeof(*ra), GFP_NOFS);
 	if (!ra)
 		return;
@@ -295,7 +297,7 @@ static void readahead_cache(struct inode *inode)
 	file_ra_state_init(ra, inode->i_mapping);
 	last_index = (i_size_read(inode) - 1) >> PAGE_SHIFT;
 
-	page_cache_sync_readahead(inode->i_mapping, ra, NULL, 0, last_index);
+	page_cache_sync_readahead(&rac, ra, last_index);
 
 	kfree(ra);
 }
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index bd3511c5ca81..9f9321f20615 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1428,6 +1428,8 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 	struct page **pages = NULL;
 	bool do_compress = range->flags & BTRFS_DEFRAG_RANGE_COMPRESS;
 
+	DEFINE_READAHEAD(rac, file, inode->i_mapping, 0);
+
 	if (isize == 0)
 		return 0;
 
@@ -1534,9 +1536,10 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
 
 		if (i + cluster > ra_index) {
 			ra_index = max(i, ra_index);
-			if (ra)
-				page_cache_sync_readahead(inode->i_mapping, ra,
-						file, ra_index, cluster);
+			if (ra) {
+				rac._index = ra_index;
+				page_cache_sync_readahead(&rac, ra, cluster);
+			}
 			ra_index += cluster;
 		}
 
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 4ba1ab9cc76d..3d21aeaaa762 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2684,6 +2684,8 @@ static int relocate_file_extent_cluster(struct inode *inode,
 	int nr = 0;
 	int ret = 0;
 
+	DEFINE_READAHEAD(rac, NULL, inode->i_mapping, 0);
+
 	if (!cluster->nr)
 		return 0;
 
@@ -2712,8 +2714,8 @@ static int relocate_file_extent_cluster(struct inode *inode,
 
 		page = find_lock_page(inode->i_mapping, index);
 		if (!page) {
-			page_cache_sync_readahead(inode->i_mapping,
-						  ra, NULL, index,
+			rac._index = index;
+			page_cache_sync_readahead(&rac, ra,
 						  last_index + 1 - index);
 			page = find_or_create_page(inode->i_mapping, index,
 						   mask);
@@ -2728,8 +2730,8 @@ static int relocate_file_extent_cluster(struct inode *inode,
 		}
 
 		if (PageReadahead(page)) {
-			page_cache_async_readahead(inode->i_mapping,
-						   ra, NULL, page, index,
+			rac._index = index;
+			page_cache_async_readahead(&rac, ra, page,
 						   last_index + 1 - index);
 		}
 
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index d9813a5b075a..f41391fc4230 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4811,6 +4811,8 @@ static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len)
 	unsigned pg_offset = offset_in_page(offset);
 	ssize_t ret = 0;
 
+	DEFINE_READAHEAD(rac, NULL, NULL, 0);
+
 	inode = btrfs_iget(fs_info->sb, sctx->cur_ino, root);
 	if (IS_ERR(inode))
 		return PTR_ERR(inode);
@@ -4829,15 +4831,18 @@ static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len)
 	/* initial readahead */
 	memset(&sctx->ra, 0, sizeof(struct file_ra_state));
 	file_ra_state_init(&sctx->ra, inode->i_mapping);
+	rac.mapping = inode->i_mapping;
 
 	while (index <= last_index) {
 		unsigned cur_len = min_t(unsigned, len,
 					 PAGE_SIZE - pg_offset);
 
+		rac._index = index;
+
 		page = find_lock_page(inode->i_mapping, index);
 		if (!page) {
-			page_cache_sync_readahead(inode->i_mapping, &sctx->ra,
-				NULL, index, last_index + 1 - index);
+			page_cache_sync_readahead(&rac, &sctx->ra,
+				last_index + 1 - index);
 
 			page = find_or_create_page(inode->i_mapping, index,
 					GFP_KERNEL);
@@ -4847,10 +4852,9 @@ static ssize_t fill_read_buf(struct send_ctx *sctx, u64 offset, u32 len)
 			}
 		}
 
-		if (PageReadahead(page)) {
-			page_cache_async_readahead(inode->i_mapping, &sctx->ra,
-				NULL, page, index, last_index + 1 - index);
-		}
+		if (PageReadahead(page))
+			page_cache_async_readahead(&rac, &sctx->ra, page,
+				last_index + 1 - index);
 
 		if (!PageUptodate(page)) {
 			btrfs_readpage(NULL, page);
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 1d82336b1cd4..9fca0de50e0f 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -118,6 +118,8 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
 	struct buffer_head *bh = NULL;
 	struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
 
+	DEFINE_READAHEAD(rac, file, sb->s_bdev->bd_inode->i_mapping, 0);
+
 	if (IS_ENCRYPTED(inode)) {
 		err = fscrypt_get_encryption_info(inode);
 		if (err)
@@ -176,11 +178,10 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
 		if (err > 0) {
 			pgoff_t index = map.m_pblk >>
 					(PAGE_SHIFT - inode->i_blkbits);
-			if (!ra_has_index(&file->f_ra, index))
-				page_cache_sync_readahead(
-					sb->s_bdev->bd_inode->i_mapping,
-					&file->f_ra, file,
-					index, 1);
+			if (!ra_has_index(&file->f_ra, index)) {
+				rac._index = index;
+				page_cache_sync_readahead(&rac, &file->f_ra, 1);
+			}
 			file->f_ra.prev_pos = (loff_t)index << PAGE_SHIFT;
 			bh = ext4_bread(NULL, inode, map.m_lblk, 0);
 			if (IS_ERR(bh)) {
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index 069f498af1e3..69a316e7808d 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -1027,6 +1027,8 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
 	struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
 	int err = 0;
 
+	DEFINE_READAHEAD(rac, file, inode->i_mapping, 0);
+
 	if (IS_ENCRYPTED(inode)) {
 		err = fscrypt_get_encryption_info(inode);
 		if (err)
@@ -1052,9 +1054,11 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
 		cond_resched();
 
 		/* readahead for multi pages of dir */
-		if (npages - n > 1 && !ra_has_index(ra, n))
-			page_cache_sync_readahead(inode->i_mapping, ra, file, n,
+		if (npages - n > 1 && !ra_has_index(ra, n)) {
+			rac._index = n;
+			page_cache_sync_readahead(&rac, ra,
 				min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES));
+		}
 
 		dentry_page = f2fs_find_data_page(inode, n);
 		if (IS_ERR(dentry_page)) {
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 8bf048a76c43..3c362ddfeb4d 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -769,11 +769,10 @@ void delete_from_page_cache_batch(struct address_space *mapping,
 
 #define VM_READAHEAD_PAGES	(SZ_128K / PAGE_SIZE)
 
-void page_cache_sync_readahead(struct address_space *, struct file_ra_state *,
-		struct file *, pgoff_t index, unsigned long req_count);
-void page_cache_async_readahead(struct address_space *, struct file_ra_state *,
-		struct file *, struct page *, pgoff_t index,
+void page_cache_sync_readahead(struct readahead_control *, struct file_ra_state *,
 		unsigned long req_count);
+void page_cache_async_readahead(struct readahead_control *, struct file_ra_state *,
+		struct page *, unsigned long req_count);
 void page_cache_readahead_unbounded(struct readahead_control *,
 		unsigned long nr_to_read, unsigned long lookahead_count);
 
diff --git a/mm/filemap.c b/mm/filemap.c
index 82b97cf4306c..fdfeedd1eb71 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2070,6 +2070,8 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
 	unsigned int prev_offset;
 	int error = 0;
 
+	DEFINE_READAHEAD(rac, filp, mapping, 0);
+
 	if (unlikely(*ppos >= inode->i_sb->s_maxbytes))
 		return 0;
 	iov_iter_truncate(iter, inode->i_sb->s_maxbytes);
@@ -2097,9 +2099,8 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
 		if (!page) {
 			if (iocb->ki_flags & IOCB_NOIO)
 				goto would_block;
-			page_cache_sync_readahead(mapping,
-					ra, filp,
-					index, last_index - index);
+			rac._index = index;
+			page_cache_sync_readahead(&rac, ra, last_index - index);
 			page = find_get_page(mapping, index);
 			if (unlikely(page == NULL))
 				goto no_cached_page;
@@ -2109,9 +2110,9 @@ ssize_t generic_file_buffered_read(struct kiocb *iocb,
 				put_page(page);
 				goto out;
 			}
-			page_cache_async_readahead(mapping,
-					ra, filp, thp_head(page),
-					index, last_index - index);
+			rac._index = index;
+			page_cache_async_readahead(&rac, ra, thp_head(page),
+					last_index - index);
 		}
 		if (!PageUptodate(page)) {
 			/*
@@ -2469,6 +2470,8 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	pgoff_t offset = vmf->pgoff;
 	unsigned int mmap_miss;
 
+	DEFINE_READAHEAD(rac, file, mapping, offset);
+
 	/* If we don't want any read-ahead, don't bother */
 	if (vmf->vma->vm_flags & VM_RAND_READ)
 		return fpin;
@@ -2477,8 +2480,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 
 	if (vmf->vma->vm_flags & VM_SEQ_READ) {
 		fpin = maybe_unlock_mmap_for_io(vmf, fpin);
-		page_cache_sync_readahead(mapping, ra, file, offset,
-					  ra->ra_pages);
+		page_cache_sync_readahead(&rac, ra, ra->ra_pages);
 		return fpin;
 	}
 
@@ -2515,10 +2517,10 @@ static struct file *do_async_mmap_readahead(struct vm_fault *vmf,
 {
 	struct file *file = vmf->vma->vm_file;
 	struct file_ra_state *ra = &file->f_ra;
-	struct address_space *mapping = file->f_mapping;
 	struct file *fpin = NULL;
 	unsigned int mmap_miss;
-	pgoff_t offset = vmf->pgoff;
+
+	DEFINE_READAHEAD(rac, file, file->f_mapping, vmf->pgoff);
 
 	/* If we don't want any read-ahead, don't bother */
 	if (vmf->vma->vm_flags & VM_RAND_READ || !ra->ra_pages)
@@ -2528,8 +2530,8 @@ static struct file *do_async_mmap_readahead(struct vm_fault *vmf,
 		WRITE_ONCE(ra->mmap_miss, --mmap_miss);
 	if (PageReadahead(thp_head(page))) {
 		fpin = maybe_unlock_mmap_for_io(vmf, fpin);
-		page_cache_async_readahead(mapping, ra, file,
-				thp_head(page), offset, ra->ra_pages);
+		page_cache_async_readahead(&rac, ra, thp_head(page),
+				ra->ra_pages);
 	}
 	return fpin;
 }
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index f2d243077b74..84305574b36d 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1703,9 +1703,9 @@ static void collapse_file(struct mm_struct *mm,
 			}
 		} else {	/* !is_shmem */
 			if (!page || xa_is_value(page)) {
+				DEFINE_READAHEAD(rac, file, mapping, index);
 				xas_unlock_irq(&xas);
-				page_cache_sync_readahead(mapping, &file->f_ra,
-							  file, index,
+				page_cache_sync_readahead(&rac, &file->f_ra,
 							  end - index);
 				/* drain pagevecs to help isolate_lru_page() */
 				lru_add_drain();
diff --git a/mm/readahead.c b/mm/readahead.c
index 366357e6e845..d8e3e59e4c46 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -633,10 +633,8 @@ static void ondemand_readahead(struct readahead_control *rac,
 
 /**
  * page_cache_sync_readahead - generic file readahead
- * @mapping: address_space which holds the pagecache and I/O vectors
+ * @rac: Readahead control.
  * @ra: file_ra_state which holds the readahead state
- * @filp: passed on to ->readpage() and ->readpages()
- * @index: Index of first page to be read.
  * @req_count: Total number of pages being read by the caller.
  *
  * page_cache_sync_readahead() should be called when a cache miss happened:
@@ -644,12 +642,10 @@ static void ondemand_readahead(struct readahead_control *rac,
  * pages onto the read request if access patterns suggest it will improve
  * performance.
  */
-void page_cache_sync_readahead(struct address_space *mapping,
-			       struct file_ra_state *ra, struct file *filp,
-			       pgoff_t index, unsigned long req_count)
+void page_cache_sync_readahead(struct readahead_control *rac,
+			       struct file_ra_state *ra,
+			       unsigned long req_count)
 {
-	DEFINE_READAHEAD(rac, filp, mapping, index);
-
 	/* no read-ahead */
 	if (!ra->ra_pages)
 		return;
@@ -658,23 +654,21 @@ void page_cache_sync_readahead(struct address_space *mapping,
 		return;
 
 	/* be dumb */
-	if (filp && (filp->f_mode & FMODE_RANDOM)) {
-		force_page_cache_readahead(&rac, req_count);
+	if (rac->file && (rac->file->f_mode & FMODE_RANDOM)) {
+		force_page_cache_readahead(rac, req_count);
 		return;
 	}
 
 	/* do read-ahead */
-	ondemand_readahead(&rac, ra, NULL, req_count);
+	ondemand_readahead(rac, ra, NULL, req_count);
 }
 EXPORT_SYMBOL_GPL(page_cache_sync_readahead);
 
 /**
  * page_cache_async_readahead - file readahead for marked pages
- * @mapping: address_space which holds the pagecache and I/O vectors
+ * @rac: Readahead control.
  * @ra: file_ra_state which holds the readahead state
- * @filp: passed on to ->readpage() and ->readpages()
  * @page: The page at @index which triggered the readahead call.
- * @index: Index of first page to be read.
  * @req_count: Total number of pages being read by the caller.
  *
  * page_cache_async_readahead() should be called when a page is used which
@@ -683,13 +677,11 @@ EXPORT_SYMBOL_GPL(page_cache_sync_readahead);
  * more pages.
  */
 void
-page_cache_async_readahead(struct address_space *mapping,
-			   struct file_ra_state *ra, struct file *filp,
-			   struct page *page, pgoff_t index,
+page_cache_async_readahead(struct readahead_control *rac,
+			   struct file_ra_state *ra,
+			   struct page *page,
 			   unsigned long req_count)
 {
-	DEFINE_READAHEAD(rac, filp, mapping, index);
-
 	/* No Read-ahead */
 	if (!ra->ra_pages)
 		return;
@@ -705,14 +697,14 @@ page_cache_async_readahead(struct address_space *mapping,
 	/*
 	 * Defer asynchronous read-ahead on IO congestion.
 	 */
-	if (inode_read_congested(mapping->host))
+	if (inode_read_congested(rac->mapping->host))
 		return;
 
 	if (blk_cgroup_congested())
 		return;
 
 	/* do read-ahead */
-	ondemand_readahead(&rac, ra, page, req_count);
+	ondemand_readahead(rac, ra, page, req_count);
 }
 EXPORT_SYMBOL_GPL(page_cache_async_readahead);
 



  parent reply	other threads:[~2020-09-02 15:45 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-02 15:44 [RFC PATCH 0/6] mm: Make more use of readahead_control [ver #2] David Howells
2020-09-02 15:44 ` [RFC PATCH 1/6] Fix khugepaged's request size in collapse_file() " David Howells
2020-09-02 15:44 ` [RFC PATCH 2/6] mm: Make ondemand_readahead() take a readahead_control struct " David Howells
2020-09-02 15:44 ` [RFC PATCH 3/6] mm: Push readahead_control down into force_page_cache_readahead() " David Howells
2020-09-02 15:54   ` Matthew Wilcox
2020-09-02 15:44 ` David Howells [this message]
2020-09-02 15:44 ` [RFC PATCH 5/6] mm: Fold ra_submit() into do_sync_mmap_readahead() " David Howells
2020-09-02 15:45 ` [RFC PATCH 6/6] mm: Pass a file_ra_state struct into force_page_cache_readahead() " David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=159906148519.663183.14012026331551396649.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.