mirror of
https://github.com/torvalds/linux.git
synced 2026-03-09 18:16:36 +01:00
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>
This commit is contained in:
parent
3a86608788
commit
1888635532
2 changed files with 10 additions and 1 deletions
|
|
@ -14,6 +14,7 @@
|
|||
* Additions for address_space-based writeback
|
||||
*/
|
||||
|
||||
#include <linux/sched/sysctl.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
|
@ -213,7 +214,8 @@ static void wb_queue_work(struct bdi_writeback *wb,
|
|||
void wb_wait_for_completion(struct wb_completion *done)
|
||||
{
|
||||
atomic_dec(&done->cnt); /* put down the initial count */
|
||||
wait_event(*done->waitq, !atomic_read(&done->cnt));
|
||||
wait_event(*done->waitq,
|
||||
({ done->progress_stamp = jiffies; !atomic_read(&done->cnt); }));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CGROUP_WRITEBACK
|
||||
|
|
@ -2014,6 +2016,12 @@ static long writeback_sb_inodes(struct super_block *sb,
|
|||
*/
|
||||
__writeback_single_inode(inode, &wbc);
|
||||
|
||||
/* Report progress to inform the hung task detector of the progress. */
|
||||
if (work->done && work->done->progress_stamp &&
|
||||
(jiffies - work->done->progress_stamp) > HZ *
|
||||
sysctl_hung_task_timeout_secs / 2)
|
||||
wake_up_all(work->done->waitq);
|
||||
|
||||
wbc_detach_inode(&wbc);
|
||||
work->nr_pages -= write_chunk - wbc.nr_to_write;
|
||||
wrote = write_chunk - wbc.nr_to_write - wbc.pages_skipped;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ enum wb_reason {
|
|||
struct wb_completion {
|
||||
atomic_t cnt;
|
||||
wait_queue_head_t *waitq;
|
||||
unsigned long progress_stamp; /* The jiffies when slow progress is detected */
|
||||
};
|
||||
|
||||
#define __WB_COMPLETION_INIT(_waitq) \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue