]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
f2fs: introduce f2fs_schedule_timeout()
authorChao Yu <chao@kernel.org>
Wed, 12 Nov 2025 01:47:48 +0000 (09:47 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 4 Dec 2025 02:00:05 +0000 (02:00 +0000)
In f2fs retry logic, we will call f2fs_io_schedule_timeout() to sleep as
uninterruptible state (waiting for IO) for a while, however, in several
paths below, we are not blocked by IO:
- f2fs_write_single_data_page() return -EAGAIN due to racing on cp_rwsem.
- f2fs_flush_device_cache() failed to submit preflush command.
- __issue_discard_cmd_range() sleeps periodically in between two in batch
discard submissions.

So, in order to reveal state of task more accurate, let's introduce
f2fs_schedule_timeout() and call it in above paths in where we are waiting
for non-IO reasons.

Then we can get real reason of uninterruptible sleep for a thread in
tracepoint, perfetto, etc.

Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/compress.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/segment.c
fs/f2fs/super.c

index bbe07e3a6c75ac236989ea256bd721245cef3eda..4c401b5b29336b5bb3732b0a48b49421e5efaae1 100644 (file)
@@ -1318,7 +1318,7 @@ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type)
                        f2fs_submit_merged_write(sbi, DATA);
 
                prepare_to_wait(&sbi->cp_wait, &wait, TASK_UNINTERRUPTIBLE);
-               io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+               io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
        }
        finish_wait(&sbi->cp_wait, &wait);
 }
@@ -1974,7 +1974,7 @@ void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi)
 
        /* Let's wait for the previous dispatched checkpoint. */
        while (atomic_read(&cprc->queued_ckpt))
-               io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+               io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 }
 
 void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi)
index 716004ba44dc1e7f619e60782513f8f173e762a3..148bb925b03b69f6efd2cb3dc6e93d9a1c2145af 100644 (file)
@@ -1057,7 +1057,7 @@ static void cancel_cluster_writeback(struct compress_ctx *cc,
                f2fs_submit_merged_write(F2FS_I_SB(cc->inode), DATA);
                while (atomic_read(&cic->pending_pages) !=
                                        (cc->valid_nr_cpages - submitted + 1))
-                       f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+                       f2fs_io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
        }
 
        /* Cancel writeback and stay locked. */
@@ -1574,7 +1574,7 @@ continue_unlock:
                                 */
                                if (IS_NOQUOTA(cc->inode))
                                        goto out;
-                               f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+                               f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
                                goto retry_write;
                        }
                        goto out;
index 7be0837a9456612514af04d59c2296125e2ea96b..9d4f46b8c25623a73a5f567ceb896750293c81e5 100644 (file)
@@ -3141,8 +3141,8 @@ result:
                                } else if (ret == -EAGAIN) {
                                        ret = 0;
                                        if (wbc->sync_mode == WB_SYNC_ALL) {
-                                               f2fs_io_schedule_timeout(
-                                                       DEFAULT_IO_TIMEOUT);
+                                               f2fs_schedule_timeout(
+                                                       DEFAULT_SCHEDULE_TIMEOUT);
                                                goto retry_write;
                                        }
                                        goto next;
index 3d8b69628721e8c51336b80deacd0217b005f05d..858ceb3d2ad6e37f89873e0f42cb34bf7d9e90c3 100644 (file)
@@ -656,8 +656,8 @@ enum {
 
 #define DEFAULT_RETRY_IO_COUNT 8       /* maximum retry read IO or flush count */
 
-/* congestion wait timeout value, default: 20ms */
-#define        DEFAULT_IO_TIMEOUT      (msecs_to_jiffies(20))
+/* IO/non-IO congestion wait timeout value, default: 20ms */
+#define        DEFAULT_SCHEDULE_TIMEOUT        (msecs_to_jiffies(20))
 
 /* timeout value injected, default: 1000ms */
 #define DEFAULT_FAULT_TIMEOUT  (msecs_to_jiffies(1000))
@@ -4908,22 +4908,30 @@ static inline bool f2fs_block_unit_discard(struct f2fs_sb_info *sbi)
        return F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_BLOCK;
 }
 
-static inline void f2fs_io_schedule_timeout(long timeout)
+static inline void __f2fs_schedule_timeout(long timeout, bool io)
 {
        set_current_state(TASK_UNINTERRUPTIBLE);
-       io_schedule_timeout(timeout);
+       if (io)
+               io_schedule_timeout(timeout);
+       else
+               schedule_timeout(timeout);
 }
 
+#define f2fs_io_schedule_timeout(timeout)              \
+                       __f2fs_schedule_timeout(timeout, true)
+#define f2fs_schedule_timeout(timeout)                 \
+                       __f2fs_schedule_timeout(timeout, false)
+
 static inline void f2fs_io_schedule_timeout_killable(long timeout)
 {
        while (timeout) {
                if (fatal_signal_pending(current))
                        return;
                set_current_state(TASK_UNINTERRUPTIBLE);
-               io_schedule_timeout(DEFAULT_IO_TIMEOUT);
-               if (timeout <= DEFAULT_IO_TIMEOUT)
+               io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
+               if (timeout <= DEFAULT_SCHEDULE_TIMEOUT)
                        return;
-               timeout -= DEFAULT_IO_TIMEOUT;
+               timeout -= DEFAULT_SCHEDULE_TIMEOUT;
        }
 }
 
index d968a4250b1a5e590acf05970db0e108ffd26250..993ec8afe2dbbe62b2a00fd959c6d0cbdd13f08b 100644 (file)
@@ -750,7 +750,7 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi)
                do {
                        ret = __submit_flush_wait(sbi, FDEV(i).bdev);
                        if (ret)
-                               f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+                               f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
                } while (ret && --count);
 
                if (ret) {
@@ -3471,7 +3471,7 @@ next:
                        blk_finish_plug(&plug);
                        mutex_unlock(&dcc->cmd_lock);
                        trimmed += __wait_all_discard_cmd(sbi, NULL);
-                       f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+                       f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
                        goto next;
                }
 skip:
index 2bd7c2320d4f05b76b2c949db032a7a95e1cc50d..d47ec718f3be797c95e14aea00987baac7239ef4 100644 (file)
@@ -2652,7 +2652,7 @@ static int f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
        /* we should flush all the data to keep data consistency */
        while (get_pages(sbi, F2FS_DIRTY_DATA)) {
                writeback_inodes_sb_nr(sbi->sb, nr_pages, WB_REASON_SYNC);
-               f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+               f2fs_io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT);
 
                if (f2fs_time_over(sbi, ENABLE_TIME))
                        break;