From: Valentin Schneider <vschneid@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: Tejun Heo <tj@kernel.org>, Lai Jiangshan <jiangshanlai@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Frederic Weisbecker <frederic@kernel.org>,
Juri Lelli <juri.lelli@redhat.com>, Phil Auld <pauld@redhat.com>,
Marcelo Tosatti <mtosatti@redhat.com>
Subject: [PATCH v6 0/4] workqueue: destroy_worker() vs isolated CPUs
Date: Mon, 28 Nov 2022 18:31:05 +0000 [thread overview]
Message-ID: <20221128183109.446754-1-vschneid@redhat.com> (raw)
Hi folks,
This revision is mostly about getting work out of the timer callback and
into the new idle worker culling work item.
Revisions
=========
v5 -> v6
++++++++
o Rebase onto v6.1-rc7
o Get rid of worker_pool.idle_cull_list; only do minimal amount of work in the
timer callback (Tejun)
o Dropped the too_many_workers() -> nr_workers_to_cull() change
v4 -> v5
++++++++
o Rebase onto v6.1-rc6
o Overall renaming from "reaping" to "cull"
I somehow convinced myself this was more appropriate
o Split the dwork into timer callback + work item (Tejun)
I didn't want to have redudant operations happen in the timer callback and in
the work item, so I made the timer callback detect which workers are "ripe"
enough and then toss them to a worker for removal.
This however means we release the pool->lock before getting to actually doing
anything to those idle workers, which means they can wake up in the meantime.
The new worker_pool.idle_cull_list is there for that reason.
The alternative was to have the timer callback detect if any worker was ripe
enough, kick the work item if so, and have the work item do the same thing
again, which I didn't like.
RFCv3 -> v4
+++++++++++
o Rebase onto v6.0
o Split into more patches for reviewability
o Take dying workers out of the pool->workers as suggested by Lai
RFCv2 -> RFCv3
++++++++++++++
o Rebase onto v5.19
o Add new patch (1/3) around accessing wq_unbound_cpumask
o Prevent WORKER_DIE workers for kfree()'ing themselves before the idle reaper
gets to handle them (Tejun)
Bit of an aside on that: I've been struggling to convince myself this can
happen due to spurious wakeups and would like some help here.
Idle workers are TASK_UNINTERRUPTIBLE, so they can't be woken up by
signals. That state is set *under* pool->lock, and all wakeups (before this
patch) are also done while holding pool->lock.
wake_up_worker() is done under pool->lock AND only wakes a worker on the
pool->idle_list. Thus the to-be-woken worker *cannot* have WORKER_DIE, though
it could gain it *after* being woken but *before* it runs, e.g.:
LOCK pool->lock
wake_up_worker(pool)
wake_up_process(p)
UNLOCK pool->lock
idle_reaper_fn()
LOCK pool->lock
destroy_worker(worker, list);
UNLOCK pool->lock
worker_thread()
goto woke_up;
LOCK pool->lock
READ worker->flags & WORKER_DIE
UNLOCK pool->lock
...
kfree(worker);
reap_worker(worker);
// Uh-oh
... But IMO that's not a spurious wakeup, that's a concurrency issue. I don't
see any spurious/unexpected worker wakeup happening once a worker is off the
pool->idle_list.
RFCv1 -> RFCv2
++++++++++++++
o Change the pool->timer into a delayed_work to have a sleepable context for
unbinding kworkers
Cheers,
Valentin
Lai Jiangshan (1):
workqueue: Protects wq_unbound_cpumask with wq_pool_attach_mutex
Valentin Schneider (3):
workqueue: Factorize unbind/rebind_workers() logic
workqueue: Convert the idle_timer to a timer + work_struct
workqueue: Unbind kworkers before sending them to exit()
kernel/workqueue.c | 195 +++++++++++++++++++++++++++++++++------------
1 file changed, 143 insertions(+), 52 deletions(-)
--
2.31.1
next reply other threads:[~2022-11-28 18:34 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-28 18:31 Valentin Schneider [this message]
2022-11-28 18:31 ` [PATCH v6 1/4] workqueue: Protects wq_unbound_cpumask with wq_pool_attach_mutex Valentin Schneider
2022-11-28 18:31 ` [PATCH v6 2/4] workqueue: Factorize unbind/rebind_workers() logic Valentin Schneider
2022-11-28 18:31 ` [PATCH v6 3/4] workqueue: Convert the idle_timer to a timer + work_struct Valentin Schneider
2022-11-30 21:06 ` Tejun Heo
2022-12-01 11:01 ` Valentin Schneider
2022-11-28 18:31 ` [PATCH v6 4/4] workqueue: Unbind kworkers before sending them to exit() Valentin Schneider
2022-12-01 3:01 ` Lai Jiangshan
2022-12-01 10:37 ` Valentin Schneider
2022-11-30 21:06 ` [PATCH v6 0/4] workqueue: destroy_worker() vs isolated CPUs Tejun Heo
2022-12-01 3:05 ` Lai Jiangshan
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=20221128183109.446754-1-vschneid@redhat.com \
--to=vschneid@redhat.com \
--cc=frederic@kernel.org \
--cc=jiangshanlai@gmail.com \
--cc=juri.lelli@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mtosatti@redhat.com \
--cc=pauld@redhat.com \
--cc=peterz@infradead.org \
--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
all inboxes | Powered by JetHome®