* [f2fs-dev] [PATCH 0/4] Reduce the time spent in interrupt context
@ 2026-05-28 21:20 Bart Van Assche via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 1/4] f2fs: Prepare for supporting delayed bio completion Bart Van Assche via Linux-f2fs-devel
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Bart Van Assche via Linux-f2fs-devel @ 2026-05-28 21:20 UTC (permalink / raw)
To: Jaegeuk Kim; +Cc: Bart Van Assche, linux-f2fs-devel
Hi Jaegeuk,
This patch series reduces the amount of time spent in interrupt context for
completing write bios. Please consider this patch series for the next merge
window.
Thanks,
Bart.
Bart Van Assche (4):
f2fs: Prepare for supporting delayed bio completion
f2fs: Rename f2fs_post_read_wq into f2fs_wq
f2fs: Split f2fs_write_end_io()
f2fs: Run f2fs_write_end_io() asynchronously
fs/f2fs/compress.c | 2 +-
fs/f2fs/data.c | 62 +++++++++++++++++++++++++++++++---------------
fs/f2fs/f2fs.h | 8 +++---
fs/f2fs/super.c | 13 +++++++---
fs/f2fs/sysfs.c | 2 ++
5 files changed, 59 insertions(+), 28 deletions(-)
_______________________________________________
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] 13+ messages in thread
* [f2fs-dev] [PATCH 1/4] f2fs: Prepare for supporting delayed bio completion
2026-05-28 21:20 [f2fs-dev] [PATCH 0/4] Reduce the time spent in interrupt context Bart Van Assche via Linux-f2fs-devel
@ 2026-05-28 21:20 ` Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:10 ` Chao Yu via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 2/4] f2fs: Rename f2fs_post_read_wq into f2fs_wq Bart Van Assche via Linux-f2fs-devel
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche via Linux-f2fs-devel @ 2026-05-28 21:20 UTC (permalink / raw)
To: Jaegeuk Kim; +Cc: Bart Van Assche, linux-f2fs-devel
Use bio frontpadding to allocate memory for a work_struct when
allocating a bio.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
fs/f2fs/data.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 8d4f1e75dee3..1659a57a6d5b 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -40,12 +40,17 @@ struct f2fs_folio_state {
unsigned int read_pages_pending;
};
+struct f2fs_bio {
+ struct work_struct work;
+ struct bio bio;
+};
+
#define F2FS_BIO_POOL_SIZE NR_CURSEG_TYPE
int __init f2fs_init_bioset(void)
{
return bioset_init(&f2fs_bioset, F2FS_BIO_POOL_SIZE,
- 0, BIOSET_NEED_BVECS);
+ offsetof(struct f2fs_bio, bio), BIOSET_NEED_BVECS);
}
void f2fs_destroy_bioset(void)
_______________________________________________
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] 13+ messages in thread
* [f2fs-dev] [PATCH 2/4] f2fs: Rename f2fs_post_read_wq into f2fs_wq
2026-05-28 21:20 [f2fs-dev] [PATCH 0/4] Reduce the time spent in interrupt context Bart Van Assche via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 1/4] f2fs: Prepare for supporting delayed bio completion Bart Van Assche via Linux-f2fs-devel
@ 2026-05-28 21:20 ` Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:10 ` Chao Yu via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 3/4] f2fs: Split f2fs_write_end_io() Bart Van Assche via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously Bart Van Assche via Linux-f2fs-devel
3 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche via Linux-f2fs-devel @ 2026-05-28 21:20 UTC (permalink / raw)
To: Jaegeuk Kim; +Cc: Bart Van Assche, linux-f2fs-devel
Rename f2fs_post_read_wq into f2fs_wq. Create it unconditionally.
Prepare for using this workqueue for completing write bios.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
fs/f2fs/compress.c | 2 +-
fs/f2fs/data.c | 22 ++++++++--------------
fs/f2fs/f2fs.h | 6 +++---
fs/f2fs/super.c | 8 ++++----
4 files changed, 16 insertions(+), 22 deletions(-)
diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 881e76158b96..b3c016c4094b 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -1807,7 +1807,7 @@ static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task)
f2fs_free_dic(dic, false);
} else {
INIT_WORK(&dic->free_work, f2fs_late_free_dic);
- queue_work(dic->sbi->post_read_wq, &dic->free_work);
+ queue_work(dic->sbi->wq, &dic->free_work);
}
}
}
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 1659a57a6d5b..080d69fa8cd1 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -341,7 +341,7 @@ static void f2fs_read_end_io(struct bio *bio)
f2fs_handle_step_decompress(ctx, intask);
} else if (enabled_steps) {
INIT_WORK(&ctx->work, f2fs_post_read_work);
- queue_work(ctx->sbi->post_read_wq, &ctx->work);
+ queue_work(ctx->sbi->wq, &ctx->work);
return;
}
}
@@ -4477,23 +4477,17 @@ void f2fs_destroy_post_read_processing(void)
kmem_cache_destroy(bio_post_read_ctx_cache);
}
-int f2fs_init_post_read_wq(struct f2fs_sb_info *sbi)
+int f2fs_init_wq(struct f2fs_sb_info *sbi)
{
- if (!f2fs_sb_has_encrypt(sbi) &&
- !f2fs_sb_has_verity(sbi) &&
- !f2fs_sb_has_compression(sbi))
- return 0;
-
- sbi->post_read_wq = alloc_workqueue("f2fs_post_read_wq",
- WQ_UNBOUND | WQ_HIGHPRI,
- num_online_cpus());
- return sbi->post_read_wq ? 0 : -ENOMEM;
+ sbi->wq = alloc_workqueue("f2fs_wq", WQ_UNBOUND | WQ_HIGHPRI,
+ num_online_cpus());
+ return sbi->wq ? 0 : -ENOMEM;
}
-void f2fs_destroy_post_read_wq(struct f2fs_sb_info *sbi)
+void f2fs_destroy_wq(struct f2fs_sb_info *sbi)
{
- if (sbi->post_read_wq)
- destroy_workqueue(sbi->post_read_wq);
+ if (sbi->wq)
+ destroy_workqueue(sbi->wq);
}
int __init f2fs_init_bio_entry_cache(void)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 91f506e7c9cf..30353c439d3c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1969,7 +1969,7 @@ struct f2fs_sb_info {
/* Precomputed FS UUID checksum for seeding other checksums */
__u32 s_chksum_seed;
- struct workqueue_struct *post_read_wq; /* post read workqueue */
+ struct workqueue_struct *wq; /* bio completion workqueue */
/*
* If we are in irq context, let's update error information into
@@ -4193,8 +4193,8 @@ bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len);
void f2fs_clear_page_cache_dirty_tag(struct folio *folio);
int f2fs_init_post_read_processing(void);
void f2fs_destroy_post_read_processing(void);
-int f2fs_init_post_read_wq(struct f2fs_sb_info *sbi);
-void f2fs_destroy_post_read_wq(struct f2fs_sb_info *sbi);
+int f2fs_init_wq(struct f2fs_sb_info *sbi);
+void f2fs_destroy_wq(struct f2fs_sb_info *sbi);
extern const struct iomap_ops f2fs_iomap_ops;
/*
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ccf806b676f5..5a100f740b3f 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2074,7 +2074,7 @@ static void f2fs_put_super(struct super_block *sb)
/* flush s_error_work before sbi destroy */
flush_work(&sbi->s_error_work);
- f2fs_destroy_post_read_wq(sbi);
+ f2fs_destroy_wq(sbi);
kvfree(sbi->ckpt);
@@ -5130,9 +5130,9 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
goto free_devices;
}
- err = f2fs_init_post_read_wq(sbi);
+ err = f2fs_init_wq(sbi);
if (err) {
- f2fs_err(sbi, "Failed to initialize post read workqueue");
+ f2fs_err(sbi, "Failed to create workqueue");
goto free_devices;
}
@@ -5419,7 +5419,7 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
f2fs_stop_ckpt_thread(sbi);
/* flush s_error_work before sbi destroy */
flush_work(&sbi->s_error_work);
- f2fs_destroy_post_read_wq(sbi);
+ f2fs_destroy_wq(sbi);
free_devices:
destroy_device_list(sbi);
kvfree(sbi->ckpt);
_______________________________________________
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] 13+ messages in thread
* [f2fs-dev] [PATCH 3/4] f2fs: Split f2fs_write_end_io()
2026-05-28 21:20 [f2fs-dev] [PATCH 0/4] Reduce the time spent in interrupt context Bart Van Assche via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 1/4] f2fs: Prepare for supporting delayed bio completion Bart Van Assche via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 2/4] f2fs: Rename f2fs_post_read_wq into f2fs_wq Bart Van Assche via Linux-f2fs-devel
@ 2026-05-28 21:20 ` Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:11 ` Chao Yu via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously Bart Van Assche via Linux-f2fs-devel
3 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche via Linux-f2fs-devel @ 2026-05-28 21:20 UTC (permalink / raw)
To: Jaegeuk Kim; +Cc: Bart Van Assche, linux-f2fs-devel
Prepare for running most of the write completion work asynchronously.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
fs/f2fs/data.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 080d69fa8cd1..48c004976c4e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -349,14 +349,11 @@ static void f2fs_read_end_io(struct bio *bio)
f2fs_verify_and_finish_bio(bio, intask);
}
-static void f2fs_write_end_io(struct bio *bio)
+static void f2fs_write_end_bio(struct bio *bio)
{
- struct f2fs_sb_info *sbi;
+ struct f2fs_sb_info *sbi = bio->bi_private;
struct folio_iter fi;
- iostat_update_and_unbind_ctx(bio);
- sbi = bio->bi_private;
-
if (time_to_inject(sbi, FAULT_WRITE_IO))
bio->bi_status = BLK_STS_IOERR;
@@ -412,6 +409,13 @@ static void f2fs_write_end_io(struct bio *bio)
bio_put(bio);
}
+static void f2fs_write_end_io(struct bio *bio)
+{
+ iostat_update_and_unbind_ctx(bio);
+
+ f2fs_write_end_bio(bio);
+}
+
#ifdef CONFIG_BLK_DEV_ZONED
static void f2fs_zone_write_end_io(struct bio *bio)
{
_______________________________________________
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] 13+ messages in thread
* [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously
2026-05-28 21:20 [f2fs-dev] [PATCH 0/4] Reduce the time spent in interrupt context Bart Van Assche via Linux-f2fs-devel
` (2 preceding siblings ...)
2026-05-28 21:20 ` [f2fs-dev] [PATCH 3/4] f2fs: Split f2fs_write_end_io() Bart Van Assche via Linux-f2fs-devel
@ 2026-05-28 21:20 ` Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:14 ` Chao Yu via Linux-f2fs-devel
3 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche via Linux-f2fs-devel @ 2026-05-28 21:20 UTC (permalink / raw)
To: Jaegeuk Kim; +Cc: Bart Van Assche, linux-f2fs-devel
The bio_for_each_segment_all() loop can take more than 10 ms for a large
bio on an ARM little core. This is too much for interrupt context. Hence
perform the write bio completion work asynchronously if a bio is large and
if f2fs_write_end_io() is called from atomic context. This patch reduces
the time spent in f2fs_write_end_io() from about 10 ms to about 150
microseconds on an Arm Cortex-A520 core.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
fs/f2fs/data.c | 21 ++++++++++++++++++++-
fs/f2fs/f2fs.h | 2 ++
fs/f2fs/super.c | 5 +++++
fs/f2fs/sysfs.c | 2 ++
4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 48c004976c4e..6e169490c4cf 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -409,11 +409,30 @@ static void f2fs_write_end_bio(struct bio *bio)
bio_put(bio);
}
+static void f2fs_write_end_io_work(struct work_struct *work)
+{
+ struct bio *bio = &container_of(work, struct f2fs_bio, work)->bio;
+
+ f2fs_write_end_bio(bio);
+}
+
static void f2fs_write_end_io(struct bio *bio)
{
+ struct f2fs_sb_info *sbi;
+
iostat_update_and_unbind_ctx(bio);
- f2fs_write_end_bio(bio);
+ sbi = bio->bi_private;
+
+ if (in_atomic() && bio->bi_iter.bi_size > sbi->max_atc_write_bio_size) {
+ struct work_struct *w;
+
+ w = &container_of(bio, struct f2fs_bio, bio)->work;
+ INIT_WORK(w, f2fs_write_end_io_work);
+ queue_work(sbi->wq, w);
+ } else {
+ f2fs_write_end_bio(bio);
+ }
}
#ifdef CONFIG_BLK_DEV_ZONED
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 30353c439d3c..a6a3e01122e1 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1763,6 +1763,8 @@ struct f2fs_sb_info {
struct f2fs_sm_info *sm_info; /* segment manager */
/* for bio operations */
+ /* Largest write bio size completed in atomic context (atc). */
+ u32 max_atc_write_bio_size;
struct f2fs_bio_info *write_io[NR_PAGE_TYPE]; /* for write bios */
/* keep migration IO order for LFS mode */
struct f2fs_rwsem io_order_lock;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 5a100f740b3f..1e822380edb3 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -5007,6 +5007,11 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_fs_info = sbi;
sbi->raw_super = raw_super;
+ /*
+ * SZ_16K restricts the time spent on completing writes to about 150
+ * microseconds on an Arm Cortex-A520 core.
+ */
+ sbi->max_atc_write_bio_size = SZ_16K;
INIT_WORK(&sbi->s_error_work, f2fs_record_error_work);
memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS);
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 352e96ad5c3a..70b2e9be8f8b 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -1266,6 +1266,7 @@ F2FS_SBI_RW_ATTR(gc_idle_interval, interval_time[GC_TIME]);
F2FS_SBI_RW_ATTR(umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);
F2FS_SBI_RW_ATTR(gc_pin_file_thresh, gc_pin_file_threshold);
F2FS_SBI_RW_ATTR(gc_reclaimed_segments, gc_reclaimed_segs);
+F2FS_SBI_RW_ATTR(max_atc_write_bio_size, max_atc_write_bio_size);
F2FS_SBI_GENERAL_RW_ATTR(max_victim_search);
F2FS_SBI_GENERAL_RW_ATTR(migration_granularity);
F2FS_SBI_GENERAL_RW_ATTR(migration_window_granularity);
@@ -1508,6 +1509,7 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST(seq_file_ra_mul),
ATTR_LIST(gc_segment_mode),
ATTR_LIST(gc_reclaimed_segments),
+ ATTR_LIST(max_atc_write_bio_size),
ATTR_LIST(max_fragment_chunk),
ATTR_LIST(max_fragment_hole),
ATTR_LIST(current_atomic_write),
_______________________________________________
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 1/4] f2fs: Prepare for supporting delayed bio completion
2026-05-28 21:20 ` [f2fs-dev] [PATCH 1/4] f2fs: Prepare for supporting delayed bio completion Bart Van Assche via Linux-f2fs-devel
@ 2026-06-10 12:10 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 13+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-06-10 12:10 UTC (permalink / raw)
To: Bart Van Assche, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 5/29/26 05:20, Bart Van Assche wrote:
> Use bio frontpadding to allocate memory for a work_struct when
> allocating a bio.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 2/4] f2fs: Rename f2fs_post_read_wq into f2fs_wq
2026-05-28 21:20 ` [f2fs-dev] [PATCH 2/4] f2fs: Rename f2fs_post_read_wq into f2fs_wq Bart Van Assche via Linux-f2fs-devel
@ 2026-06-10 12:10 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 13+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-06-10 12:10 UTC (permalink / raw)
To: Bart Van Assche, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 5/29/26 05:20, Bart Van Assche wrote:
> Rename f2fs_post_read_wq into f2fs_wq. Create it unconditionally.
> Prepare for using this workqueue for completing write bios.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 3/4] f2fs: Split f2fs_write_end_io()
2026-05-28 21:20 ` [f2fs-dev] [PATCH 3/4] f2fs: Split f2fs_write_end_io() Bart Van Assche via Linux-f2fs-devel
@ 2026-06-10 12:11 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 13+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-06-10 12:11 UTC (permalink / raw)
To: Bart Van Assche, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 5/29/26 05:20, Bart Van Assche wrote:
> Prepare for running most of the write completion work asynchronously.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously
2026-05-28 21:20 ` [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously Bart Van Assche via Linux-f2fs-devel
@ 2026-06-10 12:14 ` Chao Yu via Linux-f2fs-devel
2026-06-10 18:27 ` Bart Van Assche via Linux-f2fs-devel
0 siblings, 1 reply; 13+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-06-10 12:14 UTC (permalink / raw)
To: Bart Van Assche, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 5/29/26 05:20, Bart Van Assche wrote:
> The bio_for_each_segment_all() loop can take more than 10 ms for a large
> bio on an ARM little core. This is too much for interrupt context. Hence
> perform the write bio completion work asynchronously if a bio is large and
> if f2fs_write_end_io() is called from atomic context. This patch reduces
> the time spent in f2fs_write_end_io() from about 10 ms to about 150
> microseconds on an Arm Cortex-A520 core.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
> fs/f2fs/data.c | 21 ++++++++++++++++++++-
> fs/f2fs/f2fs.h | 2 ++
> fs/f2fs/super.c | 5 +++++
> fs/f2fs/sysfs.c | 2 ++
> 4 files changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 48c004976c4e..6e169490c4cf 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -409,11 +409,30 @@ static void f2fs_write_end_bio(struct bio *bio)
> bio_put(bio);
> }
>
> +static void f2fs_write_end_io_work(struct work_struct *work)
> +{
> + struct bio *bio = &container_of(work, struct f2fs_bio, work)->bio;
> +
> + f2fs_write_end_bio(bio);
> +}
> +
> static void f2fs_write_end_io(struct bio *bio)
> {
> + struct f2fs_sb_info *sbi;
> +
> iostat_update_and_unbind_ctx(bio);
>
> - f2fs_write_end_bio(bio);
> + sbi = bio->bi_private;
> +
> + if (in_atomic() && bio->bi_iter.bi_size > sbi->max_atc_write_bio_size) {
> + struct work_struct *w;
> +
> + w = &container_of(bio, struct f2fs_bio, bio)->work;
> + INIT_WORK(w, f2fs_write_end_io_work);
> + queue_work(sbi->wq, w);
> + } else {
> + f2fs_write_end_bio(bio);
> + }
> }
>
> #ifdef CONFIG_BLK_DEV_ZONED
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 30353c439d3c..a6a3e01122e1 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1763,6 +1763,8 @@ struct f2fs_sb_info {
> struct f2fs_sm_info *sm_info; /* segment manager */
>
> /* for bio operations */
> + /* Largest write bio size completed in atomic context (atc). */
> + u32 max_atc_write_bio_size;
> struct f2fs_bio_info *write_io[NR_PAGE_TYPE]; /* for write bios */
> /* keep migration IO order for LFS mode */
> struct f2fs_rwsem io_order_lock;
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 5a100f740b3f..1e822380edb3 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -5007,6 +5007,11 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
>
> sb->s_fs_info = sbi;
> sbi->raw_super = raw_super;
> + /*
> + * SZ_16K restricts the time spent on completing writes to about 150
> + * microseconds on an Arm Cortex-A520 core.
> + */
> + sbi->max_atc_write_bio_size = SZ_16K;
Actually, I don't see this problem before, can we disable this by default, and
only enable for your case via sysfs?
>
> INIT_WORK(&sbi->s_error_work, f2fs_record_error_work);
> memcpy(sbi->errors, raw_super->s_errors, MAX_F2FS_ERRORS);
> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> index 352e96ad5c3a..70b2e9be8f8b 100644
> --- a/fs/f2fs/sysfs.c
> +++ b/fs/f2fs/sysfs.c
> @@ -1266,6 +1266,7 @@ F2FS_SBI_RW_ATTR(gc_idle_interval, interval_time[GC_TIME]);
> F2FS_SBI_RW_ATTR(umount_discard_timeout, interval_time[UMOUNT_DISCARD_TIMEOUT]);
> F2FS_SBI_RW_ATTR(gc_pin_file_thresh, gc_pin_file_threshold);
> F2FS_SBI_RW_ATTR(gc_reclaimed_segments, gc_reclaimed_segs);
> +F2FS_SBI_RW_ATTR(max_atc_write_bio_size, max_atc_write_bio_size);
> F2FS_SBI_GENERAL_RW_ATTR(max_victim_search);
> F2FS_SBI_GENERAL_RW_ATTR(migration_granularity);
> F2FS_SBI_GENERAL_RW_ATTR(migration_window_granularity);
> @@ -1508,6 +1509,7 @@ static struct attribute *f2fs_attrs[] = {
> ATTR_LIST(seq_file_ra_mul),
> ATTR_LIST(gc_segment_mode),
> ATTR_LIST(gc_reclaimed_segments),
> + ATTR_LIST(max_atc_write_bio_size),
We need to update Documentation/ABI/testing/sysfs-fs-f2fs as well.
Thanks,
> ATTR_LIST(max_fragment_chunk),
> ATTR_LIST(max_fragment_hole),
> ATTR_LIST(current_atomic_write),
_______________________________________________
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously
2026-06-10 12:14 ` Chao Yu via Linux-f2fs-devel
@ 2026-06-10 18:27 ` Bart Van Assche via Linux-f2fs-devel
2026-06-12 12:05 ` Chao Yu via Linux-f2fs-devel
0 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche via Linux-f2fs-devel @ 2026-06-10 18:27 UTC (permalink / raw)
To: Chao Yu, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 6/10/26 5:14 AM, Chao Yu wrote:
> On 5/29/26 05:20, Bart Van Assche wrote:
>> + /*
>> + * SZ_16K restricts the time spent on completing writes to about 150
>> + * microseconds on an Arm Cortex-A520 core.
>> + */
>> + sbi->max_atc_write_bio_size = SZ_16K;
>
> Actually, I don't see this problem before, can we disable this by default, and
> only enable for your case via sysfs?
The new behavior should be the default because interrupt handlers should
complete quickly.
F2FS is primarily used on Android systems. On an Android system spending
too much time in interrupt context can have the following consequences:
* User interface stuttering and frame drops (jank).
* Audio glitches.
* Application not responding (ANR).
* Connectivity degradation. Interfaces like Wi-Fi and Bluetooth depend
on fast interrupt handling.
>> + ATTR_LIST(max_atc_write_bio_size),
>
> We need to update Documentation/ABI/testing/sysfs-fs-f2fs as well.
Will do.
Thanks,
Bart.
_______________________________________________
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously
2026-06-10 18:27 ` Bart Van Assche via Linux-f2fs-devel
@ 2026-06-12 12:05 ` Chao Yu via Linux-f2fs-devel
2026-06-12 21:03 ` Bart Van Assche via Linux-f2fs-devel
0 siblings, 1 reply; 13+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-06-12 12:05 UTC (permalink / raw)
To: Bart Van Assche, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 6/11/26 02:27, Bart Van Assche wrote:
> On 6/10/26 5:14 AM, Chao Yu wrote:
>> On 5/29/26 05:20, Bart Van Assche wrote:
>>> + /*
>>> + * SZ_16K restricts the time spent on completing writes to about 150
>>> + * microseconds on an Arm Cortex-A520 core.
>>> + */
>>> + sbi->max_atc_write_bio_size = SZ_16K;
>>
>> Actually, I don't see this problem before, can we disable this by default, and
>> only enable for your case via sysfs?
>
> The new behavior should be the default because interrupt handlers should
> complete quickly.
>
> F2FS is primarily used on Android systems. On an Android system spending
> too much time in interrupt context can have the following consequences:
> * User interface stuttering and frame drops (jank).
> * Audio glitches.
> * Application not responding (ANR).
> * Connectivity degradation. Interfaces like Wi-Fi and Bluetooth depend
> on fast interrupt handling.
Bart,
Yes, agreed, and I can understand that.
Actually, I'm worry about whether there is potential performance regression
caused by enabling this by default, also a little bit concern about the affection
for PC|laptop scenario which is used by individual user.
One example is commit 91b587ba79e1 ("f2fs: Introduce linear search for dentries"),
lots of following extra works were done to fix the performance regression issue it
caused.
What do you think of separating functionality patches and enabling by default path?
I think we can apply functionality patches first.
Thanks,
>
>>> + ATTR_LIST(max_atc_write_bio_size),
>>
>> We need to update Documentation/ABI/testing/sysfs-fs-f2fs as well.
>
> Will do.
>
> Thanks,
>
> Bart.
_______________________________________________
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously
2026-06-12 12:05 ` Chao Yu via Linux-f2fs-devel
@ 2026-06-12 21:03 ` Bart Van Assche via Linux-f2fs-devel
2026-06-15 3:04 ` Chao Yu via Linux-f2fs-devel
0 siblings, 1 reply; 13+ messages in thread
From: Bart Van Assche via Linux-f2fs-devel @ 2026-06-12 21:03 UTC (permalink / raw)
To: Chao Yu, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 6/12/26 5:05 AM, Chao Yu wrote:
> Actually, I'm worry about whether there is potential performance regression
> caused by enabling this by default, also a little bit concern about the
> affection for PC|laptop scenario which is used by individual user.
According to Gemini F2FS is primarily used on PC's and laptops to
increase random write IOPS for rotating media (hard disks). I don't
expect the performance impact of this patch series to be measurable for
rotating media because the time required to queue and schedule work is
very small compared to the I/O completion time for these devices.
I ran a new set of measurements on a UFS 4 test setup with zoned
storage (ZUFS). On that test setup I see that the variation between test
runs is much larger than the variation in test results with or without
this patch series. In other words, I don't think that we have to worry
about the performance impact of this patch series.
Bart.
_______________________________________________
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] 13+ messages in thread
* Re: [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously
2026-06-12 21:03 ` Bart Van Assche via Linux-f2fs-devel
@ 2026-06-15 3:04 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 13+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-06-15 3:04 UTC (permalink / raw)
To: Bart Van Assche, Jaegeuk Kim; +Cc: linux-f2fs-devel
On 6/13/26 05:03, Bart Van Assche wrote:
> On 6/12/26 5:05 AM, Chao Yu wrote:
>> Actually, I'm worry about whether there is potential performance regression
>> caused by enabling this by default, also a little bit concern about the affection for PC|laptop scenario which is used by individual user.
>
> According to Gemini F2FS is primarily used on PC's and laptops to
> increase random write IOPS for rotating media (hard disks). I don't
> expect the performance impact of this patch series to be measurable for
> rotating media because the time required to queue and schedule work is
> very small compared to the I/O completion time for these devices.
Hmm, I suspect there is potential non rotating media user, scheduling
can be the bottleneck there, maybe.
>
> I ran a new set of measurements on a UFS 4 test setup with zoned
> storage (ZUFS). On that test setup I see that the variation between test
> runs is much larger than the variation in test results with or without
> this patch series. In other words, I don't think that we have to worry
> about the performance impact of this patch series.
Well, it needs to be verified for each kernel version you backported, on ZUFS
or non ZUFS, right? I guess Randall or Leo may have time to assist to setup the
performance test. :)
Thanks,
>
> Bart.
_______________________________________________
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] 13+ messages in thread
end of thread, other threads:[~2026-06-15 3:04 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-28 21:20 [f2fs-dev] [PATCH 0/4] Reduce the time spent in interrupt context Bart Van Assche via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 1/4] f2fs: Prepare for supporting delayed bio completion Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:10 ` Chao Yu via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 2/4] f2fs: Rename f2fs_post_read_wq into f2fs_wq Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:10 ` Chao Yu via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 3/4] f2fs: Split f2fs_write_end_io() Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:11 ` Chao Yu via Linux-f2fs-devel
2026-05-28 21:20 ` [f2fs-dev] [PATCH 4/4] f2fs: Run f2fs_write_end_io() asynchronously Bart Van Assche via Linux-f2fs-devel
2026-06-10 12:14 ` Chao Yu via Linux-f2fs-devel
2026-06-10 18:27 ` Bart Van Assche via Linux-f2fs-devel
2026-06-12 12:05 ` Chao Yu via Linux-f2fs-devel
2026-06-12 21:03 ` Bart Van Assche via Linux-f2fs-devel
2026-06-15 3:04 ` Chao Yu via Linux-f2fs-devel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox