From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
To: Tejun Heo <tj@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev,
Lai Jiangshan <jiangshanlai@gmail.com>,
Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Steven Rostedt <rostedt@goodmis.org>,
Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH] softirq: Provide a handshake for canceling tasklets via polling on PREEMPT_RT
Date: Wed, 20 Aug 2025 12:55:18 +0200 [thread overview]
Message-ID: <20250820105518.Yf36NzJd@linutronix.de> (raw)
In-Reply-To: <20250820103657.vDuDuLx6@linutronix.de>
On 2025-08-20 12:36:59 [+0200], To Tejun Heo wrote:
> Subject: [PATCH] workqueue: Provide a handshake for canceling BH workers
…
> This will flush all BH-work items assigned to that pool.
We need to flush all items because the inserted wq_barrier is at the
end of the queue. So if the cb_lock is dropped after
worker->current_func(work) then we will live lock. Just tested, I
somehow assumed it polls on worker.
This behaviour is undesired and goes back to the requirement to be able
to cancel something from an atomic context which can't be atomic on
PREEMPT_RT to begin with.
Since the caller can never be atomic on PREEMPT_RT, what about the
following:
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c6b79b3675c31..6ce9c980a7966 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4214,28 +4214,16 @@ static bool __flush_work(struct work_struct *work, bool from_cancel)
* can't currently be queued. Its data must contain OFFQ bits. If @work
* was queued on a BH workqueue, we also know that it was running in the
* BH context and thus can be busy-waited.
+ * On PREEMPT_RT the BH context can not be busy-waited because it can be
+ * preempted by the caller if it has higher priority.
*/
- if (from_cancel) {
+ if (from_cancel && !IS_ENABLED(CONFIG_PREEMPT_RT)) {
unsigned long data = *work_data_bits(work);
if (!WARN_ON_ONCE(data & WORK_STRUCT_PWQ) &&
(data & WORK_OFFQ_BH)) {
- /*
- * On RT, prevent a live lock when %current preempted
- * soft interrupt processing or prevents ksoftirqd from
- * running by keeping flipping BH. If the BH work item
- * runs on a different CPU then this has no effect other
- * than doing the BH disable/enable dance for nothing.
- * This is copied from
- * kernel/softirq.c::tasklet_unlock_spin_wait().
- */
while (!try_wait_for_completion(&barr.done)) {
- if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
- local_bh_disable();
- local_bh_enable();
- } else {
- cpu_relax();
- }
+ cpu_relax();
}
goto out_destroy;
}
@@ -4351,7 +4339,7 @@ static bool __cancel_work_sync(struct work_struct *work, u32 cflags)
ret = __cancel_work(work, cflags | WORK_CANCEL_DISABLE);
- if (*work_data_bits(work) & WORK_OFFQ_BH)
+ if (!IS_ENABLED(CONFIG_PREEMPT_RT) && *work_data_bits(work) & WORK_OFFQ_BH)
WARN_ON_ONCE(in_hardirq());
else
might_sleep();
It is not the revert I suggested.
This should work for softirq caller and from forced-thread interrupt
(not that I encourage such behaviour).
It will not work from an atomic context such as with raw_spinlock_t
acquired but this will also not work with the current
(local_bh_disable() + enable()) solution.
I prefer this because it avoids the locking bh_worker() and the flushing
of all pending work items the flush/ cancel case.
Sebastian
next prev parent reply other threads:[~2025-08-20 10:55 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-12 14:39 Sebastian Andrzej Siewior
2025-08-12 14:53 ` Sebastian Andrzej Siewior
2025-08-12 19:38 ` Tejun Heo
2025-08-13 6:33 ` Sebastian Andrzej Siewior
2025-08-13 18:05 ` Tejun Heo
2025-08-18 12:52 ` Sebastian Andrzej Siewior
2025-08-18 17:41 ` Tejun Heo
2025-08-19 15:01 ` Sebastian Andrzej Siewior
2025-08-20 10:36 ` Sebastian Andrzej Siewior
2025-08-20 10:55 ` Sebastian Andrzej Siewior [this message]
2025-08-20 19:44 ` Tejun Heo
2025-08-21 9:28 ` Sebastian Andrzej Siewior
2025-08-21 17:10 ` Tejun Heo
2025-08-22 9:48 ` Sebastian Andrzej Siewior
2025-08-22 18:07 ` Tejun Heo
2025-08-26 15:49 ` Sebastian Andrzej Siewior
2025-08-26 16:27 ` Tejun Heo
2025-08-28 16:04 ` Sebastian Andrzej Siewior
2025-08-29 19:34 ` Tejun Heo
2025-08-13 8:20 ` kernel test robot
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=20250820105518.Yf36NzJd@linutronix.de \
--to=bigeasy@linutronix.de \
--cc=jiangshanlai@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
--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®