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 3/3] workqueue: Add workqueue_bh_budget_yield tracepoint
Date: Fri, 4 Sep 2026 15:34:47 -0400 [thread overview]
Message-ID: <20260904193447.247502-4-atomlin@atomlin.com> (raw)
In-Reply-To: <20260904193447.247502-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 | 26 +++++++++++++++++++--
2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h
index 12ac24586835..bbba34e40470 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 ab1371ed890a..74f595396227 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3758,6 +3758,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 restarts = 0;
worker_lock_callback(pool);
raw_spin_lock_irq(&pool->lock);
@@ -3780,8 +3783,23 @@ static void bh_worker(struct worker *worker)
if (assign_work(work, worker, NULL))
process_scheduled_works(worker);
- } while (keep_working(pool) &&
- --nr_restarts && time_before(jiffies, end));
+
+ if (!keep_working(pool))
+ break;
+
+ if (!--nr_restarts) {
+ budget_exhausted = true;
+ break;
+ }
+
+ if (!time_before(jiffies, end)) {
+ budget_exhausted = true;
+ timeout = true;
+ break;
+ }
+
+ restarts++;
+ } while (1);
worker_set_flags(worker, WORKER_PREP);
done:
@@ -3789,6 +3807,10 @@ static void bh_worker(struct worker *worker)
kick_pool(pool);
raw_spin_unlock_irq(&pool->lock);
worker_unlock_callback(pool);
+
+ if (budget_exhausted)
+ trace_workqueue_bh_budget_yield(pool, restarts, timeout,
+ pool->attrs->nice == HIGHPRI_NICE_LEVEL);
}
/*
--
2.55.0
next prev 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 ` [PATCH v2 2/3] workqueue: Add workqueue_mayday and workqueue_rescued tracepoints Aaron Tomlin
2026-09-04 19:34 ` Aaron Tomlin [this message]
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-4-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.