From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 815C828DB54 for ; Wed, 12 Nov 2025 01:48:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762912080; cv=none; b=pO+zaacJ9A/XEa3Wc04NcuaGZXVW4eUE2yRzeHS0TrGVQHz/qXQR4Fts5L7mHFc01IlmI4YAwPjJPHTlgymlFU+auavPLJt+wrtUJxKyr5ZyftOuWsfoWVDqxW68ndl3DEYb2iBqSpeqQ7yEFMfH8kxH/xTcEAztQMO79C/LPqI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762912080; c=relaxed/simple; bh=caTNvumpR+KdHLkJSpfpObyy4nYXY+CobTC0ucALsd0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EjsfF4pzq3MEsEuoMeaDGkPqEXWv12lGd6kVqjb2AUipYFL+Kp3/kXeUcxlVPgdNvjY8pg5Kg7tFaJWvkTZ6c3Ga0yLgg9GWM5hYpvFUXYb30hx3TA/mFBnLYN6C8/GHryZODwgs44jliX4pD4uaO+JF8YvIZB/WqHX+BBaL83o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EMMFj4Fu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EMMFj4Fu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EAEA3C116B1; Wed, 12 Nov 2025 01:47:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1762912080; bh=caTNvumpR+KdHLkJSpfpObyy4nYXY+CobTC0ucALsd0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EMMFj4Fuavf+prqYjQuL/Fcq6Xe8sqIkFZ0/uxFszO5/RZ74/Man62RlZk2UHdu0o J21e/F9ZUPB9tN0/K4yu+AqlYQqEKHtFlcy7/8zuqqs45ZWDnQoY07kUuHgvWKFZQo ZOCRUDMrUpuBDVrcoS/j34epKGvXzmd2OkymnxB/8QggASDfk779iaQzDJhyeQpJZ7 58y7TV5W1c/ffl51/ZePRm3mv1xcOkMrDvTzkJoKzqmEVueYLjEpxeQE2CT/Fq3dbj Fc5zFfzYHUAEMN3IbLDAgCG3OSLG0meyQ+FfgwbBWjrRooPc1VNfeN8VJdueEGoEPJ Hvq3VA8eUjEmg== From: Chao Yu To: jaegeuk@kernel.org Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, Chao Yu Subject: [PATCH v2 2/3] f2fs: introduce f2fs_schedule_timeout() Date: Wed, 12 Nov 2025 09:47:48 +0800 Message-ID: <20251112014749.2006439-2-chao@kernel.org> X-Mailer: git-send-email 2.52.0.rc1.455.g30608eb744-goog In-Reply-To: <20251112014749.2006439-1-chao@kernel.org> References: <20251112014749.2006439-1-chao@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- v2: - get rid of f2fs_schedule_timeout() replacement in retry logic for no memory error. fs/f2fs/checkpoint.c | 4 ++-- fs/f2fs/compress.c | 4 ++-- fs/f2fs/data.c | 4 ++-- fs/f2fs/f2fs.h | 22 +++++++++++++++------- fs/f2fs/segment.c | 4 ++-- fs/f2fs/super.c | 2 +- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index bbe07e3a6c75..4c401b5b2933 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -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) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 716004ba44dc..148bb925b03b 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -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 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, */ 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; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d8e163cc7308..48c20386f031 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3150,8 +3150,8 @@ static int f2fs_write_cache_pages(struct address_space *mapping, } 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; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a4439175eabf..0d0e0a01a659 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -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)) @@ -4919,22 +4919,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; } } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index d968a4250b1a..993ec8afe2db 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -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 @@ static unsigned int __issue_discard_cmd_range(struct f2fs_sb_info *sbi, 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: diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2bd7c2320d4f..d47ec718f3be 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -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; -- 2.49.0