writeback: Add logging for slow writeback (exceeds sysctl_hung_task_timeout_secs)

When a writeback work lasts for sysctl_hung_task_timeout_secs, we want
to identify that there are tasks waiting for a long time-this helps us
pinpoint potential issues.

Additionally, recording the starting jiffies is useful when debugging a
crashed vmcore.

Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Julian Sun 2025-09-30 15:18:29 +08:00 committed by Christian Brauner
parent 1888635532
commit d6e6215907
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
2 changed files with 16 additions and 2 deletions

View File

@ -201,6 +201,19 @@ static void wb_queue_work(struct bdi_writeback *wb,
spin_unlock_irq(&wb->work_lock);
}
static bool wb_wait_for_completion_cb(struct wb_completion *done)
{
unsigned long waited_secs = (jiffies - done->wait_start) / HZ;
done->progress_stamp = jiffies;
if (waited_secs > sysctl_hung_task_timeout_secs)
pr_info("INFO: The task %s:%d has been waiting for writeback "
"completion for more than %lu seconds.",
current->comm, current->pid, waited_secs);
return !atomic_read(&done->cnt);
}
/**
* wb_wait_for_completion - wait for completion of bdi_writeback_works
* @done: target wb_completion
@ -213,9 +226,9 @@ static void wb_queue_work(struct bdi_writeback *wb,
*/
void wb_wait_for_completion(struct wb_completion *done)
{
done->wait_start = jiffies;
atomic_dec(&done->cnt); /* put down the initial count */
wait_event(*done->waitq,
({ done->progress_stamp = jiffies; !atomic_read(&done->cnt); }));
wait_event(*done->waitq, wb_wait_for_completion_cb(done));
}
#ifdef CONFIG_CGROUP_WRITEBACK

View File

@ -64,6 +64,7 @@ struct wb_completion {
atomic_t cnt;
wait_queue_head_t *waitq;
unsigned long progress_stamp; /* The jiffies when slow progress is detected */
unsigned long wait_start; /* The jiffies when waiting for the writeback work to finish */
};
#define __WB_COMPLETION_INIT(_waitq) \