linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: qixiaoyu1 <qxy65535@gmail.com>
To: Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <chao@kernel.org>
Cc: linux-kernel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net,
	qixiaoyu1 <qixiaoyu1@xiaomi.com>,
	xiongping1 <xiongping1@xiaomi.com>
Subject: [PATCH 4/5] f2fs: update block age info during out of place update
Date: Mon, 28 Nov 2022 16:58:58 +0800	[thread overview]
Message-ID: <20221128085859.5295-5-qixiaoyu1@xiaomi.com> (raw)
In-Reply-To: <20221128085859.5295-1-qixiaoyu1@xiaomi.com>

Signed-off-by: qixiaoyu1 <qixiaoyu1@xiaomi.com>
Signed-off-by: xiongping1 <xiongping1@xiaomi.com>
---
 fs/f2fs/block_age.c | 89 ++++++++++++++++++++++++++++++++++++++++++++-
 fs/f2fs/f2fs.h      |  1 +
 fs/f2fs/segment.c   |  4 ++
 3 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/block_age.c b/fs/f2fs/block_age.c
index bc009616adfb..488461b3f4bf 100644
--- a/fs/f2fs/block_age.c
+++ b/fs/f2fs/block_age.c
@@ -9,9 +9,14 @@
 #include <linux/f2fs_fs.h>
 
 #include "f2fs.h"
+#include "node.h"
 #include "segment.h"
 #include <trace/events/f2fs.h>
 
+
+#define LAST_AGE_WEIGHT		30
+#define SAME_AGE_REGION		1024
+
 static struct kmem_cache *age_extent_tree_slab;
 static struct kmem_cache *age_extent_node_slab;
 
@@ -264,8 +269,8 @@ static inline bool __is_age_extent_mergeable(struct age_extent_info *back,
 						struct age_extent_info *front)
 {
 	return (back->fofs + back->len == front->fofs &&
-			back->age == front->age &&
-			back->last_blocks == front->last_blocks);
+			abs(back->age - front->age) <= SAME_AGE_REGION &&
+			abs(back->last_blocks - front->last_blocks) <= SAME_AGE_REGION);
 }
 
 static inline bool __is_back_age_ext_mergeable(struct age_extent_info *cur,
@@ -497,6 +502,86 @@ void f2fs_truncate_age_extent_cache(struct inode *inode, pgoff_t fofs, unsigned
 	f2fs_update_age_extent_cache(inode, fofs, len, 0, 0);
 }
 
+unsigned long long f2fs_get_cur_dblock_allocated(struct f2fs_sb_info *sbi)
+{
+	return atomic64_read(&sbi->total_data_alloc);
+}
+
+static unsigned long long calculate_block_age(unsigned long long new,
+							unsigned long long old)
+{
+	if (new >= old)
+		return new - (new - old) * LAST_AGE_WEIGHT / 100;
+	else
+		return new + (old - new) * LAST_AGE_WEIGHT / 100;
+}
+
+void f2fs_update_data_block_age(struct dnode_of_data *dn)
+{
+	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
+	unsigned long long cur_total_blk_alloced = f2fs_get_cur_dblock_allocated(sbi);
+	pgoff_t fofs;
+	unsigned long long cur_age, new_age;
+	struct age_extent_info ei;
+	bool find;
+	loff_t f_size = i_size_read(dn->inode);
+
+	if (!f2fs_may_age_extent_tree(dn->inode))
+		return;
+
+	fofs = f2fs_start_bidx_of_node(ofs_of_node(dn->node_page), dn->inode) +
+								dn->ofs_in_node;
+
+
+	/* When I/O is not aligned to a PAGE_SIZE, update will happen to the last
+	 * file block even in seq write. So don't record age for newly last file
+	 * block here.
+	 */
+	if ((f_size >> PAGE_SHIFT) == fofs && f_size & (PAGE_SIZE - 1) &&
+			dn->data_blkaddr == NEW_ADDR)
+		return;
+
+	find = f2fs_lookup_age_extent_cache(dn->inode, fofs, &ei);
+	if (find) {
+		if (cur_total_blk_alloced >= ei.last_blocks)
+			cur_age = cur_total_blk_alloced - ei.last_blocks;
+		else
+			/* total_data_alloc overflow */
+			cur_age = ULLONG_MAX - ei.last_blocks + cur_total_blk_alloced;
+
+		if (ei.age)
+			new_age = calculate_block_age(cur_age, ei.age);
+		else
+			new_age = cur_age;
+
+		WARN(new_age > cur_total_blk_alloced,
+				"inode block(%lu: %lu) age changed from: %llu to %llu",
+				dn->inode->i_ino, fofs, ei.age, new_age);
+	} else {
+		f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR);
+
+		if (dn->data_blkaddr == NEW_ADDR)
+			/* the data block was allocated for the first time */
+			new_age = 0;
+		else {
+			if (__is_valid_data_blkaddr(dn->data_blkaddr) &&
+					!f2fs_is_valid_blkaddr(sbi, dn->data_blkaddr,
+								DATA_GENERIC_ENHANCE)) {
+				f2fs_bug_on(sbi, 1);
+				return;
+			}
+
+			/*
+			 * init block age with zero, this can happen when the block age extent
+			 * was reclaimed due to memory constraint or system reboot
+			 */
+			new_age = 0;
+		}
+	}
+
+	f2fs_update_age_extent_cache(dn->inode, fofs, 1, new_age, cur_total_blk_alloced);
+}
+
 void f2fs_destroy_age_extent_tree(struct inode *inode)
 {
 	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 428cc560b721..23516498b6d0 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4238,6 +4238,7 @@ bool f2fs_lookup_age_extent_cache(struct inode *inode, pgoff_t pgofs,
 void f2fs_update_age_extent_cache(struct inode *inode, pgoff_t fofs,
 					unsigned int len, u64 age,
 					unsigned long long cur_blk_alloced);
+void f2fs_update_data_block_age(struct dnode_of_data *dn);
 void f2fs_truncate_age_extent_cache(struct inode *inode, pgoff_t fofs,
 					unsigned int len);
 int __init f2fs_create_age_extent_cache(void);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b105d8418f77..d4c338f332fa 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3417,6 +3417,10 @@ void f2fs_outplace_write_data(struct dnode_of_data *dn,
 	struct f2fs_summary sum;
 
 	f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR);
+#ifdef CONFIG_F2FS_FS_DATA_SEPARATION
+	if (fio->io_type == FS_DATA_IO || fio->io_type == FS_CP_DATA_IO)
+		f2fs_update_data_block_age(dn);
+#endif
 	set_summary(&sum, dn->nid, dn->ofs_in_node, fio->version);
 	do_write_page(&sum, fio);
 	f2fs_update_data_blkaddr(dn, fio->new_blkaddr);
-- 
2.36.1


  parent reply	other threads:[~2022-11-28  9:06 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-28  8:58 [PATCH 0/5] Support enhanced hot/cold data separation for f2fs qixiaoyu1
2022-11-28  8:58 ` [PATCH 1/5] f2fs: record total data blocks allocated since mount qixiaoyu1
2022-11-29  2:51   ` Jaegeuk Kim
2022-12-05 19:04     ` [f2fs-dev] " Jaegeuk Kim
2022-11-28  8:58 ` [PATCH 2/5] f2fs: implement cache to manager block update frequency per inode qixiaoyu1
2022-11-28 10:44   ` kernel test robot
2022-11-28  8:58 ` [PATCH 3/5] f2fs: add age_extent_cache mount option qixiaoyu1
2022-11-28  8:58 ` qixiaoyu1 [this message]
2022-11-28 11:14   ` [PATCH 4/5] f2fs: update block age info during out of place update kernel test robot
2022-12-12  3:04   ` kernel test robot
2022-11-28  8:58 ` [PATCH 5/5] f2fs: implement data block seperation with block update frequency qixiaoyu1
2022-11-29  7:49 ` [PATCH] f2fs: Support enhanced hot/cold data separation for f2fs Yangtao Li

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=20221128085859.5295-5-qixiaoyu1@xiaomi.com \
    --to=qxy65535@gmail.com \
    --cc=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=qixiaoyu1@xiaomi.com \
    --cc=xiongping1@xiaomi.com \
    /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 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).