Signed-off-by: qixiaoyu1 <qixiao...@xiaomi.com>
Signed-off-by: xiongping1 <xiongpi...@xiaomi.com>
---
 Documentation/ABI/testing/sysfs-fs-f2fs | 14 ++++++++++++
 fs/f2fs/block_age.c                     | 29 +++++++++++++++++++++++++
 fs/f2fs/f2fs.h                          |  4 ++++
 fs/f2fs/segment.c                       |  9 ++++++++
 fs/f2fs/sysfs.c                         | 28 ++++++++++++++++++++++++
 include/trace/events/f2fs.h             |  2 +-
 6 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs 
b/Documentation/ABI/testing/sysfs-fs-f2fs
index 483639fb727b..34952666b2fe 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -634,3 +634,17 @@ Date:              July 2022
 Contact:       "Daeho Jeong" <daehoje...@google.com>
 Description:   Show the accumulated total revoked atomic write block count 
after boot.
                If you write "0" here, you can initialize to "0".
+
+What:          /sys/fs/f2fs/<disk>/hot_data_age_threshold
+Date:          November 2022
+Contact:       "Ping Xiong" <xiongpi...@xiaomi.com>
+Description:   When DATA SEPARATION is on, it controls the age threshold to 
indicate
+               the data blocks as hot. By default it was initialized as 262144 
blocks
+               (equals to 1GB).
+
+What:          /sys/fs/f2fs/<disk>/warm_data_age_threshold
+Date:          November 2022
+Contact:       "Ping Xiong" <xiongpi...@xiaomi.com>
+Description:   When DATA SEPARATION is on, it controls the age threshold to 
indicate
+               the data blocks as warm. By default it was initialized as 
2621440 blocks
+               (equals to 10GB).
diff --git a/fs/f2fs/block_age.c b/fs/f2fs/block_age.c
index 488461b3f4bf..d0b578544df7 100644
--- a/fs/f2fs/block_age.c
+++ b/fs/f2fs/block_age.c
@@ -17,6 +17,13 @@
 #define LAST_AGE_WEIGHT                30
 #define SAME_AGE_REGION                1024
 
+/*
+ * Define data block with age less than 1GB as hot data
+ * define data block with age less than 10GB but more than 1GB as warm data
+ */
+#define DEF_HOT_DATA_AGE_THRESHOLD     262144
+#define DEF_WARM_DATA_AGE_THRESHOLD    2621440
+
 static struct kmem_cache *age_extent_tree_slab;
 static struct kmem_cache *age_extent_node_slab;
 
@@ -29,6 +36,9 @@ static inline void f2fs_inc_data_block_alloc(struct 
f2fs_sb_info *sbi)
 static void f2fs_init_block_age_info(struct f2fs_sb_info *sbi)
 {
        atomic64_set(&sbi->total_data_alloc, 0);
+
+       sbi->hot_data_age_threshold = DEF_HOT_DATA_AGE_THRESHOLD;
+       sbi->warm_data_age_threshold = DEF_WARM_DATA_AGE_THRESHOLD;
 }
 
 static inline bool f2fs_may_age_extent_tree(struct inode *inode)
@@ -697,6 +707,25 @@ unsigned long f2fs_count_age_extent_cache(struct 
f2fs_sb_info *sbi)
                                atomic_read(&sbi->total_age_ext_node);
 }
 
+int f2fs_get_data_segment_type(struct inode *inode, pgoff_t pgofs)
+{
+       struct age_extent_info ei;
+       struct f2fs_sb_info *sbi =  F2FS_I_SB(inode);
+
+       if (f2fs_lookup_age_extent_cache(inode, pgofs, &ei)) {
+               if (ei.age != 0) {
+                       if (ei.age <= sbi->hot_data_age_threshold)
+                               return CURSEG_HOT_DATA;
+                       else if (ei.age <= sbi->warm_data_age_threshold)
+                               return CURSEG_WARM_DATA;
+                       else
+                               return CURSEG_COLD_DATA;
+               }
+       }
+
+       return NO_CHECK_TYPE;
+}
+
 void f2fs_destroy_age_extent_cache(void)
 {
        kmem_cache_destroy(age_extent_node_slab);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 23516498b6d0..50f6f21b23bf 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1854,6 +1854,9 @@ struct f2fs_sb_info {
 
 #ifdef CONFIG_F2FS_FS_DATA_SEPARATION
        atomic64_t total_data_alloc;
+       /* The threshold used for hot and warm data seperation*/
+       unsigned int hot_data_age_threshold;
+       unsigned int warm_data_age_threshold;
 #endif
 
        /* Reference to checksum algorithm driver via cryptoapi */
@@ -4241,6 +4244,7 @@ void f2fs_update_age_extent_cache(struct inode *inode, 
pgoff_t fofs,
 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 f2fs_get_data_segment_type(struct inode *inode, pgoff_t pgofs);
 int __init f2fs_create_age_extent_cache(void);
 void f2fs_destroy_age_extent_cache(void);
 #endif
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index d4c338f332fa..2fa5b22119ac 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3163,6 +3163,9 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
        if (fio->type == DATA) {
                struct inode *inode = fio->page->mapping->host;
 
+#ifdef CONFIG_F2FS_FS_DATA_SEPARATION
+               int type;
+#endif
                if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
                        return CURSEG_COLD_DATA_PINNED;
 
@@ -3176,6 +3179,12 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
                }
                if (file_is_cold(inode) || f2fs_need_compress_data(inode))
                        return CURSEG_COLD_DATA;
+
+#ifdef CONFIG_F2FS_FS_DATA_SEPARATION
+               type = f2fs_get_data_segment_type(inode, fio->page->index);
+               if (type != NO_CHECK_TYPE)
+                       return type;
+#endif
                if (file_is_hot(inode) ||
                                is_inode_flag_set(inode, FI_HOT_DATA) ||
                                f2fs_is_cow_file(inode))
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index df27afd71ef4..68ba8c1c2cb3 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -648,6 +648,25 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
                sbi->revoked_atomic_block = 0;
                return count;
        }
+#ifdef CONFIG_F2FS_FS_DATA_SEPARATION
+       if (!strcmp(a->attr.name, "hot_data_age_threshold")) {
+               if (t == 0 || t >= sbi->warm_data_age_threshold)
+                       return -EINVAL;
+               if (t == *ui)
+                       return count;
+               *ui = (unsigned int)t;
+               return count;
+       }
+
+       if (!strcmp(a->attr.name, "warm_data_age_threshold")) {
+               if (t == 0 || t <= sbi->hot_data_age_threshold)
+                       return -EINVAL;
+               if (t == *ui)
+                       return count;
+               *ui = (unsigned int)t;
+               return count;
+       }
+#endif
 
        *ui = (unsigned int)t;
 
@@ -902,6 +921,11 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, peak_atomic_write, 
peak_atomic_write);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, committed_atomic_block, 
committed_atomic_block);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, revoked_atomic_block, 
revoked_atomic_block);
 
+#ifdef CONFIG_F2FS_FS_DATA_SEPARATION
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, hot_data_age_threshold, 
hot_data_age_threshold);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, warm_data_age_threshold, 
warm_data_age_threshold);
+#endif
+
 #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
 static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(gc_urgent_sleep_time),
@@ -995,6 +1019,10 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(peak_atomic_write),
        ATTR_LIST(committed_atomic_block),
        ATTR_LIST(revoked_atomic_block),
+#ifdef CONFIG_F2FS_FS_DATA_SEPARATION
+       ATTR_LIST(hot_data_age_threshold),
+       ATTR_LIST(warm_data_age_threshold),
+#endif
        NULL,
 };
 ATTRIBUTE_GROUPS(f2fs);
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index b19c057ff801..0adb26397e68 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -1692,7 +1692,7 @@ DECLARE_EVENT_CLASS(f2fs_add_age_extent_node,
                __entry->blocks = ei->last_blocks;
        ),
 
-       TP_printk("dev = (%d,%d), ino = %lu, node_cnt = %lu, "
+       TP_printk("dev = (%d,%d), ino = %lu, node_cnt = %u, "
                "age_ext_info(fofs: %u, len: %u, age: %llu, blocks: %llu)",
                show_dev_ino(__entry),
                __entry->cnt,
-- 
2.36.1



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

Reply via email to