All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aaron Tomlin <atomlin@atomlin.com>
To: tj@kernel.org
Cc: jiangshanlai@gmail.com, rostedt@goodmis.org, mhiramat@kernel.org,
	osandov@osandov.com, atomlin@atomlin.com, neelx@suse.com,
	sean@ashe.io, marco.crivellari@suse.com,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org
Subject: [PATCH v2 2/3] workqueue: Add workqueue_mayday and workqueue_rescued tracepoints
Date: Fri,  4 Sep 2026 15:34:46 -0400	[thread overview]
Message-ID: <20260904193447.247502-3-atomlin@atomlin.com> (raw)
In-Reply-To: <20260904193447.247502-1-atomlin@atomlin.com>

When a worker pool fails to create a new worker thread within
MAYDAY_INTERVAL (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>
---
 include/trace/events/workqueue.h | 68 ++++++++++++++++++++++++++++++++
 kernel/workqueue.c               |  2 +
 2 files changed, 70 insertions(+)

diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h
index d2ad38f93a83..12ac24586835 100644
--- a/include/trace/events/workqueue.h
+++ b/include/trace/events/workqueue.h
@@ -165,6 +165,74 @@ TRACE_EVENT(workqueue_cpu_intensive,
 		  __entry->cpu, __entry->duration_us)
 );
 
+/**
+ * workqueue_mayday - called when a pool_workqueue sends mayday to rescuer
+ * @pwq:	pointer to struct pool_workqueue
+ *
+ * This event occurs when a worker pool fails to create a new worker
+ * within MAYDAY_INTERVAL and requests the workqueue's rescuer thread to
+ * process pending works.
+ */
+TRACE_EVENT(workqueue_mayday,
+
+	TP_PROTO(struct pool_workqueue *pwq),
+
+	TP_ARGS(pwq),
+
+	TP_STRUCT__entry(
+		__string( workqueue,	pwq->wq->name	)
+		__field( int,		pool_id		)
+		__field( int,		cpu		)
+		__field( int,		nr_active	)
+	),
+
+	TP_fast_assign(
+		__assign_str(workqueue);
+		__entry->pool_id	= pwq->pool->id;
+		__entry->cpu		= pwq->pool->cpu;
+		__entry->nr_active	= pwq->nr_active;
+	),
+
+	TP_printk("workqueue=%s pool_id=%d cpu=%d nr_active=%d",
+		  __get_str(workqueue), __entry->pool_id, __entry->cpu,
+		  __entry->nr_active)
+);
+
+/**
+ * workqueue_rescued - called when a work item is assigned to a rescuer
+ * @pwq:	pointer to struct pool_workqueue
+ * @work:	pointer to struct work_struct
+ * @function:	pointer to worker function
+ *
+ * This event occurs when a work item is claimed by a rescuer thread
+ * to guarantee forward progress.
+ */
+TRACE_EVENT(workqueue_rescued,
+
+	TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work,
+		 work_func_t function),
+
+	TP_ARGS(pwq, work, function),
+
+	TP_STRUCT__entry(
+		__field( void *,	work		)
+		__field( void *,	function	)
+		__string( workqueue,	pwq->wq->name	)
+		__field( int,		cpu		)
+	),
+
+	TP_fast_assign(
+		__entry->work		= work;
+		__entry->function	= function;
+		__assign_str(workqueue);
+		__entry->cpu		= pwq->pool->cpu;
+	),
+
+	TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d",
+		  __entry->work, __entry->function, __get_str(workqueue),
+		  __entry->cpu)
+);
+
 #endif /*  _TRACE_WORKQUEUE_H */
 
 /* This part must be outside protection */
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index bad1217cf45a..ab1371ed890a 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3124,6 +3124,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);
 	}
 }
 
@@ -3621,6 +3622,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;
-- 
2.55.0


  parent reply	other threads:[~2026-09-04 19:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-04 19:34 [PATCH v2 0/3] Add telemetry tracepoints for CPU hogs, distress, and BH budget yields Aaron Tomlin
2026-09-04 19:34 ` [PATCH v2 1/3] workqueue: Add workqueue_cpu_intensive tracepoint Aaron Tomlin
2026-09-04 19:34 ` Aaron Tomlin [this message]
2026-09-04 19:34 ` [PATCH v2 3/3] workqueue: Add workqueue_bh_budget_yield tracepoint Aaron Tomlin
2026-09-04 20:22 ` [PATCH v2 0/3] Add telemetry tracepoints for CPU hogs, distress, and BH budget yields Tejun Heo
2026-09-05 23:05   ` Aaron Tomlin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260904193447.247502-3-atomlin@atomlin.com \
    --to=atomlin@atomlin.com \
    --cc=jiangshanlai@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=marco.crivellari@suse.com \
    --cc=mhiramat@kernel.org \
    --cc=neelx@suse.com \
    --cc=osandov@osandov.com \
    --cc=rostedt@goodmis.org \
    --cc=sean@ashe.io \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.