Skip to content

Commit 1888635

Browse files
Julian Sunbrauner
authored andcommitted
writeback: Wake up waiting tasks when finishing the writeback of a chunk.
Writing back a large number of pages can take a lots of time. This issue is exacerbated when the underlying device is slow or subject to block layer rate limiting, which in turn triggers unexpected hung task warnings. We can trigger a wake-up once a chunk has been written back and the waiting time for writeback exceeds half of sysctl_hung_task_timeout_secs. This action allows the hung task detector to be aware of the writeback progress, thereby eliminating these unexpected hung task warnings. This patch has passed the xfstests 'check -g quick' test based on ext4, with no additional failures introduced. Signed-off-by: Julian Sun <sunjunchao@bytedance.com> Reviewed-by: Jan Kara <jack@suse.cz> Suggested-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 3a86608 commit 1888635

2 files changed

Lines changed: 10 additions & 1 deletion

File tree

fs/fs-writeback.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* Additions for address_space-based writeback
1515
*/
1616

17+
#include <linux/sched/sysctl.h>
1718
#include <linux/kernel.h>
1819
#include <linux/export.h>
1920
#include <linux/spinlock.h>
@@ -213,7 +214,8 @@ static void wb_queue_work(struct bdi_writeback *wb,
213214
void wb_wait_for_completion(struct wb_completion *done)
214215
{
215216
atomic_dec(&done->cnt); /* put down the initial count */
216-
wait_event(*done->waitq, !atomic_read(&done->cnt));
217+
wait_event(*done->waitq,
218+
({ done->progress_stamp = jiffies; !atomic_read(&done->cnt); }));
217219
}
218220

219221
#ifdef CONFIG_CGROUP_WRITEBACK
@@ -2014,6 +2016,12 @@ static long writeback_sb_inodes(struct super_block *sb,
20142016
*/
20152017
__writeback_single_inode(inode, &wbc);
20162018

2019+
/* Report progress to inform the hung task detector of the progress. */
2020+
if (work->done && work->done->progress_stamp &&
2021+
(jiffies - work->done->progress_stamp) > HZ *
2022+
sysctl_hung_task_timeout_secs / 2)
2023+
wake_up_all(work->done->waitq);
2024+
20172025
wbc_detach_inode(&wbc);
20182026
work->nr_pages -= write_chunk - wbc.nr_to_write;
20192027
wrote = write_chunk - wbc.nr_to_write - wbc.pages_skipped;

include/linux/backing-dev-defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ enum wb_reason {
6363
struct wb_completion {
6464
atomic_t cnt;
6565
wait_queue_head_t *waitq;
66+
unsigned long progress_stamp; /* The jiffies when slow progress is detected */
6667
};
6768

6869
#define __WB_COMPLETION_INIT(_waitq) \

0 commit comments

Comments
 (0)