From: Greg Kroah-Hartman Date: Tue, 13 Aug 2024 13:23:29 +0000 (+0200) Subject: drop some unneeded 5.15 changes X-Git-Tag: v6.1.105~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=96134d0e3c7bbb9712e7f114b667d0c566a56fdb;p=thirdparty%2Fkernel%2Fstable-queue.git drop some unneeded 5.15 changes --- diff --git a/queue-5.15/f2fs-add-a-way-to-limit-roll-forward-recovery-time.patch b/queue-5.15/f2fs-add-a-way-to-limit-roll-forward-recovery-time.patch deleted file mode 100644 index 33fe3ad6ace..00000000000 --- a/queue-5.15/f2fs-add-a-way-to-limit-roll-forward-recovery-time.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 891520a1e9d657d51327e792f782dc5421ca1cd3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 27 Jan 2022 13:31:43 -0800 -Subject: f2fs: add a way to limit roll forward recovery time - -From: Jaegeuk Kim - -[ Upstream commit 47c8ebcce85ed7113e9e3e3f1d8c6374fa87848e ] - -This adds a sysfs entry to call checkpoint during fsync() in order to avoid -long elapsed time to run roll-forward recovery when booting the device. -Default value doesn't enforce the limitation which is same as before. - -Reviewed-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Stable-dep-of: f06c0f82e38b ("f2fs: fix to update user block counts in block_operations()") -Signed-off-by: Sasha Levin ---- - Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++++++ - fs/f2fs/checkpoint.c | 1 + - fs/f2fs/debug.c | 3 +++ - fs/f2fs/f2fs.h | 3 +++ - fs/f2fs/node.c | 2 ++ - fs/f2fs/node.h | 3 +++ - fs/f2fs/recovery.c | 4 ++++ - fs/f2fs/super.c | 14 ++++++++++++-- - fs/f2fs/sysfs.c | 2 ++ - 9 files changed, 36 insertions(+), 2 deletions(-) - -diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs -index bdbece0b08051..92bc2bdc8baf1 100644 ---- a/Documentation/ABI/testing/sysfs-fs-f2fs -+++ b/Documentation/ABI/testing/sysfs-fs-f2fs -@@ -536,3 +536,9 @@ Contact: "Daeho Jeong" - Description: You can set the trial count limit for GC urgent high mode with this value. - If GC thread gets to the limit, the mode will turn back to GC normal mode. - By default, the value is zero, which means there is no limit like before. -+ -+What: /sys/fs/f2fs//max_roll_forward_node_blocks -+Date: January 2022 -+Contact: "Jaegeuk Kim" -+Description: Controls max # of node block writes to be used for roll forward -+ recovery. This can limit the roll forward recovery time. -diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c -index 71a3714419f85..8d12e2fa32b8f 100644 ---- a/fs/f2fs/checkpoint.c -+++ b/fs/f2fs/checkpoint.c -@@ -1569,6 +1569,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) - /* update user_block_counts */ - sbi->last_valid_block_count = sbi->total_valid_block_count; - percpu_counter_set(&sbi->alloc_valid_block_count, 0); -+ percpu_counter_set(&sbi->rf_node_block_count, 0); - - /* Here, we have one bio having CP pack except cp pack 2 page */ - f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); -diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c -index b449c7a372a4b..6d26872c7364d 100644 ---- a/fs/f2fs/debug.c -+++ b/fs/f2fs/debug.c -@@ -534,6 +534,9 @@ static int stat_show(struct seq_file *s, void *v) - si->ndirty_meta, si->meta_pages); - seq_printf(s, " - imeta: %4d\n", - si->ndirty_imeta); -+ seq_printf(s, " - fsync mark: %4lld\n", -+ percpu_counter_sum_positive( -+ &si->sbi->rf_node_block_count)); - seq_printf(s, " - NATs: %9d/%9d\n - SITs: %9d/%9d\n", - si->dirty_nats, si->nats, si->dirty_sits, si->sits); - seq_printf(s, " - free_nids: %9d/%9d\n - alloc_nids: %9d\n", -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index d4a5700927cd5..fb1422a81d382 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -891,6 +891,7 @@ struct f2fs_nm_info { - nid_t max_nid; /* maximum possible node ids */ - nid_t available_nids; /* # of available node ids */ - nid_t next_scan_nid; /* the next nid to be scanned */ -+ nid_t max_rf_node_blocks; /* max # of nodes for recovery */ - unsigned int ram_thresh; /* control the memory footprint */ - unsigned int ra_nid_pages; /* # of nid pages to be readaheaded */ - unsigned int dirty_nats_ratio; /* control dirty nats ratio threshold */ -@@ -1663,6 +1664,8 @@ struct f2fs_sb_info { - atomic_t nr_pages[NR_COUNT_TYPE]; - /* # of allocated blocks */ - struct percpu_counter alloc_valid_block_count; -+ /* # of node block writes as roll forward recovery */ -+ struct percpu_counter rf_node_block_count; - - /* writeback control */ - atomic_t wb_sync_req[META]; /* count # of WB_SYNC threads */ -diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c -index b6758887540f2..16eab673ca84d 100644 ---- a/fs/f2fs/node.c -+++ b/fs/f2fs/node.c -@@ -1787,6 +1787,7 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, - - if (!atomic || page == last_page) { - set_fsync_mark(page, 1); -+ percpu_counter_inc(&sbi->rf_node_block_count); - if (IS_INODE(page)) { - if (is_inode_flag_set(inode, - FI_DIRTY_INODE)) -@@ -3227,6 +3228,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) - nm_i->ram_thresh = DEF_RAM_THRESHOLD; - nm_i->ra_nid_pages = DEF_RA_NID_PAGES; - nm_i->dirty_nats_ratio = DEF_DIRTY_NAT_RATIO_THRESHOLD; -+ nm_i->max_rf_node_blocks = DEF_RF_NODE_BLOCKS; - - INIT_RADIX_TREE(&nm_i->free_nid_root, GFP_ATOMIC); - INIT_LIST_HEAD(&nm_i->free_nid_list); -diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h -index ff14a6e5ac1c9..048f309e32ff4 100644 ---- a/fs/f2fs/node.h -+++ b/fs/f2fs/node.h -@@ -31,6 +31,9 @@ - /* control total # of nats */ - #define DEF_NAT_CACHE_THRESHOLD 100000 - -+/* control total # of node writes used for roll-fowrad recovery */ -+#define DEF_RF_NODE_BLOCKS 0 -+ - /* vector size for gang look-up from nat cache that consists of radix tree */ - #define NATVEC_SIZE 64 - #define SETVEC_SIZE 32 -diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c -index f07ae58d266d1..a5044be137988 100644 ---- a/fs/f2fs/recovery.c -+++ b/fs/f2fs/recovery.c -@@ -55,6 +55,10 @@ bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi) - - if (sbi->last_valid_block_count + nalloc > sbi->user_block_count) - return false; -+ if (NM_I(sbi)->max_rf_node_blocks && -+ percpu_counter_sum_positive(&sbi->rf_node_block_count) >= -+ NM_I(sbi)->max_rf_node_blocks) -+ return false; - return true; - } - -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 098daef550f49..144c35b2760f4 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -1540,8 +1540,9 @@ static void f2fs_free_inode(struct inode *inode) - - static void destroy_percpu_info(struct f2fs_sb_info *sbi) - { -- percpu_counter_destroy(&sbi->alloc_valid_block_count); - percpu_counter_destroy(&sbi->total_valid_inode_count); -+ percpu_counter_destroy(&sbi->rf_node_block_count); -+ percpu_counter_destroy(&sbi->alloc_valid_block_count); - } - - static void destroy_device_list(struct f2fs_sb_info *sbi) -@@ -3659,11 +3660,20 @@ static int init_percpu_info(struct f2fs_sb_info *sbi) - if (err) - return err; - -+ err = percpu_counter_init(&sbi->rf_node_block_count, 0, GFP_KERNEL); -+ if (err) -+ goto err_valid_block; -+ - err = percpu_counter_init(&sbi->total_valid_inode_count, 0, - GFP_KERNEL); - if (err) -- percpu_counter_destroy(&sbi->alloc_valid_block_count); -+ goto err_node_block; -+ return 0; - -+err_node_block: -+ percpu_counter_destroy(&sbi->rf_node_block_count); -+err_valid_block: -+ percpu_counter_destroy(&sbi->alloc_valid_block_count); - return err; - } - -diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c -index 673b1153dbc67..5bccd70a3f3be 100644 ---- a/fs/f2fs/sysfs.c -+++ b/fs/f2fs/sysfs.c -@@ -720,6 +720,7 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections); - F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); - F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); - F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio); -+F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, max_roll_forward_node_blocks, max_rf_node_blocks); - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search); - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, migration_granularity, migration_granularity); - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level); -@@ -837,6 +838,7 @@ static struct attribute *f2fs_attrs[] = { - ATTR_LIST(ram_thresh), - ATTR_LIST(ra_nid_pages), - ATTR_LIST(dirty_nats_ratio), -+ ATTR_LIST(max_roll_forward_node_blocks), - ATTR_LIST(cp_interval), - ATTR_LIST(idle_interval), - ATTR_LIST(discard_idle_interval), --- -2.43.0 - diff --git a/queue-5.15/f2fs-add-gc_urgent_high_remaining-sysfs-node.patch b/queue-5.15/f2fs-add-gc_urgent_high_remaining-sysfs-node.patch deleted file mode 100644 index 0bede465b76..00000000000 --- a/queue-5.15/f2fs-add-gc_urgent_high_remaining-sysfs-node.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 6d0fb871dbe1cd210304a6833e845a4f1c5cfb27 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 8 Dec 2021 16:41:51 -0800 -Subject: f2fs: add gc_urgent_high_remaining sysfs node - -From: Daeho Jeong - -[ Upstream commit 325163e9892b627fc9fb1af51e51f0f95dded517 ] - -Added a new sysfs node called gc_urgent_high_remaining. The user can -set the trial count limit for GC urgent high mode with this value. If -GC thread gets to the limit, the mode will turn back to GC normal mode. -By default, the value is zero, which means there is no limit like before. - -Signed-off-by: Daeho Jeong -Signed-off-by: Jaegeuk Kim -Stable-dep-of: f06c0f82e38b ("f2fs: fix to update user block counts in block_operations()") -Signed-off-by: Sasha Levin ---- - Documentation/ABI/testing/sysfs-fs-f2fs | 7 +++++++ - fs/f2fs/f2fs.h | 3 +++ - fs/f2fs/gc.c | 12 ++++++++++++ - fs/f2fs/super.c | 1 + - fs/f2fs/sysfs.c | 11 +++++++++++ - 5 files changed, 34 insertions(+) - -diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs -index 91e2b549f8172..bdbece0b08051 100644 ---- a/Documentation/ABI/testing/sysfs-fs-f2fs -+++ b/Documentation/ABI/testing/sysfs-fs-f2fs -@@ -529,3 +529,10 @@ Description: With "mode=fragment:block" mount options, we can scatter block allo - f2fs will allocate 1.. blocks in a chunk and make a hole - in the length of 1.. by turns. This value can be set - between 1..512 and the default value is 4. -+ -+What: /sys/fs/f2fs//gc_urgent_high_remaining -+Date: December 2021 -+Contact: "Daeho Jeong" -+Description: You can set the trial count limit for GC urgent high mode with this value. -+ If GC thread gets to the limit, the mode will turn back to GC normal mode. -+ By default, the value is zero, which means there is no limit like before. -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index b5f1099ab388f..d4a5700927cd5 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -1682,6 +1682,9 @@ struct f2fs_sb_info { - unsigned int cur_victim_sec; /* current victim section num */ - unsigned int gc_mode; /* current GC state */ - unsigned int next_victim_seg[2]; /* next segment in victim section */ -+ spinlock_t gc_urgent_high_lock; -+ bool gc_urgent_high_limited; /* indicates having limited trial count */ -+ unsigned int gc_urgent_high_remaining; /* remaining trial count for GC_URGENT_HIGH */ - - /* for skip statistic */ - unsigned int atomic_files; /* # of opened atomic file */ -diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c -index 4d4d7f0c8a71b..21081e7ff55d5 100644 ---- a/fs/f2fs/gc.c -+++ b/fs/f2fs/gc.c -@@ -92,6 +92,18 @@ static int gc_thread_func(void *data) - * So, I'd like to wait some time to collect dirty segments. - */ - if (sbi->gc_mode == GC_URGENT_HIGH) { -+ spin_lock(&sbi->gc_urgent_high_lock); -+ if (sbi->gc_urgent_high_limited) { -+ if (!sbi->gc_urgent_high_remaining) { -+ sbi->gc_urgent_high_limited = false; -+ spin_unlock(&sbi->gc_urgent_high_lock); -+ sbi->gc_mode = GC_NORMAL; -+ continue; -+ } -+ sbi->gc_urgent_high_remaining--; -+ } -+ spin_unlock(&sbi->gc_urgent_high_lock); -+ - wait_ms = gc_th->urgent_sleep_time; - down_write(&sbi->gc_lock); - goto do_gc; -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 339e44467b9cd..098daef550f49 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -3621,6 +3621,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi) - sbi->seq_file_ra_mul = MIN_RA_MUL; - sbi->max_fragment_chunk = DEF_FRAGMENT_SIZE; - sbi->max_fragment_hole = DEF_FRAGMENT_SIZE; -+ spin_lock_init(&sbi->gc_urgent_high_lock); - - sbi->dir_level = DEF_DIR_LEVEL; - sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL; -diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c -index c0e72bd44b135..673b1153dbc67 100644 ---- a/fs/f2fs/sysfs.c -+++ b/fs/f2fs/sysfs.c -@@ -480,6 +480,15 @@ static ssize_t __sbi_store(struct f2fs_attr *a, - return count; - } - -+ if (!strcmp(a->attr.name, "gc_urgent_high_remaining")) { -+ spin_lock(&sbi->gc_urgent_high_lock); -+ sbi->gc_urgent_high_limited = t == 0 ? false : true; -+ sbi->gc_urgent_high_remaining = t; -+ spin_unlock(&sbi->gc_urgent_high_lock); -+ -+ return count; -+ } -+ - #ifdef CONFIG_F2FS_IOSTAT - if (!strcmp(a->attr.name, "iostat_enable")) { - sbi->iostat_enable = !!t; -@@ -735,6 +744,7 @@ F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type); - #endif - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag); - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag); -+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent_high_remaining, gc_urgent_high_remaining); - F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, ckpt_thread_ioprio, ckpt_thread_ioprio); - F2FS_GENERAL_RO_ATTR(dirty_segments); - F2FS_GENERAL_RO_ATTR(free_segments); -@@ -846,6 +856,7 @@ static struct attribute *f2fs_attrs[] = { - #endif - ATTR_LIST(data_io_flag), - ATTR_LIST(node_io_flag), -+ ATTR_LIST(gc_urgent_high_remaining), - ATTR_LIST(ckpt_thread_ioprio), - ATTR_LIST(dirty_segments), - ATTR_LIST(free_segments), --- -2.43.0 - diff --git a/queue-5.15/f2fs-assign-curseg_all_data_atgc-if-blkaddr-is-valid.patch b/queue-5.15/f2fs-assign-curseg_all_data_atgc-if-blkaddr-is-valid.patch deleted file mode 100644 index d5c02a90869..00000000000 --- a/queue-5.15/f2fs-assign-curseg_all_data_atgc-if-blkaddr-is-valid.patch +++ /dev/null @@ -1,59 +0,0 @@ -From fce24e07ef388141ce18a9fcc5cc4e5bcc05dc42 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 18 Jun 2024 02:15:38 +0000 -Subject: f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid - -From: Jaegeuk Kim - -[ Upstream commit 8cb1f4080dd91c6e6b01dbea013a3f42341cb6a1 ] - -mkdir /mnt/test/comp -f2fs_io setflags compression /mnt/test/comp -dd if=/dev/zero of=/mnt/test/comp/testfile bs=16k count=1 -truncate --size 13 /mnt/test/comp/testfile - -In the above scenario, we can get a BUG_ON. - kernel BUG at fs/f2fs/segment.c:3589! - Call Trace: - do_write_page+0x78/0x390 [f2fs] - f2fs_outplace_write_data+0x62/0xb0 [f2fs] - f2fs_do_write_data_page+0x275/0x740 [f2fs] - f2fs_write_single_data_page+0x1dc/0x8f0 [f2fs] - f2fs_write_multi_pages+0x1e5/0xae0 [f2fs] - f2fs_write_cache_pages+0xab1/0xc60 [f2fs] - f2fs_write_data_pages+0x2d8/0x330 [f2fs] - do_writepages+0xcf/0x270 - __writeback_single_inode+0x44/0x350 - writeback_sb_inodes+0x242/0x530 - __writeback_inodes_wb+0x54/0xf0 - wb_writeback+0x192/0x310 - wb_workfn+0x30d/0x400 - -The reason is we gave CURSEG_ALL_DATA_ATGC to COMPR_ADDR where the -page was set the gcing flag by set_cluster_dirty(). - -Cc: stable@vger.kernel.org -Fixes: 4961acdd65c9 ("f2fs: fix to tag gcing flag on page during block migration") -Reviewed-by: Chao Yu -Tested-by: Will McVicker -Signed-off-by: Jaegeuk Kim -Signed-off-by: Sasha Levin ---- - fs/f2fs/segment.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c -index d8b1980df52d6..ae70e536bef37 100644 ---- a/fs/f2fs/segment.c -+++ b/fs/f2fs/segment.c -@@ -3360,6 +3360,7 @@ static int __get_segment_type_6(struct f2fs_io_info *fio) - if (fio->sbi->am.atgc_enabled && - (fio->io_type == FS_DATA_IO) && - (fio->sbi->gc_mode != GC_URGENT_HIGH) && -+ __is_valid_data_blkaddr(fio->old_blkaddr) && - !is_inode_flag_set(inode, FI_OPU_WRITE)) - return CURSEG_ALL_DATA_ATGC; - else --- -2.43.0 - diff --git a/queue-5.15/f2fs-fix-start-segno-of-large-section.patch b/queue-5.15/f2fs-fix-start-segno-of-large-section.patch deleted file mode 100644 index 6a6351093d9..00000000000 --- a/queue-5.15/f2fs-fix-start-segno-of-large-section.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 42507285d0900ef65a62dc3aef2b194073593961 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 8 Jul 2024 20:04:07 +0800 -Subject: f2fs: fix start segno of large section - -From: Sheng Yong - -[ Upstream commit 8c409989678e92e4a737e7cd2bb04f3efb81071a ] - -get_ckpt_valid_blocks() checks valid ckpt blocks in current section. -It counts all vblocks from the first to the last segment in the -large section. However, START_SEGNO() is used to get the first segno -in an SIT block. This patch fixes that to get the correct start segno. - -Fixes: 61461fc921b7 ("f2fs: fix to avoid touching checkpointed data in get_victim()") -Signed-off-by: Sheng Yong -Reviewed-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Signed-off-by: Sasha Levin ---- - fs/f2fs/segment.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h -index 04f448ddf49ea..1d16449089d02 100644 ---- a/fs/f2fs/segment.h -+++ b/fs/f2fs/segment.h -@@ -369,7 +369,8 @@ static inline unsigned int get_ckpt_valid_blocks(struct f2fs_sb_info *sbi, - unsigned int segno, bool use_section) - { - if (use_section && __is_large_section(sbi)) { -- unsigned int start_segno = START_SEGNO(segno); -+ unsigned int secno = GET_SEC_FROM_SEG(sbi, segno); -+ unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno); - unsigned int blocks = 0; - int i; - --- -2.43.0 - diff --git a/queue-5.15/f2fs-fix-to-avoid-use-ssr-allocate-when-do-defragmen.patch b/queue-5.15/f2fs-fix-to-avoid-use-ssr-allocate-when-do-defragmen.patch deleted file mode 100644 index 9088b1844d5..00000000000 --- a/queue-5.15/f2fs-fix-to-avoid-use-ssr-allocate-when-do-defragmen.patch +++ /dev/null @@ -1,75 +0,0 @@ -From f73481308a0fbe8393969f8daa0d85943a0dd576 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 29 May 2024 17:47:00 +0800 -Subject: f2fs: fix to avoid use SSR allocate when do defragment - -From: Zhiguo Niu - -[ Upstream commit 21327a042dd94bc73181d7300e688699cb1f467e ] - -SSR allocate mode will be used when doing file defragment -if ATGC is working at the same time, that is because -set_page_private_gcing may make CURSEG_ALL_DATA_ATGC segment -type got in f2fs_allocate_data_block when defragment page -is writeback, which may cause file fragmentation is worse. - -A file with 2 fragmentations is changed as following after defragment: - -----------------file info------------------- -sensorsdata : --------------------------------------------- -dev [254:48] -ino [0x 3029 : 12329] -mode [0x 81b0 : 33200] -nlink [0x 1 : 1] -uid [0x 27e6 : 10214] -gid [0x 27e6 : 10214] -size [0x 242000 : 2367488] -blksize [0x 1000 : 4096] -blocks [0x 1210 : 4624] --------------------------------------------- - -file_pos start_blk end_blk blks - 0 11361121 11361207 87 - 356352 11361215 11361216 2 - 364544 11361218 11361218 1 - 368640 11361220 11361221 2 - 376832 11361224 11361225 2 - 385024 11361227 11361238 12 - 434176 11361240 11361252 13 - 487424 11361254 11361254 1 - 491520 11361271 11361279 9 - 528384 3681794 3681795 2 - 536576 3681797 3681797 1 - 540672 3681799 3681799 1 - 544768 3681803 3681803 1 - 548864 3681805 3681805 1 - 552960 3681807 3681807 1 - 557056 3681809 3681809 1 - -Signed-off-by: Zhiguo Niu -Reviewed-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Stable-dep-of: 8cb1f4080dd9 ("f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid") -Signed-off-by: Sasha Levin ---- - fs/f2fs/segment.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c -index b059b02fc179d..d8b1980df52d6 100644 ---- a/fs/f2fs/segment.c -+++ b/fs/f2fs/segment.c -@@ -3359,7 +3359,8 @@ static int __get_segment_type_6(struct f2fs_io_info *fio) - if (page_private_gcing(fio->page)) { - if (fio->sbi->am.atgc_enabled && - (fio->io_type == FS_DATA_IO) && -- (fio->sbi->gc_mode != GC_URGENT_HIGH)) -+ (fio->sbi->gc_mode != GC_URGENT_HIGH) && -+ !is_inode_flag_set(inode, FI_OPU_WRITE)) - return CURSEG_ALL_DATA_ATGC; - else - return CURSEG_COLD_DATA; --- -2.43.0 - diff --git a/queue-5.15/f2fs-fix-to-update-user-block-counts-in-block_operat.patch b/queue-5.15/f2fs-fix-to-update-user-block-counts-in-block_operat.patch deleted file mode 100644 index ef26e3d6346..00000000000 --- a/queue-5.15/f2fs-fix-to-update-user-block-counts-in-block_operat.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 28a1435984b58374df33937baf30b25d7668f3b4 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 25 Jun 2024 10:32:39 +0800 -Subject: f2fs: fix to update user block counts in block_operations() - -From: Chao Yu - -[ Upstream commit f06c0f82e38bbda7264d6ef3c90045ad2810e0f3 ] - -Commit 59c9081bc86e ("f2fs: allow write page cache when writting cp") -allows write() to write data to page cache during checkpoint, so block -count fields like .total_valid_block_count, .alloc_valid_block_count -and .rf_node_block_count may encounter race condition as below: - -CP Thread A -- write_checkpoint - - block_operations - - f2fs_down_write(&sbi->node_change) - - __prepare_cp_block - : ckpt->valid_block_count = .total_valid_block_count - - f2fs_up_write(&sbi->node_change) - - write - - f2fs_preallocate_blocks - - f2fs_map_blocks(,F2FS_GET_BLOCK_PRE_AIO) - - f2fs_map_lock - - f2fs_down_read(&sbi->node_change) - - f2fs_reserve_new_blocks - - inc_valid_block_count - : percpu_counter_add(&sbi->alloc_valid_block_count, count) - : sbi->total_valid_block_count += count - - f2fs_up_read(&sbi->node_change) - - do_checkpoint - : sbi->last_valid_block_count = sbi->total_valid_block_count - : percpu_counter_set(&sbi->alloc_valid_block_count, 0) - : percpu_counter_set(&sbi->rf_node_block_count, 0) - - fsync - - need_do_checkpoint - - f2fs_space_for_roll_forward - : alloc_valid_block_count was reset to zero, - so, it may missed last data during checkpoint - -Let's change to update .total_valid_block_count, .alloc_valid_block_count -and .rf_node_block_count in block_operations(), then their access can be -protected by .node_change and .cp_rwsem lock, so that it can avoid above -race condition. - -Fixes: 59c9081bc86e ("f2fs: allow write page cache when writting cp") -Cc: Yunlei He -Signed-off-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Signed-off-by: Sasha Levin ---- - fs/f2fs/checkpoint.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c -index 8d12e2fa32b8f..ab91aa0003fe4 100644 ---- a/fs/f2fs/checkpoint.c -+++ b/fs/f2fs/checkpoint.c -@@ -1175,6 +1175,11 @@ static void __prepare_cp_block(struct f2fs_sb_info *sbi) - ckpt->valid_node_count = cpu_to_le32(valid_node_count(sbi)); - ckpt->valid_inode_count = cpu_to_le32(valid_inode_count(sbi)); - ckpt->next_free_nid = cpu_to_le32(last_nid); -+ -+ /* update user_block_counts */ -+ sbi->last_valid_block_count = sbi->total_valid_block_count; -+ percpu_counter_set(&sbi->alloc_valid_block_count, 0); -+ percpu_counter_set(&sbi->rf_node_block_count, 0); - } - - static bool __need_flush_quota(struct f2fs_sb_info *sbi) -@@ -1566,11 +1571,6 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) - start_blk += NR_CURSEG_NODE_TYPE; - } - -- /* update user_block_counts */ -- sbi->last_valid_block_count = sbi->total_valid_block_count; -- percpu_counter_set(&sbi->alloc_valid_block_count, 0); -- percpu_counter_set(&sbi->rf_node_block_count, 0); -- - /* Here, we have one bio having CP pack except cp pack 2 page */ - f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); - /* Wait for all dirty meta pages to be submitted for IO */ --- -2.43.0 - diff --git a/queue-5.15/f2fs-fix-wrong-continue-condition-in-gc.patch b/queue-5.15/f2fs-fix-wrong-continue-condition-in-gc.patch deleted file mode 100644 index 21a983f2259..00000000000 --- a/queue-5.15/f2fs-fix-wrong-continue-condition-in-gc.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 605b0a778aa2599aa902ae639b8e9937c74b869b Mon Sep 17 00:00:00 2001 -From: Jaegeuk Kim -Date: Fri, 12 Aug 2022 22:49:50 -0700 -Subject: f2fs: fix wrong continue condition in GC - -From: Jaegeuk Kim - -commit 605b0a778aa2599aa902ae639b8e9937c74b869b upstream. - -We should decrease the frozen counter. - -Cc: stable@vger.kernel.org -Fixes: 325163e9892b ("f2fs: add gc_urgent_high_remaining sysfs node") -Reviewed-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Signed-off-by: Greg Kroah-Hartman ---- - fs/f2fs/gc.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - ---- a/fs/f2fs/gc.c -+++ b/fs/f2fs/gc.c -@@ -93,14 +93,10 @@ static int gc_thread_func(void *data) - */ - if (sbi->gc_mode == GC_URGENT_HIGH) { - spin_lock(&sbi->gc_urgent_high_lock); -- if (sbi->gc_urgent_high_limited) { -- if (!sbi->gc_urgent_high_remaining) { -- sbi->gc_urgent_high_limited = false; -- spin_unlock(&sbi->gc_urgent_high_lock); -- sbi->gc_mode = GC_NORMAL; -- continue; -- } -- sbi->gc_urgent_high_remaining--; -+ if (sbi->gc_urgent_high_limited && -+ !sbi->gc_urgent_high_remaining--) { -+ sbi->gc_urgent_high_limited = false; -+ sbi->gc_mode = GC_NORMAL; - } - spin_unlock(&sbi->gc_urgent_high_lock); - diff --git a/queue-5.15/f2fs-introduce-f2fs_ipu_honor_opu_write-ipu-policy.patch b/queue-5.15/f2fs-introduce-f2fs_ipu_honor_opu_write-ipu-policy.patch deleted file mode 100644 index 6f34dce4c94..00000000000 --- a/queue-5.15/f2fs-introduce-f2fs_ipu_honor_opu_write-ipu-policy.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 73bca3a74464453640ea4a8e3aff8f475fcfdbab Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 4 Feb 2022 15:19:46 +0800 -Subject: f2fs: introduce F2FS_IPU_HONOR_OPU_WRITE ipu policy - -From: Chao Yu - -[ Upstream commit 1018a5463a063715365784704c4e8cdf2eec4b04 ] - -Once F2FS_IPU_FORCE policy is enabled in some cases: -a) f2fs forces to use F2FS_IPU_FORCE in a small-sized volume -b) user sets F2FS_IPU_FORCE policy via sysfs - -Then we may fail to defragment file due to IPU policy check, it doesn't -make sense, let's introduce a new IPU policy to allow OPU during file -defragmentation. - -In small-sized volume, let's enable F2FS_IPU_HONOR_OPU_WRITE policy -by default. - -Signed-off-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Stable-dep-of: 8cb1f4080dd9 ("f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid") -Signed-off-by: Sasha Levin ---- - Documentation/ABI/testing/sysfs-fs-f2fs | 3 ++- - fs/f2fs/data.c | 18 +++++++++++++----- - fs/f2fs/f2fs.h | 3 ++- - fs/f2fs/file.c | 18 +++++++++++------- - fs/f2fs/segment.h | 5 ++++- - fs/f2fs/super.c | 3 ++- - 6 files changed, 34 insertions(+), 16 deletions(-) - -diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs -index 92bc2bdc8baf1..320fc162bcf15 100644 ---- a/Documentation/ABI/testing/sysfs-fs-f2fs -+++ b/Documentation/ABI/testing/sysfs-fs-f2fs -@@ -55,8 +55,9 @@ Description: Controls the in-place-update policy. - 0x04 F2FS_IPU_UTIL - 0x08 F2FS_IPU_SSR_UTIL - 0x10 F2FS_IPU_FSYNC -- 0x20 F2FS_IPU_ASYNC, -+ 0x20 F2FS_IPU_ASYNC - 0x40 F2FS_IPU_NOCACHE -+ 0x80 F2FS_IPU_HONOR_OPU_WRITE - ==== ================= - - Refer segment.h for details. -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index fa86eaf1d6393..3f8dae229d422 100644 ---- a/fs/f2fs/data.c -+++ b/fs/f2fs/data.c -@@ -2567,6 +2567,9 @@ static inline bool check_inplace_update_policy(struct inode *inode, - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - unsigned int policy = SM_I(sbi)->ipu_policy; - -+ if (policy & (0x1 << F2FS_IPU_HONOR_OPU_WRITE) && -+ is_inode_flag_set(inode, FI_OPU_WRITE)) -+ return false; - if (policy & (0x1 << F2FS_IPU_FORCE)) - return true; - if (policy & (0x1 << F2FS_IPU_SSR) && f2fs_need_SSR(sbi)) -@@ -2637,6 +2640,9 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) - if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) - return true; - -+ if (is_inode_flag_set(inode, FI_OPU_WRITE)) -+ return true; -+ - if (fio) { - if (page_private_gcing(fio->page)) - return true; -@@ -3263,8 +3269,8 @@ static int __f2fs_write_data_pages(struct address_space *mapping, - f2fs_available_free_memory(sbi, DIRTY_DENTS)) - goto skip_write; - -- /* skip writing during file defragment */ -- if (is_inode_flag_set(inode, FI_DO_DEFRAG)) -+ /* skip writing in file defragment preparing stage */ -+ if (is_inode_flag_set(inode, FI_SKIP_WRITES)) - goto skip_write; - - trace_f2fs_writepages(mapping->host, wbc, DATA); -@@ -3998,6 +4004,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, - filemap_invalidate_lock(inode->i_mapping); - - set_inode_flag(inode, FI_ALIGNED_WRITE); -+ set_inode_flag(inode, FI_OPU_WRITE); - - for (; secidx < end_sec; secidx++) { - down_write(&sbi->pin_sem); -@@ -4006,7 +4013,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, - f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); - f2fs_unlock_op(sbi); - -- set_inode_flag(inode, FI_DO_DEFRAG); -+ set_inode_flag(inode, FI_SKIP_WRITES); - - for (blkofs = 0; blkofs < blk_per_sec; blkofs++) { - struct page *page; -@@ -4023,7 +4030,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, - f2fs_put_page(page, 1); - } - -- clear_inode_flag(inode, FI_DO_DEFRAG); -+ clear_inode_flag(inode, FI_SKIP_WRITES); - - ret = filemap_fdatawrite(inode->i_mapping); - -@@ -4034,7 +4041,8 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, - } - - done: -- clear_inode_flag(inode, FI_DO_DEFRAG); -+ clear_inode_flag(inode, FI_SKIP_WRITES); -+ clear_inode_flag(inode, FI_OPU_WRITE); - clear_inode_flag(inode, FI_ALIGNED_WRITE); - - filemap_invalidate_unlock(inode->i_mapping); -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index fb1422a81d382..62390632db401 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -714,7 +714,8 @@ enum { - FI_DROP_CACHE, /* drop dirty page cache */ - FI_DATA_EXIST, /* indicate data exists */ - FI_INLINE_DOTS, /* indicate inline dot dentries */ -- FI_DO_DEFRAG, /* indicate defragment is running */ -+ FI_SKIP_WRITES, /* should skip data page writeback */ -+ FI_OPU_WRITE, /* used for opu per file */ - FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */ - FI_NO_PREALLOC, /* indicate skipped preallocated blocks */ - FI_HOT_DATA, /* indicate file is hot */ -diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c -index be9536815e50d..0e6766d4eff57 100644 ---- a/fs/f2fs/file.c -+++ b/fs/f2fs/file.c -@@ -2576,10 +2576,6 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, - bool fragmented = false; - int err; - -- /* if in-place-update policy is enabled, don't waste time here */ -- if (f2fs_should_update_inplace(inode, NULL)) -- return -EINVAL; -- - pg_start = range->start >> PAGE_SHIFT; - pg_end = (range->start + range->len) >> PAGE_SHIFT; - -@@ -2587,6 +2583,13 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, - - inode_lock(inode); - -+ /* if in-place-update policy is enabled, don't waste time here */ -+ set_inode_flag(inode, FI_OPU_WRITE); -+ if (f2fs_should_update_inplace(inode, NULL)) { -+ err = -EINVAL; -+ goto out; -+ } -+ - /* writeback all dirty pages in the range */ - err = filemap_write_and_wait_range(inode->i_mapping, range->start, - range->start + range->len - 1); -@@ -2668,7 +2671,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, - goto check; - } - -- set_inode_flag(inode, FI_DO_DEFRAG); -+ set_inode_flag(inode, FI_SKIP_WRITES); - - idx = map.m_lblk; - while (idx < map.m_lblk + map.m_len && cnt < blk_per_seg) { -@@ -2694,15 +2697,16 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, - if (map.m_lblk < pg_end && cnt < blk_per_seg) - goto do_map; - -- clear_inode_flag(inode, FI_DO_DEFRAG); -+ clear_inode_flag(inode, FI_SKIP_WRITES); - - err = filemap_fdatawrite(inode->i_mapping); - if (err) - goto out; - } - clear_out: -- clear_inode_flag(inode, FI_DO_DEFRAG); -+ clear_inode_flag(inode, FI_SKIP_WRITES); - out: -+ clear_inode_flag(inode, FI_OPU_WRITE); - inode_unlock(inode); - if (!err) - range->len = (u64)total << PAGE_SHIFT; -diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h -index d1c0c8732c4fd..6d3a48407e1ba 100644 ---- a/fs/f2fs/segment.h -+++ b/fs/f2fs/segment.h -@@ -667,7 +667,9 @@ static inline int utilization(struct f2fs_sb_info *sbi) - * pages over min_fsync_blocks. (=default option) - * F2FS_IPU_ASYNC - do IPU given by asynchronous write requests. - * F2FS_IPU_NOCACHE - disable IPU bio cache. -- * F2FS_IPUT_DISABLE - disable IPU. (=default option in LFS mode) -+ * F2FS_IPU_HONOR_OPU_WRITE - use OPU write prior to IPU write if inode has -+ * FI_OPU_WRITE flag. -+ * F2FS_IPU_DISABLE - disable IPU. (=default option in LFS mode) - */ - #define DEF_MIN_IPU_UTIL 70 - #define DEF_MIN_FSYNC_BLOCKS 8 -@@ -683,6 +685,7 @@ enum { - F2FS_IPU_FSYNC, - F2FS_IPU_ASYNC, - F2FS_IPU_NOCACHE, -+ F2FS_IPU_HONOR_OPU_WRITE, - }; - - static inline unsigned int curseg_segno(struct f2fs_sb_info *sbi, -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 144c35b2760f4..5ba244d01c6ea 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -3992,7 +3992,8 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi) - F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE; - if (f2fs_block_unit_discard(sbi)) - sm_i->dcc_info->discard_granularity = 1; -- sm_i->ipu_policy = 1 << F2FS_IPU_FORCE; -+ sm_i->ipu_policy = 1 << F2FS_IPU_FORCE | -+ 1 << F2FS_IPU_HONOR_OPU_WRITE; - } - - sbi->readdir_ra = 1; --- -2.43.0 - diff --git a/queue-5.15/f2fs-introduce-fragment-allocation-mode-mount-option.patch b/queue-5.15/f2fs-introduce-fragment-allocation-mode-mount-option.patch deleted file mode 100644 index f15422e8dff..00000000000 --- a/queue-5.15/f2fs-introduce-fragment-allocation-mode-mount-option.patch +++ /dev/null @@ -1,312 +0,0 @@ -From bcfa36b10c3241ed299f21f0b186e97a9f064eed Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 29 Sep 2021 11:12:03 -0700 -Subject: f2fs: introduce fragment allocation mode mount option - -From: Daeho Jeong - -[ Upstream commit 6691d940b0e09dd1564130e7a354d6deaf05d009 ] - -Added two options into "mode=" mount option to make it possible for -developers to simulate filesystem fragmentation/after-GC situation -itself. The developers use these modes to understand filesystem -fragmentation/after-GC condition well, and eventually get some -insights to handle them better. - -"fragment:segment": f2fs allocates a new segment in ramdom position. - With this, we can simulate the after-GC condition. -"fragment:block" : We can scatter block allocation with - "max_fragment_chunk" and "max_fragment_hole" sysfs - nodes. f2fs will allocate 1.. - blocks in a chunk and make a hole in the length of - 1.. by turns in a newly allocated - free segment. Plus, this mode implicitly enables - "fragment:segment" option for more randomness. - -Reviewed-by: Chao Yu -Signed-off-by: Daeho Jeong -Signed-off-by: Jaegeuk Kim -Stable-dep-of: f06c0f82e38b ("f2fs: fix to update user block counts in block_operations()") -Signed-off-by: Sasha Levin ---- - Documentation/ABI/testing/sysfs-fs-f2fs | 16 ++++++++++++++++ - Documentation/filesystems/f2fs.rst | 18 ++++++++++++++++++ - fs/f2fs/f2fs.h | 19 +++++++++++++++++-- - fs/f2fs/gc.c | 5 ++++- - fs/f2fs/segment.c | 20 ++++++++++++++++++-- - fs/f2fs/segment.h | 1 + - fs/f2fs/super.c | 10 ++++++++++ - fs/f2fs/sysfs.c | 20 ++++++++++++++++++++ - 8 files changed, 104 insertions(+), 5 deletions(-) - -diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs -index 48d41b6696270..91e2b549f8172 100644 ---- a/Documentation/ABI/testing/sysfs-fs-f2fs -+++ b/Documentation/ABI/testing/sysfs-fs-f2fs -@@ -513,3 +513,19 @@ Date: July 2021 - Contact: "Daeho Jeong" - Description: You can control the multiplier value of bdi device readahead window size - between 2 (default) and 256 for POSIX_FADV_SEQUENTIAL advise option. -+ -+What: /sys/fs/f2fs//max_fragment_chunk -+Date: August 2021 -+Contact: "Daeho Jeong" -+Description: With "mode=fragment:block" mount options, we can scatter block allocation. -+ f2fs will allocate 1.. blocks in a chunk and make a hole -+ in the length of 1.. by turns. This value can be set -+ between 1..512 and the default value is 4. -+ -+What: /sys/fs/f2fs//max_fragment_hole -+Date: August 2021 -+Contact: "Daeho Jeong" -+Description: With "mode=fragment:block" mount options, we can scatter block allocation. -+ f2fs will allocate 1.. blocks in a chunk and make a hole -+ in the length of 1.. by turns. This value can be set -+ between 1..512 and the default value is 4. -diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst -index 7fe50b0bccde9..6954c04753ad7 100644 ---- a/Documentation/filesystems/f2fs.rst -+++ b/Documentation/filesystems/f2fs.rst -@@ -202,6 +202,24 @@ fault_type=%d Support configuring fault injection type, should be - mode=%s Control block allocation mode which supports "adaptive" - and "lfs". In "lfs" mode, there should be no random - writes towards main area. -+ "fragment:segment" and "fragment:block" are newly added here. -+ These are developer options for experiments to simulate filesystem -+ fragmentation/after-GC situation itself. The developers use these -+ modes to understand filesystem fragmentation/after-GC condition well, -+ and eventually get some insights to handle them better. -+ In "fragment:segment", f2fs allocates a new segment in ramdom -+ position. With this, we can simulate the after-GC condition. -+ In "fragment:block", we can scatter block allocation with -+ "max_fragment_chunk" and "max_fragment_hole" sysfs nodes. -+ We added some randomness to both chunk and hole size to make -+ it close to realistic IO pattern. So, in this mode, f2fs will allocate -+ 1.. blocks in a chunk and make a hole in the -+ length of 1.. by turns. With this, the newly -+ allocated blocks will be scattered throughout the whole partition. -+ Note that "fragment:block" implicitly enables "fragment:segment" -+ option for more randomness. -+ Please, use these options for your experiments and we strongly -+ recommend to re-format the filesystem after using these options. - io_bits=%u Set the bit size of write IO requests. It should be set - with "mode=lfs". - usrquota Enable plain user disk quota accounting. -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index e49fca9daf2d3..b5f1099ab388f 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -1294,8 +1294,10 @@ enum { - }; - - enum { -- FS_MODE_ADAPTIVE, /* use both lfs/ssr allocation */ -- FS_MODE_LFS, /* use lfs allocation only */ -+ FS_MODE_ADAPTIVE, /* use both lfs/ssr allocation */ -+ FS_MODE_LFS, /* use lfs allocation only */ -+ FS_MODE_FRAGMENT_SEG, /* segment fragmentation mode */ -+ FS_MODE_FRAGMENT_BLK, /* block fragmentation mode */ - }; - - enum { -@@ -1770,6 +1772,9 @@ struct f2fs_sb_info { - - unsigned long seq_file_ra_mul; /* multiplier for ra_pages of seq. files in fadvise */ - -+ int max_fragment_chunk; /* max chunk size for block fragmentation mode */ -+ int max_fragment_hole; /* max hole size for block fragmentation mode */ -+ - #ifdef CONFIG_F2FS_FS_COMPRESSION - struct kmem_cache *page_array_slab; /* page array entry */ - unsigned int page_array_slab_size; /* default page array slab size */ -@@ -3539,6 +3544,16 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi, - unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi, - unsigned int segno); - -+#define DEF_FRAGMENT_SIZE 4 -+#define MIN_FRAGMENT_SIZE 1 -+#define MAX_FRAGMENT_SIZE 512 -+ -+static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi) -+{ -+ return F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_SEG || -+ F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_BLK; -+} -+ - /* - * checkpoint.c - */ -diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c -index 9a57754e6e0c1..4d4d7f0c8a71b 100644 ---- a/fs/f2fs/gc.c -+++ b/fs/f2fs/gc.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - #include "f2fs.h" - #include "node.h" -@@ -257,7 +258,9 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type, - p->max_search = sbi->max_victim_search; - - /* let's select beginning hot/small space first in no_heap mode*/ -- if (test_opt(sbi, NOHEAP) && -+ if (f2fs_need_rand_seg(sbi)) -+ p->offset = prandom_u32() % (MAIN_SECS(sbi) * sbi->segs_per_sec); -+ else if (test_opt(sbi, NOHEAP) && - (type == CURSEG_HOT_DATA || IS_NODESEG(type))) - p->offset = 0; - else -diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c -index 1c69dc91c3292..b059b02fc179d 100644 ---- a/fs/f2fs/segment.c -+++ b/fs/f2fs/segment.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include "f2fs.h" - #include "segment.h" -@@ -2633,6 +2634,8 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type) - unsigned short seg_type = curseg->seg_type; - - sanity_check_seg_type(sbi, seg_type); -+ if (f2fs_need_rand_seg(sbi)) -+ return prandom_u32() % (MAIN_SECS(sbi) * sbi->segs_per_sec); - - /* if segs_per_sec is large than 1, we need to keep original policy. */ - if (__is_large_section(sbi)) -@@ -2684,6 +2687,9 @@ static void new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec) - curseg->next_segno = segno; - reset_curseg(sbi, type, 1); - curseg->alloc_type = LFS; -+ if (F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_BLK) -+ curseg->fragment_remained_chunk = -+ prandom_u32() % sbi->max_fragment_chunk + 1; - } - - static int __next_free_blkoff(struct f2fs_sb_info *sbi, -@@ -2710,12 +2716,22 @@ static int __next_free_blkoff(struct f2fs_sb_info *sbi, - static void __refresh_next_blkoff(struct f2fs_sb_info *sbi, - struct curseg_info *seg) - { -- if (seg->alloc_type == SSR) -+ if (seg->alloc_type == SSR) { - seg->next_blkoff = - __next_free_blkoff(sbi, seg->segno, - seg->next_blkoff + 1); -- else -+ } else { - seg->next_blkoff++; -+ if (F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_BLK) { -+ /* To allocate block chunks in different sizes, use random number */ -+ if (--seg->fragment_remained_chunk <= 0) { -+ seg->fragment_remained_chunk = -+ prandom_u32() % sbi->max_fragment_chunk + 1; -+ seg->next_blkoff += -+ prandom_u32() % sbi->max_fragment_hole + 1; -+ } -+ } -+ } - } - - bool f2fs_segment_has_free_slot(struct f2fs_sb_info *sbi, int segno) -diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h -index 1d16449089d02..d1c0c8732c4fd 100644 ---- a/fs/f2fs/segment.h -+++ b/fs/f2fs/segment.h -@@ -321,6 +321,7 @@ struct curseg_info { - unsigned short next_blkoff; /* next block offset to write */ - unsigned int zone; /* current zone number */ - unsigned int next_segno; /* preallocated segment */ -+ int fragment_remained_chunk; /* remained block size in a chunk for block fragmentation mode */ - bool inited; /* indicate inmem log is inited */ - }; - -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 706d7adda3b22..339e44467b9cd 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -881,6 +881,10 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) - F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; - } else if (!strcmp(name, "lfs")) { - F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; -+ } else if (!strcmp(name, "fragment:segment")) { -+ F2FS_OPTION(sbi).fs_mode = FS_MODE_FRAGMENT_SEG; -+ } else if (!strcmp(name, "fragment:block")) { -+ F2FS_OPTION(sbi).fs_mode = FS_MODE_FRAGMENT_BLK; - } else { - kfree(name); - return -EINVAL; -@@ -1972,6 +1976,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) - seq_puts(seq, "adaptive"); - else if (F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS) - seq_puts(seq, "lfs"); -+ else if (F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_SEG) -+ seq_puts(seq, "fragment:segment"); -+ else if (F2FS_OPTION(sbi).fs_mode == FS_MODE_FRAGMENT_BLK) -+ seq_puts(seq, "fragment:block"); - seq_printf(seq, ",active_logs=%u", F2FS_OPTION(sbi).active_logs); - if (test_opt(sbi, RESERVE_ROOT)) - seq_printf(seq, ",reserve_root=%u,resuid=%u,resgid=%u", -@@ -3611,6 +3619,8 @@ static void init_sb_info(struct f2fs_sb_info *sbi) - sbi->max_victim_search = DEF_MAX_VICTIM_SEARCH; - sbi->migration_granularity = sbi->segs_per_sec; - sbi->seq_file_ra_mul = MIN_RA_MUL; -+ sbi->max_fragment_chunk = DEF_FRAGMENT_SIZE; -+ sbi->max_fragment_hole = DEF_FRAGMENT_SIZE; - - sbi->dir_level = DEF_DIR_LEVEL; - sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL; -diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c -index 63af1573ebcaa..c0e72bd44b135 100644 ---- a/fs/f2fs/sysfs.c -+++ b/fs/f2fs/sysfs.c -@@ -553,6 +553,22 @@ static ssize_t __sbi_store(struct f2fs_attr *a, - return count; - } - -+ if (!strcmp(a->attr.name, "max_fragment_chunk")) { -+ if (t >= MIN_FRAGMENT_SIZE && t <= MAX_FRAGMENT_SIZE) -+ sbi->max_fragment_chunk = t; -+ else -+ return -EINVAL; -+ return count; -+ } -+ -+ if (!strcmp(a->attr.name, "max_fragment_hole")) { -+ if (t >= MIN_FRAGMENT_SIZE && t <= MAX_FRAGMENT_SIZE) -+ sbi->max_fragment_hole = t; -+ else -+ return -EINVAL; -+ return count; -+ } -+ - *ui = (unsigned int)t; - - return count; -@@ -783,6 +799,8 @@ F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold); - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, seq_file_ra_mul, seq_file_ra_mul); - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode); - F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs); -+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_fragment_chunk, max_fragment_chunk); -+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_fragment_hole, max_fragment_hole); - - #define ATTR_LIST(name) (&f2fs_attr_##name.attr) - static struct attribute *f2fs_attrs[] = { -@@ -861,6 +879,8 @@ static struct attribute *f2fs_attrs[] = { - ATTR_LIST(seq_file_ra_mul), - ATTR_LIST(gc_segment_mode), - ATTR_LIST(gc_reclaimed_segments), -+ ATTR_LIST(max_fragment_chunk), -+ ATTR_LIST(max_fragment_hole), - NULL, - }; - ATTRIBUTE_GROUPS(f2fs); --- -2.43.0 - diff --git a/queue-5.15/i2c-qcom-geni-add-desc-struct-to-prepare-support-for.patch b/queue-5.15/i2c-qcom-geni-add-desc-struct-to-prepare-support-for.patch deleted file mode 100644 index 3e56be85603..00000000000 --- a/queue-5.15/i2c-qcom-geni-add-desc-struct-to-prepare-support-for.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 563606693cd1d2b34691aaff0e0f54f4afaecce7 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 29 Nov 2022 15:47:05 +0100 -Subject: i2c: qcom-geni: add desc struct to prepare support for I2C Master Hub - variant - -From: Neil Armstrong - -[ Upstream commit 14d02fbadb5dc1cdf66078ef8430dd1cd22bfd53 ] - -The I2C Master Hub is a stripped down version of the GENI Serial Engine -QUP Wrapper Controller but only supporting I2C serial engines without -DMA support. - -Those I2C serial engines variants have some requirements: -- a separate "core" clock -- doesn't support DMA, thus no memory interconnect path -- fixed FIFO size not discoverable in the HW_PARAM_0 register - -Add a desc struct specifying all those requirements which will be used in -a next change when adding the I2C Master Hub serial engine compatible. - -Signed-off-by: Neil Armstrong -Reviewed-by: Konrad Dybcio -Signed-off-by: Wolfram Sang -Stable-dep-of: 9ba48db9f77c ("i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume") -Signed-off-by: Sasha Levin ---- - drivers/i2c/busses/i2c-qcom-geni.c | 50 ++++++++++++++++++++++++++++-- - 1 file changed, 47 insertions(+), 3 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c -index fc1dcc19f2a17..f811999e3aac9 100644 ---- a/drivers/i2c/busses/i2c-qcom-geni.c -+++ b/drivers/i2c/busses/i2c-qcom-geni.c -@@ -88,6 +88,7 @@ struct geni_i2c_dev { - int cur_wr; - int cur_rd; - spinlock_t lock; -+ struct clk *core_clk; - u32 clk_freq_out; - const struct geni_i2c_clk_fld *clk_fld; - int suspended; -@@ -99,6 +100,13 @@ struct geni_i2c_dev { - bool gpi_mode; - }; - -+struct geni_i2c_desc { -+ bool has_core_clk; -+ char *icc_ddr; -+ bool no_dma_support; -+ unsigned int tx_fifo_depth; -+}; -+ - struct geni_i2c_err_log { - int err; - const char *msg; -@@ -755,6 +763,7 @@ static int geni_i2c_probe(struct platform_device *pdev) - u32 proto, tx_depth, fifo_disable; - int ret; - struct device *dev = &pdev->dev; -+ const struct geni_i2c_desc *desc = NULL; - - gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL); - if (!gi2c) -@@ -767,6 +776,14 @@ static int geni_i2c_probe(struct platform_device *pdev) - if (IS_ERR(gi2c->se.base)) - return PTR_ERR(gi2c->se.base); - -+ desc = device_get_match_data(&pdev->dev); -+ -+ if (desc && desc->has_core_clk) { -+ gi2c->core_clk = devm_clk_get(dev, "core"); -+ if (IS_ERR(gi2c->core_clk)) -+ return PTR_ERR(gi2c->core_clk); -+ } -+ - gi2c->se.clk = devm_clk_get(dev, "se"); - if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(dev)) - return PTR_ERR(gi2c->se.clk); -@@ -810,7 +827,7 @@ static int geni_i2c_probe(struct platform_device *pdev) - gi2c->adap.dev.of_node = dev->of_node; - strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name)); - -- ret = geni_icc_get(&gi2c->se, "qup-memory"); -+ ret = geni_icc_get(&gi2c->se, desc ? desc->icc_ddr : "qup-memory"); - if (ret) - return ret; - /* -@@ -820,12 +837,17 @@ static int geni_i2c_probe(struct platform_device *pdev) - */ - gi2c->se.icc_paths[GENI_TO_CORE].avg_bw = GENI_DEFAULT_BW; - gi2c->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; -- gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out); -+ if (!desc || desc->icc_ddr) -+ gi2c->se.icc_paths[GENI_TO_DDR].avg_bw = Bps_to_icc(gi2c->clk_freq_out); - - ret = geni_icc_set_bw(&gi2c->se); - if (ret) - return ret; - -+ ret = clk_prepare_enable(gi2c->core_clk); -+ if (ret) -+ return ret; -+ - ret = geni_se_resources_on(&gi2c->se); - if (ret) { - dev_err(dev, "Error turning on resources %d\n", ret); -@@ -835,10 +857,15 @@ static int geni_i2c_probe(struct platform_device *pdev) - if (proto != GENI_SE_I2C) { - dev_err(dev, "Invalid proto %d\n", proto); - geni_se_resources_off(&gi2c->se); -+ clk_disable_unprepare(gi2c->core_clk); - return -ENXIO; - } - -- fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; -+ if (desc && desc->no_dma_support) -+ fifo_disable = false; -+ else -+ fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; -+ - if (fifo_disable) { - /* FIFO is disabled, so we can only use GPI DMA */ - gi2c->gpi_mode = true; -@@ -852,6 +879,16 @@ static int geni_i2c_probe(struct platform_device *pdev) - } else { - gi2c->gpi_mode = false; - tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); -+ -+ /* I2C Master Hub Serial Elements doesn't have the HW_PARAM_0 register */ -+ if (!tx_depth && desc) -+ tx_depth = desc->tx_fifo_depth; -+ -+ if (!tx_depth) { -+ dev_err(dev, "Invalid TX FIFO depth\n"); -+ return -EINVAL; -+ } -+ - gi2c->tx_wm = tx_depth - 1; - geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth); - geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, -@@ -860,6 +897,7 @@ static int geni_i2c_probe(struct platform_device *pdev) - dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); - } - -+ clk_disable_unprepare(gi2c->core_clk); - ret = geni_se_resources_off(&gi2c->se); - if (ret) { - dev_err(dev, "Error turning off resources %d\n", ret); -@@ -925,6 +963,8 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev) - gi2c->suspended = 1; - } - -+ clk_disable_unprepare(gi2c->core_clk); -+ - return geni_icc_disable(&gi2c->se); - } - -@@ -937,6 +977,10 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) - if (ret) - return ret; - -+ ret = clk_prepare_enable(gi2c->core_clk); -+ if (ret) -+ return ret; -+ - ret = geni_se_resources_on(&gi2c->se); - if (ret) - return ret; --- -2.43.0 - diff --git a/queue-5.15/i2c-qcom-geni-add-missing-clk_disable_unprepare-in-g.patch b/queue-5.15/i2c-qcom-geni-add-missing-clk_disable_unprepare-in-g.patch deleted file mode 100644 index a60fdd930b8..00000000000 --- a/queue-5.15/i2c-qcom-geni-add-missing-clk_disable_unprepare-in-g.patch +++ /dev/null @@ -1,42 +0,0 @@ -From b9fab584c4f59346c3397e566b2172bf35e5d282 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 3 Aug 2024 14:10:41 +0800 -Subject: i2c: qcom-geni: Add missing clk_disable_unprepare in - geni_i2c_runtime_resume - -From: Gaosheng Cui - -[ Upstream commit b93d16bee557302d4e588375ececd833cc048acc ] - -Add the missing clk_disable_unprepare() before return in -geni_i2c_runtime_resume(). - -Fixes: 14d02fbadb5d ("i2c: qcom-geni: add desc struct to prepare support for I2C Master Hub variant") -Signed-off-by: Gaosheng Cui -Reviewed-by: Vladimir Zapolskiy -Signed-off-by: Andi Shyti -Stable-dep-of: 9ba48db9f77c ("i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume") -Signed-off-by: Sasha Levin ---- - drivers/i2c/busses/i2c-qcom-geni.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c -index f811999e3aac9..27a7cca3918c6 100644 ---- a/drivers/i2c/busses/i2c-qcom-geni.c -+++ b/drivers/i2c/busses/i2c-qcom-geni.c -@@ -982,8 +982,10 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) - return ret; - - ret = geni_se_resources_on(&gi2c->se); -- if (ret) -+ if (ret) { -+ clk_disable_unprepare(gi2c->core_clk); - return ret; -+ } - - enable_irq(gi2c->irq); - gi2c->suspended = 0; --- -2.43.0 - diff --git a/queue-5.15/i2c-qcom-geni-add-missing-geni_icc_disable-in-geni_i.patch b/queue-5.15/i2c-qcom-geni-add-missing-geni_icc_disable-in-geni_i.patch deleted file mode 100644 index b0949465dd9..00000000000 --- a/queue-5.15/i2c-qcom-geni-add-missing-geni_icc_disable-in-geni_i.patch +++ /dev/null @@ -1,37 +0,0 @@ -From f9edc08d44840561dfcf88791c40eab30d6a9598 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 6 Aug 2024 20:53:31 +0800 -Subject: i2c: qcom-geni: Add missing geni_icc_disable in - geni_i2c_runtime_resume - -From: Gaosheng Cui - -[ Upstream commit 9ba48db9f77ce0001dbb882476fa46e092feb695 ] - -Add the missing geni_icc_disable() before return in -geni_i2c_runtime_resume(). - -Fixes: bf225ed357c6 ("i2c: i2c-qcom-geni: Add interconnect support") -Signed-off-by: Gaosheng Cui -Reviewed-by: Vladimir Zapolskiy -Signed-off-by: Andi Shyti -Signed-off-by: Sasha Levin ---- - drivers/i2c/busses/i2c-qcom-geni.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c -index 27a7cca3918c6..8eb64b09cf58e 100644 ---- a/drivers/i2c/busses/i2c-qcom-geni.c -+++ b/drivers/i2c/busses/i2c-qcom-geni.c -@@ -984,6 +984,7 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) - ret = geni_se_resources_on(&gi2c->se); - if (ret) { - clk_disable_unprepare(gi2c->core_clk); -+ geni_icc_disable(&gi2c->se); - return ret; - } - --- -2.43.0 - diff --git a/queue-5.15/i2c-qcom-geni-add-support-for-gpi-dma.patch b/queue-5.15/i2c-qcom-geni-add-support-for-gpi-dma.patch deleted file mode 100644 index 4a8f0c7cecb..00000000000 --- a/queue-5.15/i2c-qcom-geni-add-support-for-gpi-dma.patch +++ /dev/null @@ -1,436 +0,0 @@ -From 7d1839cf943c210a5741981a805f402cc4ec3668 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 21 Feb 2022 15:57:16 +0530 -Subject: i2c: qcom-geni: Add support for GPI DMA - -From: Vinod Koul - -[ Upstream commit d8703554f4dea9775417525b22b3d65ed1c6b16e ] - -QUP Serial engines supports data transfers thru FIFO mode, SE DMA mode -and lastly GPI DMA mode. Former two are already supported and this adds -supports for the last mode. - -In GPI DMA mode, the firmware is issued commands by driver to perform -DMA and setup the serial port. - -Signed-off-by: Vinod Koul -Reviewed-by: Bjorn Andersson -Signed-off-by: Wolfram Sang -Stable-dep-of: 9ba48db9f77c ("i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume") -Signed-off-by: Sasha Levin ---- - drivers/i2c/busses/i2c-qcom-geni.c | 308 ++++++++++++++++++++++++++--- - 1 file changed, 280 insertions(+), 28 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c -index 6d635a7c104ce..fc1dcc19f2a17 100644 ---- a/drivers/i2c/busses/i2c-qcom-geni.c -+++ b/drivers/i2c/busses/i2c-qcom-geni.c -@@ -3,7 +3,9 @@ - - #include - #include -+#include - #include -+#include - #include - #include - #include -@@ -48,6 +50,9 @@ - #define LOW_COUNTER_SHFT 10 - #define CYCLE_COUNTER_MSK GENMASK(9, 0) - -+#define I2C_PACK_TX BIT(0) -+#define I2C_PACK_RX BIT(1) -+ - enum geni_i2c_err_code { - GP_IRQ0, - NACK, -@@ -89,6 +94,9 @@ struct geni_i2c_dev { - void *dma_buf; - size_t xfer_len; - dma_addr_t dma_addr; -+ struct dma_chan *tx_c; -+ struct dma_chan *rx_c; -+ bool gpi_mode; - }; - - struct geni_i2c_err_log { -@@ -456,12 +464,207 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, - return gi2c->err; - } - -+static void i2c_gpi_cb_result(void *cb, const struct dmaengine_result *result) -+{ -+ struct geni_i2c_dev *gi2c = cb; -+ -+ if (result->result != DMA_TRANS_NOERROR) { -+ dev_err(gi2c->se.dev, "DMA txn failed:%d\n", result->result); -+ gi2c->err = -EIO; -+ } else if (result->residue) { -+ dev_dbg(gi2c->se.dev, "DMA xfer has pending: %d\n", result->residue); -+ } -+ -+ complete(&gi2c->done); -+} -+ -+static void geni_i2c_gpi_unmap(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, -+ void *tx_buf, dma_addr_t tx_addr, -+ void *rx_buf, dma_addr_t rx_addr) -+{ -+ if (tx_buf) { -+ dma_unmap_single(gi2c->se.dev->parent, tx_addr, msg->len, DMA_TO_DEVICE); -+ i2c_put_dma_safe_msg_buf(tx_buf, msg, false); -+ } -+ -+ if (rx_buf) { -+ dma_unmap_single(gi2c->se.dev->parent, rx_addr, msg->len, DMA_FROM_DEVICE); -+ i2c_put_dma_safe_msg_buf(rx_buf, msg, false); -+ } -+} -+ -+static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, -+ struct dma_slave_config *config, dma_addr_t *dma_addr_p, -+ void **buf, unsigned int op, struct dma_chan *dma_chan) -+{ -+ struct gpi_i2c_config *peripheral; -+ unsigned int flags; -+ void *dma_buf; -+ dma_addr_t addr; -+ enum dma_data_direction map_dirn; -+ enum dma_transfer_direction dma_dirn; -+ struct dma_async_tx_descriptor *desc; -+ int ret; -+ -+ peripheral = config->peripheral_config; -+ -+ dma_buf = i2c_get_dma_safe_msg_buf(msg, 1); -+ if (!dma_buf) -+ return -ENOMEM; -+ -+ if (op == I2C_WRITE) -+ map_dirn = DMA_TO_DEVICE; -+ else -+ map_dirn = DMA_FROM_DEVICE; -+ -+ addr = dma_map_single(gi2c->se.dev->parent, dma_buf, msg->len, map_dirn); -+ if (dma_mapping_error(gi2c->se.dev->parent, addr)) { -+ i2c_put_dma_safe_msg_buf(dma_buf, msg, false); -+ return -ENOMEM; -+ } -+ -+ /* set the length as message for rx txn */ -+ peripheral->rx_len = msg->len; -+ peripheral->op = op; -+ -+ ret = dmaengine_slave_config(dma_chan, config); -+ if (ret) { -+ dev_err(gi2c->se.dev, "dma config error: %d for op:%d\n", ret, op); -+ goto err_config; -+ } -+ -+ peripheral->set_config = 0; -+ peripheral->multi_msg = true; -+ flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; -+ -+ if (op == I2C_WRITE) -+ dma_dirn = DMA_MEM_TO_DEV; -+ else -+ dma_dirn = DMA_DEV_TO_MEM; -+ -+ desc = dmaengine_prep_slave_single(dma_chan, addr, msg->len, dma_dirn, flags); -+ if (!desc) { -+ dev_err(gi2c->se.dev, "prep_slave_sg failed\n"); -+ ret = -EIO; -+ goto err_config; -+ } -+ -+ desc->callback_result = i2c_gpi_cb_result; -+ desc->callback_param = gi2c; -+ -+ dmaengine_submit(desc); -+ *dma_addr_p = addr; -+ -+ return 0; -+ -+err_config: -+ dma_unmap_single(gi2c->se.dev->parent, addr, msg->len, map_dirn); -+ i2c_put_dma_safe_msg_buf(dma_buf, msg, false); -+ return ret; -+} -+ -+static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], int num) -+{ -+ struct dma_slave_config config = {}; -+ struct gpi_i2c_config peripheral = {}; -+ int i, ret = 0, timeout; -+ dma_addr_t tx_addr, rx_addr; -+ void *tx_buf = NULL, *rx_buf = NULL; -+ const struct geni_i2c_clk_fld *itr = gi2c->clk_fld; -+ -+ config.peripheral_config = &peripheral; -+ config.peripheral_size = sizeof(peripheral); -+ -+ peripheral.pack_enable = I2C_PACK_TX | I2C_PACK_RX; -+ peripheral.cycle_count = itr->t_cycle_cnt; -+ peripheral.high_count = itr->t_high_cnt; -+ peripheral.low_count = itr->t_low_cnt; -+ peripheral.clk_div = itr->clk_div; -+ peripheral.set_config = 1; -+ peripheral.multi_msg = false; -+ -+ for (i = 0; i < num; i++) { -+ gi2c->cur = &msgs[i]; -+ gi2c->err = 0; -+ dev_dbg(gi2c->se.dev, "msg[%d].len:%d\n", i, gi2c->cur->len); -+ -+ peripheral.stretch = 0; -+ if (i < num - 1) -+ peripheral.stretch = 1; -+ -+ peripheral.addr = msgs[i].addr; -+ -+ if (msgs[i].flags & I2C_M_RD) { -+ ret = geni_i2c_gpi(gi2c, &msgs[i], &config, -+ &rx_addr, &rx_buf, I2C_READ, gi2c->rx_c); -+ if (ret) -+ goto err; -+ } -+ -+ ret = geni_i2c_gpi(gi2c, &msgs[i], &config, -+ &tx_addr, &tx_buf, I2C_WRITE, gi2c->tx_c); -+ if (ret) -+ goto err; -+ -+ if (msgs[i].flags & I2C_M_RD) -+ dma_async_issue_pending(gi2c->rx_c); -+ dma_async_issue_pending(gi2c->tx_c); -+ -+ timeout = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); -+ if (!timeout) { -+ dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n", -+ gi2c->cur->flags, gi2c->cur->addr); -+ gi2c->err = -ETIMEDOUT; -+ goto err; -+ } -+ -+ if (gi2c->err) { -+ ret = gi2c->err; -+ goto err; -+ } -+ -+ geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); -+ } -+ -+ return num; -+ -+err: -+ dev_err(gi2c->se.dev, "GPI transfer failed: %d\n", ret); -+ dmaengine_terminate_sync(gi2c->rx_c); -+ dmaengine_terminate_sync(gi2c->tx_c); -+ geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); -+ return ret; -+} -+ -+static int geni_i2c_fifo_xfer(struct geni_i2c_dev *gi2c, -+ struct i2c_msg msgs[], int num) -+{ -+ int i, ret = 0; -+ -+ for (i = 0; i < num; i++) { -+ u32 m_param = i < (num - 1) ? STOP_STRETCH : 0; -+ -+ m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK); -+ -+ gi2c->cur = &msgs[i]; -+ if (msgs[i].flags & I2C_M_RD) -+ ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param); -+ else -+ ret = geni_i2c_tx_one_msg(gi2c, &msgs[i], m_param); -+ -+ if (ret) -+ return ret; -+ } -+ -+ return num; -+} -+ - static int geni_i2c_xfer(struct i2c_adapter *adap, - struct i2c_msg msgs[], - int num) - { - struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap); -- int i, ret; -+ int ret; - - gi2c->err = 0; - reinit_completion(&gi2c->done); -@@ -475,28 +678,17 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, - } - - qcom_geni_i2c_conf(gi2c); -- for (i = 0; i < num; i++) { -- u32 m_param = i < (num - 1) ? STOP_STRETCH : 0; -- -- m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK); -- -- gi2c->cur = &msgs[i]; -- if (msgs[i].flags & I2C_M_RD) -- ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param); -- else -- ret = geni_i2c_tx_one_msg(gi2c, &msgs[i], m_param); - -- if (ret) -- break; -- } -- if (ret == 0) -- ret = num; -+ if (gi2c->gpi_mode) -+ ret = geni_i2c_gpi_xfer(gi2c, msgs, num); -+ else -+ ret = geni_i2c_fifo_xfer(gi2c, msgs, num); - - pm_runtime_mark_last_busy(gi2c->se.dev); - pm_runtime_put_autosuspend(gi2c->se.dev); - gi2c->cur = NULL; - gi2c->err = 0; -- return ret; -+ return num; - } - - static u32 geni_i2c_func(struct i2c_adapter *adap) -@@ -517,11 +709,50 @@ static const struct acpi_device_id geni_i2c_acpi_match[] = { - MODULE_DEVICE_TABLE(acpi, geni_i2c_acpi_match); - #endif - -+static void release_gpi_dma(struct geni_i2c_dev *gi2c) -+{ -+ if (gi2c->rx_c) -+ dma_release_channel(gi2c->rx_c); -+ -+ if (gi2c->tx_c) -+ dma_release_channel(gi2c->tx_c); -+} -+ -+static int setup_gpi_dma(struct geni_i2c_dev *gi2c) -+{ -+ int ret; -+ -+ geni_se_select_mode(&gi2c->se, GENI_GPI_DMA); -+ gi2c->tx_c = dma_request_chan(gi2c->se.dev, "tx"); -+ if (IS_ERR(gi2c->tx_c)) { -+ ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->tx_c), -+ "Failed to get tx DMA ch\n"); -+ if (ret < 0) -+ goto err_tx; -+ } -+ -+ gi2c->rx_c = dma_request_chan(gi2c->se.dev, "rx"); -+ if (IS_ERR(gi2c->rx_c)) { -+ ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->rx_c), -+ "Failed to get rx DMA ch\n"); -+ if (ret < 0) -+ goto err_rx; -+ } -+ -+ dev_dbg(gi2c->se.dev, "Grabbed GPI dma channels\n"); -+ return 0; -+ -+err_rx: -+ dma_release_channel(gi2c->tx_c); -+err_tx: -+ return ret; -+} -+ - static int geni_i2c_probe(struct platform_device *pdev) - { - struct geni_i2c_dev *gi2c; - struct resource *res; -- u32 proto, tx_depth; -+ u32 proto, tx_depth, fifo_disable; - int ret; - struct device *dev = &pdev->dev; - -@@ -601,27 +832,43 @@ static int geni_i2c_probe(struct platform_device *pdev) - return ret; - } - proto = geni_se_read_proto(&gi2c->se); -- tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); - if (proto != GENI_SE_I2C) { - dev_err(dev, "Invalid proto %d\n", proto); - geni_se_resources_off(&gi2c->se); - return -ENXIO; - } -- gi2c->tx_wm = tx_depth - 1; -- geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth); -- geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, PACKING_BYTES_PW, -- true, true, true); -+ -+ fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE; -+ if (fifo_disable) { -+ /* FIFO is disabled, so we can only use GPI DMA */ -+ gi2c->gpi_mode = true; -+ ret = setup_gpi_dma(gi2c); -+ if (ret) { -+ dev_err(dev, "Failed to setup GPI DMA mode:%d ret\n", ret); -+ return ret; -+ } -+ -+ dev_dbg(dev, "Using GPI DMA mode for I2C\n"); -+ } else { -+ gi2c->gpi_mode = false; -+ tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); -+ gi2c->tx_wm = tx_depth - 1; -+ geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth); -+ geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, -+ PACKING_BYTES_PW, true, true, true); -+ -+ dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); -+ } -+ - ret = geni_se_resources_off(&gi2c->se); - if (ret) { - dev_err(dev, "Error turning off resources %d\n", ret); -- return ret; -+ goto err_dma; - } - - ret = geni_icc_disable(&gi2c->se); - if (ret) -- return ret; -- -- dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); -+ goto err_dma; - - gi2c->suspended = 1; - pm_runtime_set_suspended(gi2c->se.dev); -@@ -633,12 +880,16 @@ static int geni_i2c_probe(struct platform_device *pdev) - if (ret) { - dev_err(dev, "Error adding i2c adapter %d\n", ret); - pm_runtime_disable(gi2c->se.dev); -- return ret; -+ goto err_dma; - } - - dev_dbg(dev, "Geni-I2C adaptor successfully added\n"); - - return 0; -+ -+err_dma: -+ release_gpi_dma(gi2c); -+ return ret; - } - - static int geni_i2c_remove(struct platform_device *pdev) -@@ -646,6 +897,7 @@ static int geni_i2c_remove(struct platform_device *pdev) - struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); - - i2c_del_adapter(&gi2c->adap); -+ release_gpi_dma(gi2c); - pm_runtime_disable(gi2c->se.dev); - return 0; - } --- -2.43.0 - diff --git a/queue-5.15/series b/queue-5.15/series index 42989e2317f..b19361ab1f9 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -1,3 +1,5 @@ +f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch +f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch edac-i10nm-make-skx_common.o-a-separate-module.patch platform-chrome-cros_ec_debugfs-fix-wrong-ec-message.patch block-refactor-to-use-helper.patch @@ -208,8 +210,6 @@ binder-fix-hang-of-unregistered-readers.patch dev-parport-fix-the-array-out-of-bounds-risk.patch fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch -f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch -f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch clk-davinci-da8xx-cfgchip-initialize-clk_init_data-before-use.patch ubi-eba-properly-rollback-inside-self_check_eba.patch decompress_bunzip2-fix-rare-decompression-failure.patch @@ -264,11 +264,6 @@ dmaengine-ti-k3-udma-fix-bchan-count-with-uhc-and-hc.patch phy-cadence-torrent-check-return-value-on-register-r.patch um-time-travel-fix-time-travel-start-option.patch um-time-travel-fix-signal-blocking-race-hang.patch -f2fs-fix-start-segno-of-large-section.patch -f2fs-introduce-fragment-allocation-mode-mount-option.patch -f2fs-add-gc_urgent_high_remaining-sysfs-node.patch -f2fs-add-a-way-to-limit-roll-forward-recovery-time.patch -f2fs-fix-to-update-user-block-counts-in-block_operat.patch libbpf-fix-no-args-func-prototype-btf-dumping-syntax.patch dma-fix-call-order-in-dmam_free_coherent.patch bpf-events-use-prog-to-emit-ksymbol-event-for-main-p.patch @@ -301,7 +296,6 @@ nvme-separate-command-prep-and-issue.patch nvme-pci-add-missing-condition-check-for-existence-o.patch fs-don-t-allow-non-init-s_user_ns-for-filesystems-wi.patch powerpc-configs-update-defconfig-with-now-user-visible-config_fsl_ifc.patch -f2fs-fix-wrong-continue-condition-in-gc.patch arm64-dts-qcom-msm8996-move-clock-cells-to-qmp-phy-c.patch arm64-dts-qcom-msm8998-drop-usb-phy-clock-index.patch arm64-dts-qcom-msm8998-switch-usb-qmp-phy-to-new-sty.patch @@ -320,9 +314,6 @@ leds-trigger-remove-unused-function-led_trigger_rena.patch leds-trigger-store-brightness-set-by-led_trigger_eve.patch leds-trigger-call-synchronize_rcu-before-calling-tri.patch leds-triggers-flush-pending-brightness-before-activa.patch -f2fs-introduce-f2fs_ipu_honor_opu_write-ipu-policy.patch -f2fs-fix-to-avoid-use-ssr-allocate-when-do-defragmen.patch -f2fs-assign-curseg_all_data_atgc-if-blkaddr-is-valid.patch irqdomain-fixed-unbalanced-fwnode-get-and-put.patch genirq-allow-the-pm-device-to-originate-from-irq-dom.patch irqchip-imx-irqsteer-constify-irq_chip-struct.patch @@ -419,10 +410,6 @@ spi-spidev-add-missing-spi_device_id-for-bh2228fv.patch i2c-smbus-send-alert-notifications-to-all-devices-if.patch bpf-kprobe-remove-unused-declaring-of-bpf_kprobe_ove.patch kprobes-fix-to-check-symbol-prefixes-correctly.patch -i2c-qcom-geni-add-support-for-gpi-dma.patch -i2c-qcom-geni-add-desc-struct-to-prepare-support-for.patch -i2c-qcom-geni-add-missing-clk_disable_unprepare-in-g.patch -i2c-qcom-geni-add-missing-geni_icc_disable-in-geni_i.patch spi-spi-fsl-lpspi-fix-scldiv-calculation.patch alsa-usb-audio-re-add-scratchamp-quirk-entries.patch asoc-meson-axg-fifo-fix-irq-scheduling-issue-with-pr.patch