diff options
Diffstat (limited to 'mm/page_io.c')
| -rw-r--r-- | mm/page_io.c | 35 | 
1 files changed, 21 insertions, 14 deletions
diff --git a/mm/page_io.c b/mm/page_io.c index 9725c7e1eeea..b417f000b49e 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -25,6 +25,7 @@  #include <linux/psi.h>  #include <linux/uio.h>  #include <linux/sched/task.h> +#include <linux/delayacct.h>  void end_swap_bio_write(struct bio *bio)  { @@ -337,10 +338,10 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,  		return 0;  	} -	bio = bio_alloc(GFP_NOIO, 1); -	bio_set_dev(bio, sis->bdev); +	bio = bio_alloc(sis->bdev, 1, +			REQ_OP_WRITE | REQ_SWAP | wbc_to_write_flags(wbc), +			GFP_NOIO);  	bio->bi_iter.bi_sector = swap_page_sector(page); -	bio->bi_opf = REQ_OP_WRITE | REQ_SWAP | wbc_to_write_flags(wbc);  	bio->bi_end_io = end_write_func;  	bio_add_page(bio, page, thp_size(page), 0); @@ -358,6 +359,7 @@ int swap_readpage(struct page *page, bool synchronous)  	struct bio *bio;  	int ret = 0;  	struct swap_info_struct *sis = page_swap_info(page); +	bool workingset = PageWorkingset(page);  	unsigned long pflags;  	VM_BUG_ON_PAGE(!PageSwapCache(page) && !synchronous, page); @@ -369,7 +371,9 @@ int swap_readpage(struct page *page, bool synchronous)  	 * or the submitting cgroup IO-throttled, submission can be a  	 * significant part of overall IO time.  	 */ -	psi_memstall_enter(&pflags); +	if (workingset) +		psi_memstall_enter(&pflags); +	delayacct_swapin_start();  	if (frontswap_load(page) == 0) {  		SetPageUptodate(page); @@ -401,9 +405,7 @@ int swap_readpage(struct page *page, bool synchronous)  	}  	ret = 0; -	bio = bio_alloc(GFP_KERNEL, 1); -	bio_set_dev(bio, sis->bdev); -	bio->bi_opf = REQ_OP_READ; +	bio = bio_alloc(sis->bdev, 1, REQ_OP_READ, GFP_KERNEL);  	bio->bi_iter.bi_sector = swap_page_sector(page);  	bio->bi_end_io = end_swap_bio_read;  	bio_add_page(bio, page, thp_size(page), 0); @@ -431,20 +433,25 @@ int swap_readpage(struct page *page, bool synchronous)  	bio_put(bio);  out: -	psi_memstall_leave(&pflags); +	if (workingset) +		psi_memstall_leave(&pflags); +	delayacct_swapin_end();  	return ret;  } -int swap_set_page_dirty(struct page *page) +bool swap_dirty_folio(struct address_space *mapping, struct folio *folio)  { -	struct swap_info_struct *sis = page_swap_info(page); +	struct swap_info_struct *sis = swp_swap_info(folio_swap_entry(folio));  	if (data_race(sis->flags & SWP_FS_OPS)) { -		struct address_space *mapping = sis->swap_file->f_mapping; +		const struct address_space_operations *aops; + +		mapping = sis->swap_file->f_mapping; +		aops = mapping->a_ops; -		VM_BUG_ON_PAGE(!PageSwapCache(page), page); -		return mapping->a_ops->set_page_dirty(page); +		VM_BUG_ON_FOLIO(!folio_test_swapcache(folio), folio); +		return aops->dirty_folio(mapping, folio);  	} else { -		return __set_page_dirty_no_writeback(page); +		return noop_dirty_folio(mapping, folio);  	}  }  |