All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aaron Tomlin <atomlin@atomlin.com>
To: tj@kernel.org
Cc: jianshanlai@mail.com, rostedt@goodmis.org, mhiramat@kernel.org,
	osandov@osandov.com, atomlin@atomlin.com, neelx@suse.com,
	sean@ashe.io, linux-kernel@vger.kernel.org,
	linux-trace-kernel@vger.kernel.org
Subject: [PATCH 3/3] workqueue: Add workqueue_bh_budget_yield tracepoint
Date: Sat, 29 Aug 2026 19:05:17 -0400	[thread overview]
Message-ID: <20260829230517.42468-4-atomlin@atomlin.com> (raw)
In-Reply-To: <20260829230517.42468-1-atomlin@atomlin.com>

Bottom-Half (BH) workqueues execute work items in softirq context.
To prevent softirqs from starving user and kernel threads, bh_worker()
enforces execution limits (i.e., BH_WORKER_JIFFIES and BH_WORKER_RESTARTS).

When keep_working() is still true but either the time slice or restart
count is exhausted, bh_worker() yields execution and re-raises the
softirq via kick_bh_pool().

Currently, there is no observability into when a BH worker hits these
limits and is forced to yield.

Add the workqueue_bh_budget_yield tracepoint, emitted when bh_worker()
exits the processing loop with pending work items remaining. It records,
the worker pool ID, executing CPU, number of loop restarts consumed, a
boolean flag indicating whether the yield was due to a time slice
timeout, and a boolean flag indicating whether this is a high-priority
BH pool.

Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
 include/trace/events/workqueue.h | 39 ++++++++++++++++++++++++++++++++
 kernel/workqueue.c               | 13 +++++++++++
 2 files changed, 52 insertions(+)

diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h
index 013cfa472f6d..ad1d0ff1a96d 100644
--- a/include/trace/events/workqueue.h
+++ b/include/trace/events/workqueue.h
@@ -9,6 +9,7 @@
 #include <linux/workqueue.h>
 
 struct pool_workqueue;
+struct worker_pool;
 
 /**
  * workqueue_queue_work - called when a work gets queued
@@ -233,6 +234,44 @@ TRACE_EVENT(workqueue_rescued,
 		  __entry->cpu)
 );
 
+/**
+ * workqueue_bh_budget_yield - called when a BH worker yields due to budget exhaustion
+ * @pool:	pointer to struct worker_pool
+ * @restarts:	number of restarts executed
+ * @timeout:	whether execution hit the time limit (BH_WORKER_JIFFIES)
+ * @highpri:	whether this is a high-priority BH pool
+ *
+ * This event occurs when a bottom-half (BH) worker pool running in softirq
+ * context exhausts its execution time slice or restart limit and must yield
+ * execution.
+ */
+TRACE_EVENT(workqueue_bh_budget_yield,
+
+	TP_PROTO(struct worker_pool *pool, int restarts, bool timeout, bool highpri),
+
+	TP_ARGS(pool, restarts, timeout, highpri),
+
+	TP_STRUCT__entry(
+		__field( int,	pool_id		)
+		__field( int,	cpu		)
+		__field( int,	restarts	)
+		__field( bool,	timeout		)
+		__field( bool,	highpri		)
+	),
+
+	TP_fast_assign(
+		__entry->pool_id	= pool->id;
+		__entry->cpu		= pool->cpu;
+		__entry->restarts	= restarts;
+		__entry->timeout	= timeout;
+		__entry->highpri	= highpri;
+	),
+
+	TP_printk("pool_id=%d cpu=%d restarts=%d timeout=%d highpri=%d",
+		  __entry->pool_id, __entry->cpu, __entry->restarts,
+		  __entry->timeout, __entry->highpri)
+);
+
 #endif /*  _TRACE_WORKQUEUE_H */
 
 /* This part must be outside protection */
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 6f6fe2068389..1c25df68f7ae 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3756,6 +3756,9 @@ static void bh_worker(struct worker *worker)
 	struct worker_pool *pool = worker->pool;
 	int nr_restarts = BH_WORKER_RESTARTS;
 	unsigned long end = jiffies + BH_WORKER_JIFFIES;
+	bool budget_exhausted = false;
+	bool timeout = false;
+	int executed_restarts = 0;
 
 	worker_lock_callback(pool);
 	raw_spin_lock_irq(&pool->lock);
@@ -3781,12 +3784,22 @@ static void bh_worker(struct worker *worker)
 	} while (keep_working(pool) &&
 		 --nr_restarts && time_before(jiffies, end));
 
+	if (keep_working(pool)) {
+		budget_exhausted = true;
+		timeout = !time_before(jiffies, end);
+		executed_restarts = BH_WORKER_RESTARTS - nr_restarts;
+	}
+
 	worker_set_flags(worker, WORKER_PREP);
 done:
 	worker_enter_idle(worker);
 	kick_pool(pool);
 	raw_spin_unlock_irq(&pool->lock);
 	worker_unlock_callback(pool);
+
+	if (budget_exhausted)
+		trace_workqueue_bh_budget_yield(pool, executed_restarts, timeout,
+						pool->attrs->nice == HIGHPRI_NICE_LEVEL);
 }
 
 /*
-- 
2.55.0


  parent reply	other threads:[~2026-08-29 23:05 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-29 23:05 [PATCH 0/3] workqueue: Add telemetry tracepoints for CPU hogs, distress, and BH budget yields Aaron Tomlin
2026-08-29 23:05 ` [PATCH 1/3] workqueue: Add workqueue_cpu_intensive tracepoint Aaron Tomlin
2026-08-29 23:14   ` sashiko-bot
2026-08-29 23:05 ` [PATCH 2/3] workqueue: Add workqueue_mayday and workqueue_rescued tracepoints Aaron Tomlin
2026-08-29 23:05 ` Aaron Tomlin [this message]
2026-08-31 17:41   ` [PATCH 3/3] workqueue: Add workqueue_bh_budget_yield tracepoint kernel test robot
2026-08-31 21:08 ` [PATCH 0/3] workqueue: Add telemetry tracepoints for CPU hogs, distress, and BH budget yields Tejun Heo

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=20260829230517.42468-4-atomlin@atomlin.com \
    --to=atomlin@atomlin.com \
    --cc=jianshanlai@mail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --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.