linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
* [f2fs-dev] [PATCH v4 0/3] support compressed file write/read amplifiction
@ 2022-07-31  3:33 Fengnan Chang
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 1/3] f2fs: intorduce f2fs_all_cluster_page_ready Fengnan Chang
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Fengnan Chang @ 2022-07-31  3:33 UTC (permalink / raw)
  To: jaegeuk, chao; +Cc: Fengnan Chang, linux-f2fs-devel

From: Fengnan Chang <changfengnan@vivo.com>

Optimise f2fs_write_cache_pages, and support compressed file write/read
amplifiction accounting.

v4:
  fix read amplifiction accounting when read one compressed page.
v3:
  fix enable COMPRESS_CACHE may make read amplifiction accounting
incorrect.

Fengnan Chang (3):
  f2fs: intorduce f2fs_all_cluster_page_ready
  f2fs: use onstack pages instead of pvec
  f2fs: support compressed file write/read amplifiction

 fs/f2fs/compress.c | 30 ++++++++++++++--------
 fs/f2fs/data.c     | 64 ++++++++++++++++++++++++++++++++++------------
 fs/f2fs/debug.c    |  7 +++--
 fs/f2fs/f2fs.h     | 42 +++++++++++++++++++++++++++---
 4 files changed, 111 insertions(+), 32 deletions(-)

-- 
2.25.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [f2fs-dev] [PATCH v4 1/3] f2fs: intorduce f2fs_all_cluster_page_ready
  2022-07-31  3:33 [f2fs-dev] [PATCH v4 0/3] support compressed file write/read amplifiction Fengnan Chang
@ 2022-07-31  3:33 ` Fengnan Chang
  2022-08-04 14:00   ` Chao Yu
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 2/3] f2fs: use onstack pages instead of pvec Fengnan Chang
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 3/3] f2fs: support compressed file write/read amplifiction Fengnan Chang
  2 siblings, 1 reply; 8+ messages in thread
From: Fengnan Chang @ 2022-07-31  3:33 UTC (permalink / raw)
  To: jaegeuk, chao; +Cc: Fengnan Chang, linux-f2fs-devel

From: Fengnan Chang <changfengnan@vivo.com>

When write total cluster, all pages is uptodate, there is not need to call
f2fs_prepare_compress_overwrite, intorduce f2fs_all_cluster_page_ready
to avoid this.

Signed-off-by: Fengnan Chang <changfengnan@vivo.com>
---
 fs/f2fs/compress.c | 21 ++++++++++++++-------
 fs/f2fs/data.c     |  8 ++++++--
 fs/f2fs/f2fs.h     |  4 ++--
 3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 2e06a301bf12..4677300e87fe 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -929,20 +929,27 @@ bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index)
 	return is_page_in_cluster(cc, index);
 }
 
-bool f2fs_all_cluster_page_loaded(struct compress_ctx *cc, struct pagevec *pvec,
-				int index, int nr_pages)
+bool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct pagevec *pvec,
+				int index, int nr_pages, bool uptodate)
 {
-	unsigned long pgidx;
-	int i;
+	unsigned long pgidx = pvec->pages[index]->index;
+	int i = uptodate ? 0 : 1;
 
-	if (nr_pages - index < cc->cluster_size)
+	/*
+	 * when uptodate set to true, try to check all pages in cluster is
+	 * uptodate or not.
+	 */
+	if (uptodate && (pgidx % cc->cluster_size))
 		return false;
 
-	pgidx = pvec->pages[index]->index;
+	if (nr_pages - index < cc->cluster_size)
+		return false;
 
-	for (i = 1; i < cc->cluster_size; i++) {
+	for (; i < cc->cluster_size; i++) {
 		if (pvec->pages[index + i]->index != pgidx + i)
 			return false;
+		if (uptodate && !PageUptodate(pvec->pages[index + i]))
+			return false;
 	}
 
 	return true;
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index f48eec8f93e2..34a7a9affea0 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3011,6 +3011,10 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 				if (!f2fs_cluster_is_empty(&cc))
 					goto lock_page;
 
+				if (f2fs_all_cluster_page_ready(&cc,
+					&pvec, i, nr_pages, true))
+					goto lock_page;
+
 				ret2 = f2fs_prepare_compress_overwrite(
 							inode, &pagep,
 							page->index, &fsdata);
@@ -3021,8 +3025,8 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 				} else if (ret2 &&
 					(!f2fs_compress_write_end(inode,
 						fsdata, page->index, 1) ||
-					 !f2fs_all_cluster_page_loaded(&cc,
-						&pvec, i, nr_pages))) {
+					 !f2fs_all_cluster_page_ready(&cc,
+						&pvec, i, nr_pages, false))) {
 					retry = 1;
 					break;
 				}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 3f669f851240..ac3788d0345d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4193,8 +4193,8 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed,
 				block_t blkaddr, bool in_task);
 bool f2fs_cluster_is_empty(struct compress_ctx *cc);
 bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index);
-bool f2fs_all_cluster_page_loaded(struct compress_ctx *cc, struct pagevec *pvec,
-				int index, int nr_pages);
+bool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct pagevec *pvec,
+				int index, int nr_pages, bool uptodate);
 bool f2fs_sanity_check_cluster(struct dnode_of_data *dn);
 void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page);
 int f2fs_write_multi_pages(struct compress_ctx *cc,
-- 
2.25.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [f2fs-dev] [PATCH v4 2/3] f2fs: use onstack pages instead of pvec
  2022-07-31  3:33 [f2fs-dev] [PATCH v4 0/3] support compressed file write/read amplifiction Fengnan Chang
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 1/3] f2fs: intorduce f2fs_all_cluster_page_ready Fengnan Chang
@ 2022-07-31  3:33 ` Fengnan Chang
  2022-08-04 14:01   ` Chao Yu
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 3/3] f2fs: support compressed file write/read amplifiction Fengnan Chang
  2 siblings, 1 reply; 8+ messages in thread
From: Fengnan Chang @ 2022-07-31  3:33 UTC (permalink / raw)
  To: jaegeuk, chao; +Cc: linux-f2fs-devel

Since pvec have 15 pages, it not a multiple of 4, when write compressed
pages, write in 64K as a unit, it will call pagevec_lookup_range_tag
agagin, sometimes this will take a lot of time.
Use onstack pages instead of pvec to mitigate this problem.

Signed-off-by: Fengnan Chang <fengnanchang@gmail.com>
---
 fs/f2fs/compress.c |  8 ++++----
 fs/f2fs/data.c     | 16 +++++++---------
 fs/f2fs/f2fs.h     |  4 +++-
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 4677300e87fe..0eca4e060deb 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -929,10 +929,10 @@ bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index)
 	return is_page_in_cluster(cc, index);
 }
 
-bool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct pagevec *pvec,
+bool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct page **pages,
 				int index, int nr_pages, bool uptodate)
 {
-	unsigned long pgidx = pvec->pages[index]->index;
+	unsigned long pgidx = pages[index]->index;
 	int i = uptodate ? 0 : 1;
 
 	/*
@@ -946,9 +946,9 @@ bool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct pagevec *pvec,
 		return false;
 
 	for (; i < cc->cluster_size; i++) {
-		if (pvec->pages[index + i]->index != pgidx + i)
+		if (pages[index + i]->index != pgidx + i)
 			return false;
-		if (uptodate && !PageUptodate(pvec->pages[index + i]))
+		if (uptodate && !PageUptodate(pages[index + i]))
 			return false;
 	}
 
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 34a7a9affea0..0b159c555069 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2916,7 +2916,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 {
 	int ret = 0;
 	int done = 0, retry = 0;
-	struct pagevec pvec;
+	struct page *pages[F2FS_ONSTACK_PAGES];
 	struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
 	struct bio *bio = NULL;
 	sector_t last_block;
@@ -2947,8 +2947,6 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 	int submitted = 0;
 	int i;
 
-	pagevec_init(&pvec);
-
 	if (get_dirty_pages(mapping->host) <=
 				SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
 		set_inode_flag(mapping->host, FI_HOT_DATA);
@@ -2974,13 +2972,13 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 		tag_pages_for_writeback(mapping, index, end);
 	done_index = index;
 	while (!done && !retry && (index <= end)) {
-		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
-				tag);
+		nr_pages = find_get_pages_range_tag(mapping, &index, end,
+				tag, F2FS_ONSTACK_PAGES, pages);
 		if (nr_pages == 0)
 			break;
 
 		for (i = 0; i < nr_pages; i++) {
-			struct page *page = pvec.pages[i];
+			struct page *page = pages[i];
 			bool need_readd;
 readd:
 			need_readd = false;
@@ -3012,7 +3010,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 					goto lock_page;
 
 				if (f2fs_all_cluster_page_ready(&cc,
-					&pvec, i, nr_pages, true))
+					pages, i, nr_pages, true))
 					goto lock_page;
 
 				ret2 = f2fs_prepare_compress_overwrite(
@@ -3026,7 +3024,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 					(!f2fs_compress_write_end(inode,
 						fsdata, page->index, 1) ||
 					 !f2fs_all_cluster_page_ready(&cc,
-						&pvec, i, nr_pages, false))) {
+						pages, i, nr_pages, false))) {
 					retry = 1;
 					break;
 				}
@@ -3116,7 +3114,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 			if (need_readd)
 				goto readd;
 		}
-		pagevec_release(&pvec);
+		release_pages(pages, nr_pages);
 		cond_resched();
 	}
 #ifdef CONFIG_F2FS_FS_COMPRESSION
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ac3788d0345d..955dbf4f83ad 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -599,6 +599,8 @@ enum {
 #define RECOVERY_MAX_RA_BLOCKS		BIO_MAX_VECS
 #define RECOVERY_MIN_RA_BLOCKS		1
 
+#define F2FS_ONSTACK_PAGES	16	/* nr of onstack pages */
+
 struct rb_entry {
 	struct rb_node rb_node;		/* rb node located in rb-tree */
 	union {
@@ -4193,7 +4195,7 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed,
 				block_t blkaddr, bool in_task);
 bool f2fs_cluster_is_empty(struct compress_ctx *cc);
 bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index);
-bool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct pagevec *pvec,
+bool f2fs_all_cluster_page_ready(struct compress_ctx *cc, struct page **pages,
 				int index, int nr_pages, bool uptodate);
 bool f2fs_sanity_check_cluster(struct dnode_of_data *dn);
 void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page);
-- 
2.25.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [f2fs-dev] [PATCH v4 3/3] f2fs: support compressed file write/read amplifiction
  2022-07-31  3:33 [f2fs-dev] [PATCH v4 0/3] support compressed file write/read amplifiction Fengnan Chang
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 1/3] f2fs: intorduce f2fs_all_cluster_page_ready Fengnan Chang
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 2/3] f2fs: use onstack pages instead of pvec Fengnan Chang
@ 2022-07-31  3:33 ` Fengnan Chang
  2022-08-04  3:52   ` Jaegeuk Kim
  2 siblings, 1 reply; 8+ messages in thread
From: Fengnan Chang @ 2022-07-31  3:33 UTC (permalink / raw)
  To: jaegeuk, chao; +Cc: linux-f2fs-devel

Try to support compressed file write and amplifiction accounting.

Signed-off-by: Fengnan Chang <fengnanchang@gmail.com>
---
 fs/f2fs/compress.c |  7 +++++--
 fs/f2fs/data.c     | 44 ++++++++++++++++++++++++++++++++++++--------
 fs/f2fs/debug.c    |  7 +++++--
 fs/f2fs/f2fs.h     | 36 +++++++++++++++++++++++++++++++++++-
 4 files changed, 81 insertions(+), 13 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 0eca4e060deb..374d4a73ab2c 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1125,7 +1125,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
 	sector_t last_block_in_bio;
 	unsigned fgp_flag = FGP_LOCK | FGP_WRITE | FGP_CREAT;
 	pgoff_t start_idx = start_idx_of_cluster(cc);
-	int i, ret;
+	int i, ret, once_read = 0;
 
 retry:
 	ret = f2fs_is_compressed_cluster(cc->inode, start_idx);
@@ -1155,13 +1155,16 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
 		struct bio *bio = NULL;
 
 		ret = f2fs_read_multi_pages(cc, &bio, cc->cluster_size,
-					&last_block_in_bio, false, true);
+					&last_block_in_bio, false, true, &once_read);
 		f2fs_put_rpages(cc);
 		f2fs_destroy_compress_ctx(cc, true);
 		if (ret)
 			goto out;
 		if (bio)
 			f2fs_submit_bio(sbi, bio, DATA);
+		/* All need read page in here is read amplification */
+		if (once_read)
+			f2fs_i_compr_ra_blocks_update(cc->inode, once_read, true);
 
 		ret = f2fs_init_compress_ctx(cc);
 		if (ret)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 0b159c555069..9bedcea189eb 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2133,7 +2133,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
 #ifdef CONFIG_F2FS_FS_COMPRESSION
 int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
 				unsigned nr_pages, sector_t *last_block_in_bio,
-				bool is_readahead, bool for_write)
+				bool is_readahead, bool for_write, int *nr_need_read)
 {
 	struct dnode_of_data dn;
 	struct inode *inode = cc->inode;
@@ -2146,7 +2146,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
 	struct extent_info ei = {0, };
 	bool from_dnode = true;
 	int i;
-	int ret = 0;
+	int ret = 0, nr_cache_hit = 0;
+
+	if (nr_need_read)
+		*nr_need_read = 0;
 
 	f2fs_bug_on(sbi, f2fs_cluster_is_empty(cc));
 
@@ -2237,6 +2240,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
 		if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
 			if (atomic_dec_and_test(&dic->remaining_pages))
 				f2fs_decompress_cluster(dic, true);
+			nr_cache_hit++;
 			continue;
 		}
 
@@ -2275,6 +2279,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
 		*last_block_in_bio = blkaddr;
 	}
 
+	/* we need read whole cluster when nr_cache_hit less than nr_cpages */
+	if (nr_need_read && nr_cache_hit < cc->nr_cpages)
+		*nr_need_read = cc->nr_cpages;
+
 	if (from_dnode)
 		f2fs_put_dnode(&dn);
 
@@ -2322,7 +2330,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
 #endif
 	unsigned nr_pages = rac ? readahead_count(rac) : 1;
 	unsigned max_nr_pages = nr_pages;
-	int ret = 0;
+	int ret = 0, once_read = 0, total_read = 0, single_read = 0;
 
 	map.m_pblk = 0;
 	map.m_lblk = 0;
@@ -2346,10 +2354,11 @@ static int f2fs_mpage_readpages(struct inode *inode,
 				ret = f2fs_read_multi_pages(&cc, &bio,
 							max_nr_pages,
 							&last_block_in_bio,
-							rac != NULL, false);
+							rac != NULL, false, &once_read);
 				f2fs_destroy_compress_ctx(&cc, false);
 				if (ret)
 					goto set_error_page;
+				total_read += once_read;
 			}
 			if (cc.cluster_idx == NULL_CLUSTER) {
 				if (nc_cluster_idx ==
@@ -2389,6 +2398,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
 			zero_user_segment(page, 0, PAGE_SIZE);
 			unlock_page(page);
 		}
+		single_read++;
 #ifdef CONFIG_F2FS_FS_COMPRESSION
 next_page:
 #endif
@@ -2402,12 +2412,23 @@ static int f2fs_mpage_readpages(struct inode *inode,
 				ret = f2fs_read_multi_pages(&cc, &bio,
 							max_nr_pages,
 							&last_block_in_bio,
-							rac != NULL, false);
+							rac != NULL, false, &once_read);
 				f2fs_destroy_compress_ctx(&cc, false);
+				if (!ret)
+					total_read += once_read;
 			}
 		}
 #endif
 	}
+	max_nr_pages -= single_read;
+	if (total_read > max_nr_pages)
+		f2fs_i_compr_ra_blocks_update(inode,
+						total_read - max_nr_pages,
+						true);
+	else
+		f2fs_i_compr_ra_blocks_update(inode,
+						max_nr_pages - total_read,
+						false);
 	if (bio)
 		__submit_bio(F2FS_I_SB(inode), bio, DATA);
 	return ret;
@@ -2944,11 +2965,11 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 	int range_whole = 0;
 	xa_mark_t tag;
 	int nwritten = 0;
-	int submitted = 0;
+	int submitted = 0, raw_dirty_pages = 0;
 	int i;
 
-	if (get_dirty_pages(mapping->host) <=
-				SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
+	raw_dirty_pages = get_dirty_pages(mapping->host);
+	if (raw_dirty_pages <= SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
 		set_inode_flag(mapping->host, FI_HOT_DATA);
 	else
 		clear_inode_flag(mapping->host, FI_HOT_DATA);
@@ -3148,6 +3169,12 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 	if (bio)
 		f2fs_submit_merged_ipu_write(sbi, &bio, NULL);
 
+	if (f2fs_compressed_file(inode)) {
+		if (nwritten > raw_dirty_pages)
+			f2fs_i_compr_wa_blocks_update(inode, nwritten - raw_dirty_pages, true);
+		else
+			f2fs_i_compr_wa_blocks_update(inode, raw_dirty_pages - nwritten, false);
+	}
 	return ret;
 }
 
@@ -3498,6 +3525,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
 			err = ret;
 			goto fail;
 		} else if (ret) {
+			f2fs_i_compr_wa_blocks_update(inode, ret - 1, true);
 			return 0;
 		}
 	}
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index c01471573977..e6b943edba91 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -136,6 +136,8 @@ static void update_general_status(struct f2fs_sb_info *sbi)
 	si->inline_dir = atomic_read(&sbi->inline_dir);
 	si->compr_inode = atomic_read(&sbi->compr_inode);
 	si->compr_blocks = atomic64_read(&sbi->compr_blocks);
+	si->compr_wa_blocks = atomic64_read(&sbi->compr_wa_blocks);
+	si->compr_ra_blocks = atomic64_read(&sbi->compr_ra_blocks);
 	si->append = sbi->im[APPEND_INO].ino_num;
 	si->update = sbi->im[UPDATE_INO].ino_num;
 	si->orphans = sbi->im[ORPHAN_INO].ino_num;
@@ -383,8 +385,9 @@ static int stat_show(struct seq_file *s, void *v)
 			   si->inline_inode);
 		seq_printf(s, "  - Inline_dentry Inode: %u\n",
 			   si->inline_dir);
-		seq_printf(s, "  - Compressed Inode: %u, Blocks: %llu\n",
-			   si->compr_inode, si->compr_blocks);
+		seq_printf(s, "  - Compressed Inode: %u, Blocks: %llu, WA Blocks: %lld, RA Blocks %lld\n",
+			   si->compr_inode, si->compr_blocks,
+			   si->compr_wa_blocks, si->compr_ra_blocks);
 		seq_printf(s, "  - Orphan/Append/Update Inode: %u, %u, %u\n",
 			   si->orphans, si->append, si->update);
 		seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 955dbf4f83ad..c549be2e75af 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1761,6 +1761,8 @@ struct f2fs_sb_info {
 	atomic_t inline_dir;			/* # of inline_dentry inodes */
 	atomic_t compr_inode;			/* # of compressed inodes */
 	atomic64_t compr_blocks;		/* # of compressed blocks */
+	atomic64_t compr_wa_blocks;		/* # of compressed WA blocks */
+	atomic64_t compr_ra_blocks;		/* # of compressed RA blocks */
 	atomic_t max_aw_cnt;			/* max # of atomic writes */
 	unsigned int io_skip_bggc;		/* skip background gc for in-flight IO */
 	unsigned int other_skip_bggc;		/* skip background gc for other reasons */
@@ -3859,6 +3861,8 @@ struct f2fs_stat_info {
 	int inline_xattr, inline_inode, inline_dir, append, update, orphans;
 	int compr_inode;
 	unsigned long long compr_blocks;
+	long long compr_wa_blocks;
+	long long compr_ra_blocks;
 	int aw_cnt, max_aw_cnt;
 	unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;
 	unsigned int bimodal, avg_vblocks;
@@ -3946,6 +3950,14 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
 		(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_blocks))
 #define stat_sub_compr_blocks(inode, blocks)				\
 		(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_blocks))
+#define stat_add_compr_wa_blocks(inode, blocks)				\
+	(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_wa_blocks))
+#define stat_sub_compr_wa_blocks(inode, blocks)				\
+	(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_wa_blocks))
+#define stat_add_compr_ra_blocks(inode, blocks)				\
+	(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_ra_blocks))
+#define stat_sub_compr_ra_blocks(inode, blocks)				\
+	(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_ra_blocks))
 #define stat_inc_meta_count(sbi, blkaddr)				\
 	do {								\
 		if (blkaddr < SIT_I(sbi)->sit_base_addr)		\
@@ -4030,6 +4042,10 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
 #define stat_dec_compr_inode(inode)			do { } while (0)
 #define stat_add_compr_blocks(inode, blocks)		do { } while (0)
 #define stat_sub_compr_blocks(inode, blocks)		do { } while (0)
+#define stat_add_compr_wa_blocks(inode, blocks)		do { } while (0)
+#define stat_sub_compr_wa_blocks(inode, blocks)		do { } while (0)
+#define stat_add_compr_ra_blocks(inode, blocks)		do { } while (0)
+#define stat_sub_compr_ra_blocks(inode, blocks)		do { } while (0)
 #define stat_update_max_atomic_write(inode)		do { } while (0)
 #define stat_inc_meta_count(sbi, blkaddr)		do { } while (0)
 #define stat_inc_seg_type(sbi, curseg)			do { } while (0)
@@ -4209,7 +4225,7 @@ void f2fs_update_extent_tree_range_compressed(struct inode *inode,
 				unsigned int c_len);
 int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
 				unsigned nr_pages, sector_t *last_block_in_bio,
-				bool is_readahead, bool for_write);
+				bool is_readahead, bool for_write, int *nr_need_read);
 struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
 void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
 				bool in_task);
@@ -4465,6 +4481,24 @@ static inline void f2fs_i_compr_blocks_update(struct inode *inode,
 	f2fs_mark_inode_dirty_sync(inode, true);
 }
 
+static inline void f2fs_i_compr_wa_blocks_update(struct inode *inode,
+						u64 blocks, bool add)
+{
+	if (add)
+		stat_add_compr_wa_blocks(inode, blocks);
+	else
+		stat_sub_compr_wa_blocks(inode, blocks);
+}
+
+static inline void f2fs_i_compr_ra_blocks_update(struct inode *inode,
+						u64 blocks, bool add)
+{
+	if (add)
+		stat_add_compr_ra_blocks(inode, blocks);
+	else
+		stat_sub_compr_ra_blocks(inode, blocks);
+}
+
 static inline int block_unaligned_IO(struct inode *inode,
 				struct kiocb *iocb, struct iov_iter *iter)
 {
-- 
2.25.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [f2fs-dev] [PATCH v4 3/3] f2fs: support compressed file write/read amplifiction
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 3/3] f2fs: support compressed file write/read amplifiction Fengnan Chang
@ 2022-08-04  3:52   ` Jaegeuk Kim
  2022-08-06  4:35     ` fengnan chang
  0 siblings, 1 reply; 8+ messages in thread
From: Jaegeuk Kim @ 2022-08-04  3:52 UTC (permalink / raw)
  To: Fengnan Chang; +Cc: linux-f2fs-devel

I feel that this adds lots of codes only for accounting purpose. Can we
discuss why we need to know WA? If it's for debugging purpose, can we
debug by tracepoints?

On 07/31, Fengnan Chang wrote:
> Try to support compressed file write and amplifiction accounting.
> 
> Signed-off-by: Fengnan Chang <fengnanchang@gmail.com>
> ---
>  fs/f2fs/compress.c |  7 +++++--
>  fs/f2fs/data.c     | 44 ++++++++++++++++++++++++++++++++++++--------
>  fs/f2fs/debug.c    |  7 +++++--
>  fs/f2fs/f2fs.h     | 36 +++++++++++++++++++++++++++++++++++-
>  4 files changed, 81 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
> index 0eca4e060deb..374d4a73ab2c 100644
> --- a/fs/f2fs/compress.c
> +++ b/fs/f2fs/compress.c
> @@ -1125,7 +1125,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
>  	sector_t last_block_in_bio;
>  	unsigned fgp_flag = FGP_LOCK | FGP_WRITE | FGP_CREAT;
>  	pgoff_t start_idx = start_idx_of_cluster(cc);
> -	int i, ret;
> +	int i, ret, once_read = 0;
>  
>  retry:
>  	ret = f2fs_is_compressed_cluster(cc->inode, start_idx);
> @@ -1155,13 +1155,16 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
>  		struct bio *bio = NULL;
>  
>  		ret = f2fs_read_multi_pages(cc, &bio, cc->cluster_size,
> -					&last_block_in_bio, false, true);
> +					&last_block_in_bio, false, true, &once_read);
>  		f2fs_put_rpages(cc);
>  		f2fs_destroy_compress_ctx(cc, true);
>  		if (ret)
>  			goto out;
>  		if (bio)
>  			f2fs_submit_bio(sbi, bio, DATA);
> +		/* All need read page in here is read amplification */
> +		if (once_read)
> +			f2fs_i_compr_ra_blocks_update(cc->inode, once_read, true);
>  
>  		ret = f2fs_init_compress_ctx(cc);
>  		if (ret)
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 0b159c555069..9bedcea189eb 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -2133,7 +2133,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
>  #ifdef CONFIG_F2FS_FS_COMPRESSION
>  int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>  				unsigned nr_pages, sector_t *last_block_in_bio,
> -				bool is_readahead, bool for_write)
> +				bool is_readahead, bool for_write, int *nr_need_read)
>  {
>  	struct dnode_of_data dn;
>  	struct inode *inode = cc->inode;
> @@ -2146,7 +2146,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>  	struct extent_info ei = {0, };
>  	bool from_dnode = true;
>  	int i;
> -	int ret = 0;
> +	int ret = 0, nr_cache_hit = 0;
> +
> +	if (nr_need_read)
> +		*nr_need_read = 0;
>  
>  	f2fs_bug_on(sbi, f2fs_cluster_is_empty(cc));
>  
> @@ -2237,6 +2240,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>  		if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
>  			if (atomic_dec_and_test(&dic->remaining_pages))
>  				f2fs_decompress_cluster(dic, true);
> +			nr_cache_hit++;
>  			continue;
>  		}
>  
> @@ -2275,6 +2279,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>  		*last_block_in_bio = blkaddr;
>  	}
>  
> +	/* we need read whole cluster when nr_cache_hit less than nr_cpages */
> +	if (nr_need_read && nr_cache_hit < cc->nr_cpages)
> +		*nr_need_read = cc->nr_cpages;
> +
>  	if (from_dnode)
>  		f2fs_put_dnode(&dn);
>  
> @@ -2322,7 +2330,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
>  #endif
>  	unsigned nr_pages = rac ? readahead_count(rac) : 1;
>  	unsigned max_nr_pages = nr_pages;
> -	int ret = 0;
> +	int ret = 0, once_read = 0, total_read = 0, single_read = 0;
>  
>  	map.m_pblk = 0;
>  	map.m_lblk = 0;
> @@ -2346,10 +2354,11 @@ static int f2fs_mpage_readpages(struct inode *inode,
>  				ret = f2fs_read_multi_pages(&cc, &bio,
>  							max_nr_pages,
>  							&last_block_in_bio,
> -							rac != NULL, false);
> +							rac != NULL, false, &once_read);
>  				f2fs_destroy_compress_ctx(&cc, false);
>  				if (ret)
>  					goto set_error_page;
> +				total_read += once_read;
>  			}
>  			if (cc.cluster_idx == NULL_CLUSTER) {
>  				if (nc_cluster_idx ==
> @@ -2389,6 +2398,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
>  			zero_user_segment(page, 0, PAGE_SIZE);
>  			unlock_page(page);
>  		}
> +		single_read++;
>  #ifdef CONFIG_F2FS_FS_COMPRESSION
>  next_page:
>  #endif
> @@ -2402,12 +2412,23 @@ static int f2fs_mpage_readpages(struct inode *inode,
>  				ret = f2fs_read_multi_pages(&cc, &bio,
>  							max_nr_pages,
>  							&last_block_in_bio,
> -							rac != NULL, false);
> +							rac != NULL, false, &once_read);
>  				f2fs_destroy_compress_ctx(&cc, false);
> +				if (!ret)
> +					total_read += once_read;
>  			}
>  		}
>  #endif
>  	}
> +	max_nr_pages -= single_read;
> +	if (total_read > max_nr_pages)
> +		f2fs_i_compr_ra_blocks_update(inode,
> +						total_read - max_nr_pages,
> +						true);
> +	else
> +		f2fs_i_compr_ra_blocks_update(inode,
> +						max_nr_pages - total_read,
> +						false);
>  	if (bio)
>  		__submit_bio(F2FS_I_SB(inode), bio, DATA);
>  	return ret;
> @@ -2944,11 +2965,11 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
>  	int range_whole = 0;
>  	xa_mark_t tag;
>  	int nwritten = 0;
> -	int submitted = 0;
> +	int submitted = 0, raw_dirty_pages = 0;
>  	int i;
>  
> -	if (get_dirty_pages(mapping->host) <=
> -				SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
> +	raw_dirty_pages = get_dirty_pages(mapping->host);
> +	if (raw_dirty_pages <= SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
>  		set_inode_flag(mapping->host, FI_HOT_DATA);
>  	else
>  		clear_inode_flag(mapping->host, FI_HOT_DATA);
> @@ -3148,6 +3169,12 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
>  	if (bio)
>  		f2fs_submit_merged_ipu_write(sbi, &bio, NULL);
>  
> +	if (f2fs_compressed_file(inode)) {
> +		if (nwritten > raw_dirty_pages)
> +			f2fs_i_compr_wa_blocks_update(inode, nwritten - raw_dirty_pages, true);
> +		else
> +			f2fs_i_compr_wa_blocks_update(inode, raw_dirty_pages - nwritten, false);
> +	}
>  	return ret;
>  }
>  
> @@ -3498,6 +3525,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
>  			err = ret;
>  			goto fail;
>  		} else if (ret) {
> +			f2fs_i_compr_wa_blocks_update(inode, ret - 1, true);
>  			return 0;
>  		}
>  	}
> diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
> index c01471573977..e6b943edba91 100644
> --- a/fs/f2fs/debug.c
> +++ b/fs/f2fs/debug.c
> @@ -136,6 +136,8 @@ static void update_general_status(struct f2fs_sb_info *sbi)
>  	si->inline_dir = atomic_read(&sbi->inline_dir);
>  	si->compr_inode = atomic_read(&sbi->compr_inode);
>  	si->compr_blocks = atomic64_read(&sbi->compr_blocks);
> +	si->compr_wa_blocks = atomic64_read(&sbi->compr_wa_blocks);
> +	si->compr_ra_blocks = atomic64_read(&sbi->compr_ra_blocks);
>  	si->append = sbi->im[APPEND_INO].ino_num;
>  	si->update = sbi->im[UPDATE_INO].ino_num;
>  	si->orphans = sbi->im[ORPHAN_INO].ino_num;
> @@ -383,8 +385,9 @@ static int stat_show(struct seq_file *s, void *v)
>  			   si->inline_inode);
>  		seq_printf(s, "  - Inline_dentry Inode: %u\n",
>  			   si->inline_dir);
> -		seq_printf(s, "  - Compressed Inode: %u, Blocks: %llu\n",
> -			   si->compr_inode, si->compr_blocks);
> +		seq_printf(s, "  - Compressed Inode: %u, Blocks: %llu, WA Blocks: %lld, RA Blocks %lld\n",
> +			   si->compr_inode, si->compr_blocks,
> +			   si->compr_wa_blocks, si->compr_ra_blocks);
>  		seq_printf(s, "  - Orphan/Append/Update Inode: %u, %u, %u\n",
>  			   si->orphans, si->append, si->update);
>  		seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 955dbf4f83ad..c549be2e75af 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1761,6 +1761,8 @@ struct f2fs_sb_info {
>  	atomic_t inline_dir;			/* # of inline_dentry inodes */
>  	atomic_t compr_inode;			/* # of compressed inodes */
>  	atomic64_t compr_blocks;		/* # of compressed blocks */
> +	atomic64_t compr_wa_blocks;		/* # of compressed WA blocks */
> +	atomic64_t compr_ra_blocks;		/* # of compressed RA blocks */
>  	atomic_t max_aw_cnt;			/* max # of atomic writes */
>  	unsigned int io_skip_bggc;		/* skip background gc for in-flight IO */
>  	unsigned int other_skip_bggc;		/* skip background gc for other reasons */
> @@ -3859,6 +3861,8 @@ struct f2fs_stat_info {
>  	int inline_xattr, inline_inode, inline_dir, append, update, orphans;
>  	int compr_inode;
>  	unsigned long long compr_blocks;
> +	long long compr_wa_blocks;
> +	long long compr_ra_blocks;
>  	int aw_cnt, max_aw_cnt;
>  	unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;
>  	unsigned int bimodal, avg_vblocks;
> @@ -3946,6 +3950,14 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
>  		(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_blocks))
>  #define stat_sub_compr_blocks(inode, blocks)				\
>  		(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_blocks))
> +#define stat_add_compr_wa_blocks(inode, blocks)				\
> +	(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_wa_blocks))
> +#define stat_sub_compr_wa_blocks(inode, blocks)				\
> +	(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_wa_blocks))
> +#define stat_add_compr_ra_blocks(inode, blocks)				\
> +	(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_ra_blocks))
> +#define stat_sub_compr_ra_blocks(inode, blocks)				\
> +	(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_ra_blocks))
>  #define stat_inc_meta_count(sbi, blkaddr)				\
>  	do {								\
>  		if (blkaddr < SIT_I(sbi)->sit_base_addr)		\
> @@ -4030,6 +4042,10 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
>  #define stat_dec_compr_inode(inode)			do { } while (0)
>  #define stat_add_compr_blocks(inode, blocks)		do { } while (0)
>  #define stat_sub_compr_blocks(inode, blocks)		do { } while (0)
> +#define stat_add_compr_wa_blocks(inode, blocks)		do { } while (0)
> +#define stat_sub_compr_wa_blocks(inode, blocks)		do { } while (0)
> +#define stat_add_compr_ra_blocks(inode, blocks)		do { } while (0)
> +#define stat_sub_compr_ra_blocks(inode, blocks)		do { } while (0)
>  #define stat_update_max_atomic_write(inode)		do { } while (0)
>  #define stat_inc_meta_count(sbi, blkaddr)		do { } while (0)
>  #define stat_inc_seg_type(sbi, curseg)			do { } while (0)
> @@ -4209,7 +4225,7 @@ void f2fs_update_extent_tree_range_compressed(struct inode *inode,
>  				unsigned int c_len);
>  int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>  				unsigned nr_pages, sector_t *last_block_in_bio,
> -				bool is_readahead, bool for_write);
> +				bool is_readahead, bool for_write, int *nr_need_read);
>  struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
>  void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
>  				bool in_task);
> @@ -4465,6 +4481,24 @@ static inline void f2fs_i_compr_blocks_update(struct inode *inode,
>  	f2fs_mark_inode_dirty_sync(inode, true);
>  }
>  
> +static inline void f2fs_i_compr_wa_blocks_update(struct inode *inode,
> +						u64 blocks, bool add)
> +{
> +	if (add)
> +		stat_add_compr_wa_blocks(inode, blocks);
> +	else
> +		stat_sub_compr_wa_blocks(inode, blocks);
> +}
> +
> +static inline void f2fs_i_compr_ra_blocks_update(struct inode *inode,
> +						u64 blocks, bool add)
> +{
> +	if (add)
> +		stat_add_compr_ra_blocks(inode, blocks);
> +	else
> +		stat_sub_compr_ra_blocks(inode, blocks);
> +}
> +
>  static inline int block_unaligned_IO(struct inode *inode,
>  				struct kiocb *iocb, struct iov_iter *iter)
>  {
> -- 
> 2.25.1


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [f2fs-dev] [PATCH v4 1/3] f2fs: intorduce f2fs_all_cluster_page_ready
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 1/3] f2fs: intorduce f2fs_all_cluster_page_ready Fengnan Chang
@ 2022-08-04 14:00   ` Chao Yu
  0 siblings, 0 replies; 8+ messages in thread
From: Chao Yu @ 2022-08-04 14:00 UTC (permalink / raw)
  To: Fengnan Chang, jaegeuk; +Cc: Fengnan Chang, linux-f2fs-devel

On 2022/7/31 11:33, Fengnan Chang wrote:
> From: Fengnan Chang <changfengnan@vivo.com>
> 
> When write total cluster, all pages is uptodate, there is not need to call
> f2fs_prepare_compress_overwrite, intorduce f2fs_all_cluster_page_ready
> to avoid this.
> 
> Signed-off-by: Fengnan Chang <changfengnan@vivo.com>

Reviewed-by: Chao Yu <chao@kernel.org>

Thanks,


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [f2fs-dev] [PATCH v4 2/3] f2fs: use onstack pages instead of pvec
  2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 2/3] f2fs: use onstack pages instead of pvec Fengnan Chang
@ 2022-08-04 14:01   ` Chao Yu
  0 siblings, 0 replies; 8+ messages in thread
From: Chao Yu @ 2022-08-04 14:01 UTC (permalink / raw)
  To: Fengnan Chang, jaegeuk; +Cc: linux-f2fs-devel

On 2022/7/31 11:33, Fengnan Chang wrote:
> Since pvec have 15 pages, it not a multiple of 4, when write compressed
> pages, write in 64K as a unit, it will call pagevec_lookup_range_tag
> agagin, sometimes this will take a lot of time.
> Use onstack pages instead of pvec to mitigate this problem.
> 
> Signed-off-by: Fengnan Chang <fengnanchang@gmail.com>

Reviewed-by: Chao Yu <chao@kernel.org>

Thanks,


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [f2fs-dev] [PATCH v4 3/3] f2fs: support compressed file write/read amplifiction
  2022-08-04  3:52   ` Jaegeuk Kim
@ 2022-08-06  4:35     ` fengnan chang
  0 siblings, 0 replies; 8+ messages in thread
From: fengnan chang @ 2022-08-06  4:35 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-f2fs-devel



> 2022年8月4日 11:52,Jaegeuk Kim <jaegeuk@kernel.org> 写道:
> 
> I feel that this adds lots of codes only for accounting purpose. Can we
> discuss why we need to know WA? If it's for debugging purpose, can we
> debug by tracepoints?

In my system, I enable compression for some type of files, such as txt file.
Some of them may rewrite, I want to figure out the compress policy will cause
WA or not, so that I can adjust compress policy.
As you know, overwrite part of compress cluster may cause WA, it’s related
to the compression ratio of the file. when the contents of file changed, the
compression ratio also changed.
I used to use trace way to account this, it's quite difficult to calculate.


> 
> On 07/31, Fengnan Chang wrote:
>> Try to support compressed file write and amplifiction accounting.
>> 
>> Signed-off-by: Fengnan Chang <fengnanchang@gmail.com>
>> ---
>> fs/f2fs/compress.c |  7 +++++--
>> fs/f2fs/data.c     | 44 ++++++++++++++++++++++++++++++++++++--------
>> fs/f2fs/debug.c    |  7 +++++--
>> fs/f2fs/f2fs.h     | 36 +++++++++++++++++++++++++++++++++++-
>> 4 files changed, 81 insertions(+), 13 deletions(-)
>> 
>> diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
>> index 0eca4e060deb..374d4a73ab2c 100644
>> --- a/fs/f2fs/compress.c
>> +++ b/fs/f2fs/compress.c
>> @@ -1125,7 +1125,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
>> 	sector_t last_block_in_bio;
>> 	unsigned fgp_flag = FGP_LOCK | FGP_WRITE | FGP_CREAT;
>> 	pgoff_t start_idx = start_idx_of_cluster(cc);
>> -	int i, ret;
>> +	int i, ret, once_read = 0;
>> 
>> retry:
>> 	ret = f2fs_is_compressed_cluster(cc->inode, start_idx);
>> @@ -1155,13 +1155,16 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
>> 		struct bio *bio = NULL;
>> 
>> 		ret = f2fs_read_multi_pages(cc, &bio, cc->cluster_size,
>> -					&last_block_in_bio, false, true);
>> +					&last_block_in_bio, false, true, &once_read);
>> 		f2fs_put_rpages(cc);
>> 		f2fs_destroy_compress_ctx(cc, true);
>> 		if (ret)
>> 			goto out;
>> 		if (bio)
>> 			f2fs_submit_bio(sbi, bio, DATA);
>> +		/* All need read page in here is read amplification */
>> +		if (once_read)
>> +			f2fs_i_compr_ra_blocks_update(cc->inode, once_read, true);
>> 
>> 		ret = f2fs_init_compress_ctx(cc);
>> 		if (ret)
>> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>> index 0b159c555069..9bedcea189eb 100644
>> --- a/fs/f2fs/data.c
>> +++ b/fs/f2fs/data.c
>> @@ -2133,7 +2133,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
>> #ifdef CONFIG_F2FS_FS_COMPRESSION
>> int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>> 				unsigned nr_pages, sector_t *last_block_in_bio,
>> -				bool is_readahead, bool for_write)
>> +				bool is_readahead, bool for_write, int *nr_need_read)
>> {
>> 	struct dnode_of_data dn;
>> 	struct inode *inode = cc->inode;
>> @@ -2146,7 +2146,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>> 	struct extent_info ei = {0, };
>> 	bool from_dnode = true;
>> 	int i;
>> -	int ret = 0;
>> +	int ret = 0, nr_cache_hit = 0;
>> +
>> +	if (nr_need_read)
>> +		*nr_need_read = 0;
>> 
>> 	f2fs_bug_on(sbi, f2fs_cluster_is_empty(cc));
>> 
>> @@ -2237,6 +2240,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>> 		if (f2fs_load_compressed_page(sbi, page, blkaddr)) {
>> 			if (atomic_dec_and_test(&dic->remaining_pages))
>> 				f2fs_decompress_cluster(dic, true);
>> +			nr_cache_hit++;
>> 			continue;
>> 		}
>> 
>> @@ -2275,6 +2279,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>> 		*last_block_in_bio = blkaddr;
>> 	}
>> 
>> +	/* we need read whole cluster when nr_cache_hit less than nr_cpages */
>> +	if (nr_need_read && nr_cache_hit < cc->nr_cpages)
>> +		*nr_need_read = cc->nr_cpages;
>> +
>> 	if (from_dnode)
>> 		f2fs_put_dnode(&dn);
>> 
>> @@ -2322,7 +2330,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
>> #endif
>> 	unsigned nr_pages = rac ? readahead_count(rac) : 1;
>> 	unsigned max_nr_pages = nr_pages;
>> -	int ret = 0;
>> +	int ret = 0, once_read = 0, total_read = 0, single_read = 0;
>> 
>> 	map.m_pblk = 0;
>> 	map.m_lblk = 0;
>> @@ -2346,10 +2354,11 @@ static int f2fs_mpage_readpages(struct inode *inode,
>> 				ret = f2fs_read_multi_pages(&cc, &bio,
>> 							max_nr_pages,
>> 							&last_block_in_bio,
>> -							rac != NULL, false);
>> +							rac != NULL, false, &once_read);
>> 				f2fs_destroy_compress_ctx(&cc, false);
>> 				if (ret)
>> 					goto set_error_page;
>> +				total_read += once_read;
>> 			}
>> 			if (cc.cluster_idx == NULL_CLUSTER) {
>> 				if (nc_cluster_idx ==
>> @@ -2389,6 +2398,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
>> 			zero_user_segment(page, 0, PAGE_SIZE);
>> 			unlock_page(page);
>> 		}
>> +		single_read++;
>> #ifdef CONFIG_F2FS_FS_COMPRESSION
>> next_page:
>> #endif
>> @@ -2402,12 +2412,23 @@ static int f2fs_mpage_readpages(struct inode *inode,
>> 				ret = f2fs_read_multi_pages(&cc, &bio,
>> 							max_nr_pages,
>> 							&last_block_in_bio,
>> -							rac != NULL, false);
>> +							rac != NULL, false, &once_read);
>> 				f2fs_destroy_compress_ctx(&cc, false);
>> +				if (!ret)
>> +					total_read += once_read;
>> 			}
>> 		}
>> #endif
>> 	}
>> +	max_nr_pages -= single_read;
>> +	if (total_read > max_nr_pages)
>> +		f2fs_i_compr_ra_blocks_update(inode,
>> +						total_read - max_nr_pages,
>> +						true);
>> +	else
>> +		f2fs_i_compr_ra_blocks_update(inode,
>> +						max_nr_pages - total_read,
>> +						false);
>> 	if (bio)
>> 		__submit_bio(F2FS_I_SB(inode), bio, DATA);
>> 	return ret;
>> @@ -2944,11 +2965,11 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
>> 	int range_whole = 0;
>> 	xa_mark_t tag;
>> 	int nwritten = 0;
>> -	int submitted = 0;
>> +	int submitted = 0, raw_dirty_pages = 0;
>> 	int i;
>> 
>> -	if (get_dirty_pages(mapping->host) <=
>> -				SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
>> +	raw_dirty_pages = get_dirty_pages(mapping->host);
>> +	if (raw_dirty_pages <= SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
>> 		set_inode_flag(mapping->host, FI_HOT_DATA);
>> 	else
>> 		clear_inode_flag(mapping->host, FI_HOT_DATA);
>> @@ -3148,6 +3169,12 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
>> 	if (bio)
>> 		f2fs_submit_merged_ipu_write(sbi, &bio, NULL);
>> 
>> +	if (f2fs_compressed_file(inode)) {
>> +		if (nwritten > raw_dirty_pages)
>> +			f2fs_i_compr_wa_blocks_update(inode, nwritten - raw_dirty_pages, true);
>> +		else
>> +			f2fs_i_compr_wa_blocks_update(inode, raw_dirty_pages - nwritten, false);
>> +	}
>> 	return ret;
>> }
>> 
>> @@ -3498,6 +3525,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
>> 			err = ret;
>> 			goto fail;
>> 		} else if (ret) {
>> +			f2fs_i_compr_wa_blocks_update(inode, ret - 1, true);
>> 			return 0;
>> 		}
>> 	}
>> diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
>> index c01471573977..e6b943edba91 100644
>> --- a/fs/f2fs/debug.c
>> +++ b/fs/f2fs/debug.c
>> @@ -136,6 +136,8 @@ static void update_general_status(struct f2fs_sb_info *sbi)
>> 	si->inline_dir = atomic_read(&sbi->inline_dir);
>> 	si->compr_inode = atomic_read(&sbi->compr_inode);
>> 	si->compr_blocks = atomic64_read(&sbi->compr_blocks);
>> +	si->compr_wa_blocks = atomic64_read(&sbi->compr_wa_blocks);
>> +	si->compr_ra_blocks = atomic64_read(&sbi->compr_ra_blocks);
>> 	si->append = sbi->im[APPEND_INO].ino_num;
>> 	si->update = sbi->im[UPDATE_INO].ino_num;
>> 	si->orphans = sbi->im[ORPHAN_INO].ino_num;
>> @@ -383,8 +385,9 @@ static int stat_show(struct seq_file *s, void *v)
>> 			   si->inline_inode);
>> 		seq_printf(s, "  - Inline_dentry Inode: %u\n",
>> 			   si->inline_dir);
>> -		seq_printf(s, "  - Compressed Inode: %u, Blocks: %llu\n",
>> -			   si->compr_inode, si->compr_blocks);
>> +		seq_printf(s, "  - Compressed Inode: %u, Blocks: %llu, WA Blocks: %lld, RA Blocks %lld\n",
>> +			   si->compr_inode, si->compr_blocks,
>> +			   si->compr_wa_blocks, si->compr_ra_blocks);
>> 		seq_printf(s, "  - Orphan/Append/Update Inode: %u, %u, %u\n",
>> 			   si->orphans, si->append, si->update);
>> 		seq_printf(s, "\nMain area: %d segs, %d secs %d zones\n",
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index 955dbf4f83ad..c549be2e75af 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -1761,6 +1761,8 @@ struct f2fs_sb_info {
>> 	atomic_t inline_dir;			/* # of inline_dentry inodes */
>> 	atomic_t compr_inode;			/* # of compressed inodes */
>> 	atomic64_t compr_blocks;		/* # of compressed blocks */
>> +	atomic64_t compr_wa_blocks;		/* # of compressed WA blocks */
>> +	atomic64_t compr_ra_blocks;		/* # of compressed RA blocks */
>> 	atomic_t max_aw_cnt;			/* max # of atomic writes */
>> 	unsigned int io_skip_bggc;		/* skip background gc for in-flight IO */
>> 	unsigned int other_skip_bggc;		/* skip background gc for other reasons */
>> @@ -3859,6 +3861,8 @@ struct f2fs_stat_info {
>> 	int inline_xattr, inline_inode, inline_dir, append, update, orphans;
>> 	int compr_inode;
>> 	unsigned long long compr_blocks;
>> +	long long compr_wa_blocks;
>> +	long long compr_ra_blocks;
>> 	int aw_cnt, max_aw_cnt;
>> 	unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;
>> 	unsigned int bimodal, avg_vblocks;
>> @@ -3946,6 +3950,14 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
>> 		(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_blocks))
>> #define stat_sub_compr_blocks(inode, blocks)				\
>> 		(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_blocks))
>> +#define stat_add_compr_wa_blocks(inode, blocks)				\
>> +	(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_wa_blocks))
>> +#define stat_sub_compr_wa_blocks(inode, blocks)				\
>> +	(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_wa_blocks))
>> +#define stat_add_compr_ra_blocks(inode, blocks)				\
>> +	(atomic64_add(blocks, &F2FS_I_SB(inode)->compr_ra_blocks))
>> +#define stat_sub_compr_ra_blocks(inode, blocks)				\
>> +	(atomic64_sub(blocks, &F2FS_I_SB(inode)->compr_ra_blocks))
>> #define stat_inc_meta_count(sbi, blkaddr)				\
>> 	do {								\
>> 		if (blkaddr < SIT_I(sbi)->sit_base_addr)		\
>> @@ -4030,6 +4042,10 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
>> #define stat_dec_compr_inode(inode)			do { } while (0)
>> #define stat_add_compr_blocks(inode, blocks)		do { } while (0)
>> #define stat_sub_compr_blocks(inode, blocks)		do { } while (0)
>> +#define stat_add_compr_wa_blocks(inode, blocks)		do { } while (0)
>> +#define stat_sub_compr_wa_blocks(inode, blocks)		do { } while (0)
>> +#define stat_add_compr_ra_blocks(inode, blocks)		do { } while (0)
>> +#define stat_sub_compr_ra_blocks(inode, blocks)		do { } while (0)
>> #define stat_update_max_atomic_write(inode)		do { } while (0)
>> #define stat_inc_meta_count(sbi, blkaddr)		do { } while (0)
>> #define stat_inc_seg_type(sbi, curseg)			do { } while (0)
>> @@ -4209,7 +4225,7 @@ void f2fs_update_extent_tree_range_compressed(struct inode *inode,
>> 				unsigned int c_len);
>> int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
>> 				unsigned nr_pages, sector_t *last_block_in_bio,
>> -				bool is_readahead, bool for_write);
>> +				bool is_readahead, bool for_write, int *nr_need_read);
>> struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
>> void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
>> 				bool in_task);
>> @@ -4465,6 +4481,24 @@ static inline void f2fs_i_compr_blocks_update(struct inode *inode,
>> 	f2fs_mark_inode_dirty_sync(inode, true);
>> }
>> 
>> +static inline void f2fs_i_compr_wa_blocks_update(struct inode *inode,
>> +						u64 blocks, bool add)
>> +{
>> +	if (add)
>> +		stat_add_compr_wa_blocks(inode, blocks);
>> +	else
>> +		stat_sub_compr_wa_blocks(inode, blocks);
>> +}
>> +
>> +static inline void f2fs_i_compr_ra_blocks_update(struct inode *inode,
>> +						u64 blocks, bool add)
>> +{
>> +	if (add)
>> +		stat_add_compr_ra_blocks(inode, blocks);
>> +	else
>> +		stat_sub_compr_ra_blocks(inode, blocks);
>> +}
>> +
>> static inline int block_unaligned_IO(struct inode *inode,
>> 				struct kiocb *iocb, struct iov_iter *iter)
>> {
>> -- 
>> 2.25.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-08-06  4:36 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-31  3:33 [f2fs-dev] [PATCH v4 0/3] support compressed file write/read amplifiction Fengnan Chang
2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 1/3] f2fs: intorduce f2fs_all_cluster_page_ready Fengnan Chang
2022-08-04 14:00   ` Chao Yu
2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 2/3] f2fs: use onstack pages instead of pvec Fengnan Chang
2022-08-04 14:01   ` Chao Yu
2022-07-31  3:33 ` [f2fs-dev] [PATCH v4 3/3] f2fs: support compressed file write/read amplifiction Fengnan Chang
2022-08-04  3:52   ` Jaegeuk Kim
2022-08-06  4:35     ` fengnan chang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).