From: Breno Leitao <leitao@debian.org>
To: Tejun Heo <tj@kernel.org>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>,
linux-kernel@vger.kernel.org, marco.crivellari@suse.com,
frederic@kernel.org, bigeasy@linutronix.de,
Hillf Danton <hdanton@sina.com>,
kernel-team@meta.com
Subject: Re: [PATCH v2 1/4] workqueue: park kicked worker on pool->kicked_list
Date: Fri, 5 Jun 2026 07:40:43 -0700 [thread overview]
Message-ID: <aiLSOAcx_v1rrMdD@gmail.com> (raw)
In-Reply-To: <aiE8RZCHvpqh_V2H@slm.duckdns.org>
Hello Tejun,
On Wed, Jun 03, 2026 at 10:50:13PM -1000, Tejun Heo wrote:
> On Wed, Jun 03, 2026 at 06:40:08AM -0700, Breno Leitao wrote:
> > kick_pool() picks an idle worker and wakes it, but leaves it WORKER_IDLE
> > on pool->idle_list until the woken kthread schedules in and runs
> > worker_leave_idle(). idle_cull_fn() only checks WORKER_IDLE, not the
>
> A lot of the existing comments in the file are double spaced but let's not
> do that anymore. Please use single space to separate sentences in desc and
> comments.
I suppose you mean double space after double space? Sorry, I will avoid
it.
> > task state, so a kicked-but-not-yet-scheduled worker is still a valid
> > cull victim -- the cull can reap it before it consumes the just-enqueued
> > work, stranding the item. The window is narrow today but later patches
> > in this series defer the wakeup outside pool->lock, widening it.
>
> Have you actually reproduced this?
No -- not without artificially changing the timeout in the kernel. So far this
is a theoretical race window rather than something I've hit in
practice; it was flagged as a critical issue by sashiko:
https://sashiko.dev/#/patchset/20260526-fastwake-v1-0-e69ad86923e6%40debian.org
The only way I could get it to actually strand an item was by shrinking
IDLE_WORKER_TIMEOUT 150,000x (300s -> 2ms), so that a worker counts as
"timed out" almost immediately.
> Idle culling never dips below 2 idle workers. Wakeup is from the head
> of the list and culling from the end.
Right -- idle_cull_fn() reaps from the tail (list_last_entry), i.e. the
worker with the oldest last_active, and stops once nr_idle drops to 2,
while kick_pool() wakes the head. So in the common case the kicked
worker (head) and the cull victim (tail) are different workers.
What I'm less sure about: the cull decision is purely time based -- it
reaps the tail worker only if worker->last_active + IDLE_WORKER_TIMEOUT
has elapsed -- but last_active is written in exactly one place,
worker_enter_idle(). Neither kick_pool()/kick_pool_pick() nor
worker_leave_idle() update it; it is only read by the two cull timers.
So being kicked gives a worker no grace period against the cull: a
worker that has already been idle ~IDLE_WORKER_TIMEOUT and is then
kicked still looks expired, and if it drifts off the head (other
workers going idle ahead of it) before it gets a chance to run, the
cull can still reap it.
Would it make sense to refresh last_active when a worker is kicked? The
cull walks tail->head and breaks at the first non-expired worker, so a
freshly-stamped kicked worker would simply be skipped while genuinely
old workers behind it are still reaped.
Thanks for the review,
--breno
next prev parent reply other threads:[~2026-06-05 14:41 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-03 13:40 [PATCH v2 0/4] workqueue: Shrink the lock time Breno Leitao
2026-06-03 13:40 ` [PATCH v2 1/4] workqueue: park kicked worker on pool->kicked_list Breno Leitao
2026-06-04 8:50 ` Tejun Heo
2026-06-05 14:40 ` Breno Leitao [this message]
2026-06-05 17:30 ` Tejun Heo
2026-06-03 13:40 ` [PATCH v2 2/4] workqueue: split kick_pool() into kick_pool_pick() + wake_up_q() Breno Leitao
2026-06-03 13:40 ` [PATCH v2 3/4] workqueue: defer the worker wakeup outside pool->lock in __queue_work() Breno Leitao
2026-06-03 13:40 ` [PATCH v2 4/4] workqueue: defer the worker wakeup outside pool->lock in process_one_work() Breno Leitao
2026-06-04 8:50 ` Tejun Heo
2026-06-04 15:29 ` Breno Leitao
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=aiLSOAcx_v1rrMdD@gmail.com \
--to=leitao@debian.org \
--cc=bigeasy@linutronix.de \
--cc=frederic@kernel.org \
--cc=hdanton@sina.com \
--cc=jiangshanlai@gmail.com \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marco.crivellari@suse.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox