summaryrefslogtreecommitdiff
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorAaron Tomlin <atomlin@atomlin.com>2026-09-04 15:34:46 -0400
committerTejun Heo <tj@kernel.org>2026-09-04 10:20:56 -1000
commita53b50e21af2eb8d4e74c8f84e409692a3332588 (patch)
treee54284332419793cb0101561fe6eabb81951fc11 /kernel/workqueue.c
parenta4d1cdc4356de4325b0a9c6fb09afa6e121407b5 (diff)
downloadlinux-next-a53b50e21af2eb8d4e74c8f84e409692a3332588.tar.gz
linux-next-a53b50e21af2eb8d4e74c8f84e409692a3332588.zip
workqueue: Add workqueue_mayday and workqueue_rescued tracepoints
When a worker pool fails to create a new worker thread (e.g., typically under severe memory pressure where memory reclaim paths depend on pending work items), send_mayday() signals distress to the workqueue's rescuer thread. The rescuer then takes over processing the pending work items via assign_rescuer_work(). While pwq->stats[PWQ_STAT_MAYDAY] and pwq->stats[PWQ_STAT_RESCUED] track these occurrences cumulatively, there is currently no event-driven mechanism to observe exactly when mayday distress occurs or which work items require rescue. Add two new tracepoints namely workqueue_mayday and workqueue_rescued to make distress and rescuer execution easily observable (e.g., via Ftrace or eBPF). Signed-off-by: Aaron Tomlin <atomlin@atomlin.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 22fb41b6ec26..53bb9ad56f49 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3127,6 +3127,7 @@ static void send_mayday(struct pool_workqueue *pwq)
list_add_tail(&pwq->mayday_node, &wq->maydays);
wake_up_process(wq->rescuer->task);
pwq->stats[PWQ_STAT_MAYDAY]++;
+ trace_workqueue_mayday(pwq);
}
}
@@ -3633,6 +3634,7 @@ static bool assign_rescuer_work(struct pool_workqueue *pwq, struct worker *rescu
list_for_each_entry_safe_from(work, n, &pool->worklist, entry) {
if (get_work_pwq(work) == pwq && assign_work(work, rescuer, &n)) {
pwq->stats[PWQ_STAT_RESCUED]++;
+ trace_workqueue_rescued(pwq, work, work->func);
/* put the cursor for next search */
list_move_tail(&cursor->entry, &n->entry);
return true;