LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: maxk@qualcomm.com
To: linux-kernel@vger.kernel.org
Cc: Max Krasnyansky <maxk@qualcomm.com>
Subject: [PATCH] [CPUISOL] Support for workqueue isolation
Date: Sun, 27 Jan 2008 20:09:41 -0800 [thread overview]
Message-ID: <1201493382-29804-5-git-send-email-maxk@qualcomm.com> (raw)
In-Reply-To: <1201493382-29804-4-git-send-email-maxk@qualcomm.com>
From: Max Krasnyansky <maxk@qualcomm.com>
I'm sure this one is going to be controversial for a lot of folks here.
So let me explain :).
What this patch is trying to address is the case when a high priority
realtime (FIFO, RR) user-space thread is using 100% CPU for extended periods
of time. In which case kernel workqueue threads do not get a chance to run and
entire machine essentially hangs because other CPUs are waiting for scheduled
workqueues to flush.
This use case is perfectly valid if one is using a CPU as a dedicated engine
(crunching numbers, hard realtime, etc). Think of it as an SPE in the Cell processor.
Which is what CPU isolation enables in first place.
Most kernel subsystems do not rely on the per CPU workqueues. In fact we already
have support for single threaded workqueues, this patch just makes it automatic.
Some subsystems namely OProfile do rely on per CPU workqueues and do not work when
this feature is enabled. It does not result in crashes or anything OProfile is just
unable to collect stats from isolated CPUs. Hence this feature is marked as
experimental.
There is zero overhead if CPU workqueue isolation is disabled.
Better ideas/suggestions on how to handle use case described above are welcome
of course.
Signed-off-by: Max Krasnyansky <maxk@qualcomm.com>
---
kernel/workqueue.c | 30 +++++++++++++++++++++++-------
1 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 52db48e..ed2f09b 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -35,6 +35,16 @@
#include <linux/lockdep.h>
/*
+ * Stub out cpu_isolated() if isolated CPUs are allowed to
+ * run workqueues.
+ */
+#ifdef CONFIG_CPUISOL_WORKQUEUE
+#define cpu_unusable(cpu) cpu_isolated(cpu)
+#else
+#define cpu_unusable(cpu) (0)
+#endif
+
+/*
* The per-CPU workqueue (if single thread, we always use the first
* possible cpu).
*/
@@ -97,7 +107,7 @@ static const cpumask_t *wq_cpu_map(struct workqueue_struct *wq)
static
struct cpu_workqueue_struct *wq_per_cpu(struct workqueue_struct *wq, int cpu)
{
- if (unlikely(is_single_threaded(wq)))
+ if (unlikely(is_single_threaded(wq)) || cpu_unusable(cpu))
cpu = singlethread_cpu;
return per_cpu_ptr(wq->cpu_wq, cpu);
}
@@ -229,9 +239,11 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
timer->data = (unsigned long)dwork;
timer->function = delayed_work_timer_fn;
- if (unlikely(cpu >= 0))
+ if (unlikely(cpu >= 0)) {
+ if (cpu_unusable(cpu))
+ cpu = singlethread_cpu;
add_timer_on(timer, cpu);
- else
+ } else
add_timer(timer);
ret = 1;
}
@@ -605,7 +617,8 @@ int schedule_on_each_cpu(work_func_t func)
get_online_cpus();
for_each_online_cpu(cpu) {
struct work_struct *work = per_cpu_ptr(works, cpu);
-
+ if (cpu_unusable(cpu))
+ continue;
INIT_WORK(work, func);
set_bit(WORK_STRUCT_PENDING, work_data_bits(work));
__queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), work);
@@ -754,7 +767,7 @@ struct workqueue_struct *__create_workqueue_key(const char *name,
for_each_possible_cpu(cpu) {
cwq = init_cpu_workqueue(wq, cpu);
- if (err || !cpu_online(cpu))
+ if (err || !cpu_online(cpu) || cpu_unusable(cpu))
continue;
err = create_workqueue_thread(cwq, cpu);
start_workqueue_thread(cwq, cpu);
@@ -833,8 +846,11 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
struct cpu_workqueue_struct *cwq;
struct workqueue_struct *wq;
- action &= ~CPU_TASKS_FROZEN;
+ if (cpu_unusable(cpu))
+ return NOTIFY_OK;
+ action &= ~CPU_TASKS_FROZEN;
+
switch (action) {
case CPU_UP_PREPARE:
@@ -869,7 +885,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
void __init init_workqueues(void)
{
- cpu_populated_map = cpu_online_map;
+ cpus_andnot(cpu_populated_map, cpu_online_map, cpu_isolated_map);
singlethread_cpu = first_cpu(cpu_possible_map);
cpu_singlethread_map = cpumask_of_cpu(singlethread_cpu);
hotcpu_notifier(workqueue_cpu_callback, 0);
--
1.5.3.7
next prev parent reply other threads:[~2008-01-28 4:34 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-28 4:09 [CPUISOL] CPU isolation extensions maxk
2008-01-28 4:09 ` [PATCH] [CPUISOL] Add config options for CPU isolation maxk
2008-01-28 4:09 ` [PATCH] [CPUISOL] Export CPU isolation bits maxk
2008-01-28 4:09 ` [PATCH] [CPUISOL] Do not route IRQs to the CPUs isolated at boot maxk
2008-01-28 4:09 ` maxk [this message]
2008-01-28 4:09 ` [PATCH] [CPUISOL] Isolated CPUs should be ignored by the "stop machine" maxk
2008-01-28 9:08 ` [CPUISOL] CPU isolation extensions Peter Zijlstra
2008-01-28 14:59 ` Paul Jackson
2008-01-28 16:34 ` Steven Rostedt
2008-01-28 16:44 ` Peter Zijlstra
2008-01-28 18:54 ` Max Krasnyanskiy
2008-01-28 18:46 ` Max Krasnyanskiy
2008-01-28 19:00 ` Steven Rostedt
2008-01-28 20:22 ` Peter Zijlstra
2008-01-28 21:42 ` Max Krasnyanskiy
2008-02-05 0:32 ` CPU isolation and workqueues [was Re: [CPUISOL] CPU isolation extensions] Max Krasnyanskiy
2008-01-28 18:37 ` [CPUISOL] CPU isolation extensions Max Krasnyanskiy
2008-01-28 19:06 ` Paul Jackson
2008-01-28 21:47 ` Max Krasnyanskiy
2008-01-31 19:06 ` Integrating cpusets and cpu isolation [was Re: [CPUISOL] CPU isolation extensions] Max Krasnyanskiy
2008-02-02 6:16 ` Paul Jackson
2008-02-03 5:57 ` Max Krasnyansky
2008-02-03 7:53 ` Paul Jackson
2008-02-04 6:03 ` Max Krasnyansky
2008-02-04 10:54 ` Paul Jackson
2008-02-04 23:19 ` Max Krasnyanskiy
2008-02-05 2:46 ` Paul Jackson
2008-02-05 4:08 ` Max Krasnyansky
2008-01-28 18:32 ` [CPUISOL] CPU isolation extensions Max Krasnyanskiy
2008-01-28 19:10 ` Paul Jackson
2008-01-28 23:41 ` Daniel Walker
2008-01-29 0:12 ` Max Krasnyanskiy
2008-01-29 1:33 ` Daniel Walker
2008-02-04 6:53 ` Max Krasnyansky
2008-01-31 12:16 ` Mark Hounschell
2008-01-31 19:13 ` Max Krasnyanskiy
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=1201493382-29804-5-git-send-email-maxk@qualcomm.com \
--to=maxk@qualcomm.com \
--cc=linux-kernel@vger.kernel.org \
--subject='Re: [PATCH] [CPUISOL] Support for workqueue isolation' \
/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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).