From: Tejun Heo <tj@kernel.org>
To: mingo@elte.hu, awalls@radix.net, linux-kernel@vger.kernel.org,
jeff@garzik.org, akpm@linux-foundation.org,
rusty@rustcorp.com.au, cl@linux-foundation.org,
dhowells@redhat.com, arjan@linux.intel.com,
johannes@sipsolutions.net, oleg@redhat.com, axboe@kernel.dk
Cc: Tejun Heo <tj@kernel.org>, Thomas Gleixner <tglx@linutronix.de>,
Tony Luck <tony.luck@intel.com>, Andi Kleen <ak@linux.intel.com>
Subject: [PATCH 25/30] workqueue: increase max_active of keventd and kill current_is_keventd()
Date: Mon, 14 Jun 2010 23:37:42 +0200 [thread overview]
Message-ID: <1276551467-21246-26-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1276551467-21246-1-git-send-email-tj@kernel.org>
Define WQ_MAX_ACTIVE and create keventd with max_active set to half of
it which means that keventd now can process upto WQ_MAX_ACTIVE / 2 - 1
works concurrently. Unless some combination can result in dependency
loop longer than max_active, deadlock won't happen and thus it's
unnecessary to check whether current_is_keventd() before trying to
schedule a work. Kill current_is_keventd().
(Lockdep annotations are broken. We need lock_map_acquire_read_norecurse())
NOT_SIGNED_OFF_YET: Tejun Heo <tj@kernel.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Christoph Lameter <cl@linux-foundation.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Oleg Nesterov <oleg@redhat.com>
---
arch/ia64/kernel/smpboot.c | 2 +-
arch/x86/kernel/smpboot.c | 2 +-
include/linux/workqueue.h | 4 ++-
kernel/workqueue.c | 63 +++++++++----------------------------------
4 files changed, 18 insertions(+), 53 deletions(-)
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 6a1380e..99dcc85 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -519,7 +519,7 @@ do_boot_cpu (int sapicid, int cpu)
/*
* We can't use kernel_thread since we must avoid to reschedule the child.
*/
- if (!keventd_up() || current_is_keventd())
+ if (!keventd_up())
c_idle.work.func(&c_idle.work);
else {
schedule_work(&c_idle.work);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index c4f33b2..4d90f37 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -735,7 +735,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
goto do_rest;
}
- if (!keventd_up() || current_is_keventd())
+ if (!keventd_up())
c_idle.work.func(&c_idle.work);
else {
schedule_work(&c_idle.work);
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index b8f4ec4..33e24e7 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -227,6 +227,9 @@ enum {
WQ_SINGLE_CPU = 1 << 1, /* only single cpu at a time */
WQ_NON_REENTRANT = 1 << 2, /* guarantee non-reentrance */
WQ_RESCUER = 1 << 3, /* has an rescue worker */
+
+ WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */
+ WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2,
};
extern struct workqueue_struct *
@@ -280,7 +283,6 @@ extern int schedule_delayed_work(struct delayed_work *work, unsigned long delay)
extern int schedule_delayed_work_on(int cpu, struct delayed_work *work,
unsigned long delay);
extern int schedule_on_each_cpu(work_func_t func);
-extern int current_is_keventd(void);
extern int keventd_up(void);
extern void init_workqueues(void);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index dd8c38b..9f22dbd 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2343,7 +2343,6 @@ EXPORT_SYMBOL(schedule_delayed_work_on);
int schedule_on_each_cpu(work_func_t func)
{
int cpu;
- int orig = -1;
struct work_struct *works;
works = alloc_percpu(struct work_struct);
@@ -2352,23 +2351,12 @@ int schedule_on_each_cpu(work_func_t func)
get_online_cpus();
- /*
- * When running in keventd don't schedule a work item on
- * itself. Can just call directly because the work queue is
- * already bound. This also is faster.
- */
- if (current_is_keventd())
- orig = raw_smp_processor_id();
-
for_each_online_cpu(cpu) {
struct work_struct *work = per_cpu_ptr(works, cpu);
INIT_WORK(work, func);
- if (cpu != orig)
- schedule_work_on(cpu, work);
+ schedule_work_on(cpu, work);
}
- if (orig >= 0)
- func(per_cpu_ptr(works, orig));
for_each_online_cpu(cpu)
flush_work(per_cpu_ptr(works, cpu));
@@ -2439,41 +2427,6 @@ int keventd_up(void)
return keventd_wq != NULL;
}
-int current_is_keventd(void)
-{
- bool found = false;
- unsigned int cpu;
-
- /*
- * There no longer is one-to-one relation between worker and
- * work queue and a worker task might be unbound from its cpu
- * if the cpu was offlined. Match all busy workers. This
- * function will go away once dynamic pool is implemented.
- */
- for_each_possible_cpu(cpu) {
- struct global_cwq *gcwq = get_gcwq(cpu);
- struct worker *worker;
- struct hlist_node *pos;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&gcwq->lock, flags);
-
- for_each_busy_worker(worker, i, pos, gcwq) {
- if (worker->task == current) {
- found = true;
- break;
- }
- }
-
- spin_unlock_irqrestore(&gcwq->lock, flags);
- if (found)
- break;
- }
-
- return found;
-}
-
static struct cpu_workqueue_struct *alloc_cwqs(void)
{
const size_t size = sizeof(struct cpu_workqueue_struct);
@@ -2515,6 +2468,16 @@ static void free_cwqs(struct cpu_workqueue_struct *cwqs)
#endif
}
+static int wq_clamp_max_active(int max_active, const char *name)
+{
+ if (max_active < 1 || max_active > WQ_MAX_ACTIVE)
+ printk(KERN_WARNING "workqueue: max_active %d requested for %s "
+ "is out of range, clamping between %d and %d\n",
+ max_active, name, 1, WQ_MAX_ACTIVE);
+
+ return clamp_val(max_active, 1, WQ_MAX_ACTIVE);
+}
+
struct workqueue_struct *__create_workqueue_key(const char *name,
unsigned int flags,
int max_active,
@@ -2524,7 +2487,7 @@ struct workqueue_struct *__create_workqueue_key(const char *name,
struct workqueue_struct *wq;
unsigned int cpu;
- max_active = clamp_val(max_active, 1, INT_MAX);
+ max_active = wq_clamp_max_active(max_active, name);
wq = kzalloc(sizeof(*wq), GFP_KERNEL);
if (!wq)
@@ -3272,6 +3235,6 @@ void __init init_workqueues(void)
spin_unlock_irq(&gcwq->lock);
}
- keventd_wq = create_workqueue("events");
+ keventd_wq = __create_workqueue("events", 0, WQ_DFL_ACTIVE);
BUG_ON(!keventd_wq);
}
--
1.6.4.2
next prev parent reply other threads:[~2010-06-14 21:44 UTC|newest]
Thread overview: 129+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-14 21:37 [PATCHSET] workqueue: concurrency managed workqueue, take#5 Tejun Heo
2010-06-14 21:37 ` [PATCH 01/30] kthread: implement kthread_data() Tejun Heo
2010-06-14 21:37 ` [PATCH 02/30] acpi: use queue_work_on() instead of binding workqueue worker to cpu0 Tejun Heo
2010-06-14 21:37 ` [PATCH 03/30] workqueue: kill RT workqueue Tejun Heo
2010-06-14 21:37 ` [PATCH 04/30] workqueue: misc/cosmetic updates Tejun Heo
2010-06-14 21:37 ` [PATCH 05/30] workqueue: merge feature parameters into flags Tejun Heo
2010-06-14 21:37 ` [PATCH 06/30] workqueue: define masks for work flags and conditionalize STATIC flags Tejun Heo
2010-06-14 21:37 ` [PATCH 07/30] workqueue: separate out process_one_work() Tejun Heo
2010-06-14 21:37 ` [PATCH 08/30] workqueue: temporarily disable workqueue tracing Tejun Heo
2010-06-15 13:29 ` Frederic Weisbecker
2010-06-15 16:37 ` Tejun Heo
2010-06-14 21:37 ` [PATCH 09/30] workqueue: kill cpu_populated_map Tejun Heo
2010-06-14 21:37 ` [PATCH 10/30] workqueue: update cwq alignement Tejun Heo
2010-06-14 21:37 ` [PATCH 11/30] workqueue: reimplement workqueue flushing using color coded works Tejun Heo
2010-06-14 21:37 ` [PATCH 12/30] workqueue: introduce worker Tejun Heo
2010-06-14 21:37 ` [PATCH 13/30] workqueue: reimplement work flushing using linked works Tejun Heo
2010-06-14 21:37 ` [PATCH 14/30] workqueue: implement per-cwq active work limit Tejun Heo
2010-06-14 21:37 ` [PATCH 15/30] workqueue: reimplement workqueue freeze using max_active Tejun Heo
2010-06-14 21:37 ` [PATCH 16/30] workqueue: introduce global cwq and unify cwq locks Tejun Heo
2010-06-14 21:37 ` [PATCH 17/30] workqueue: implement worker states Tejun Heo
2010-06-14 21:37 ` [PATCH 18/30] workqueue: reimplement CPU hotplugging support using trustee Tejun Heo
2010-06-14 21:37 ` [PATCH 19/30] workqueue: make single thread workqueue shared worker pool friendly Tejun Heo
2010-06-14 21:37 ` [PATCH 20/30] workqueue: add find_worker_executing_work() and track current_cwq Tejun Heo
2010-06-14 21:37 ` [PATCH 21/30] workqueue: carry cpu number in work data once execution starts Tejun Heo
2010-06-14 21:37 ` [PATCH 22/30] workqueue: implement WQ_NON_REENTRANT Tejun Heo
2010-06-14 21:37 ` [PATCH 23/30] workqueue: use shared worklist and pool all workers per cpu Tejun Heo
2010-06-14 21:37 ` [PATCH 24/30] workqueue: implement concurrency managed dynamic worker pool Tejun Heo
2010-06-14 21:37 ` Tejun Heo [this message]
2010-06-14 21:37 ` [PATCH 26/30] workqueue: add system_wq, system_long_wq and system_nrt_wq Tejun Heo
2010-06-14 21:37 ` [PATCH 27/30] workqueue: implement DEBUGFS/workqueue Tejun Heo
2010-06-15 13:54 ` Frederic Weisbecker
2010-06-15 16:42 ` Tejun Heo
2010-06-14 21:37 ` [PATCH 28/30] workqueue: implement several utility APIs Tejun Heo
2010-06-14 21:37 ` [PATCH 29/30] libata: take advantage of cmwq and remove concurrency limitations Tejun Heo
2010-06-14 21:37 ` [PATCH 30/30] async: use workqueue for worker pool Tejun Heo
2010-06-14 21:58 ` [PATCHSET] workqueue: concurrency managed workqueue, take#5 Andrew Morton
2010-06-14 22:17 ` Tejun Heo
2010-06-14 22:31 ` Daniel Walker
2010-06-14 22:33 ` Tejun Heo
2010-06-14 22:35 ` Daniel Walker
2010-06-14 22:44 ` Tejun Heo
2010-06-14 22:49 ` Daniel Walker
2010-06-14 22:52 ` Tejun Heo
2010-06-14 22:35 ` Andrew Morton
2010-06-14 22:43 ` Tejun Heo
2010-06-14 23:06 ` Andrew Morton
2010-06-15 12:53 ` tytso
2010-06-15 16:15 ` [PATCH] SubmittingPatches: add more about patch descriptions Randy Dunlap
2010-06-15 16:33 ` Christoph Lameter
2010-06-15 18:15 ` [PATCHSET] workqueue: concurrency managed workqueue, take#5 Stefan Richter
2010-06-15 19:39 ` Tejun Heo
2010-06-15 1:20 ` Jeff Garzik
2010-06-15 18:25 ` Overview of concurrency managed workqueue Tejun Heo
2010-06-15 18:40 ` Christoph Lameter
2010-06-15 18:44 ` Tejun Heo
2010-06-15 19:43 ` Daniel Walker
2010-06-16 12:10 ` Tejun Heo
2010-06-16 13:27 ` Daniel Walker
2010-06-16 13:30 ` Tejun Heo
2010-06-16 13:41 ` Daniel Walker
2010-06-16 13:45 ` Tejun Heo
2010-06-16 14:05 ` Daniel Walker
2010-06-16 14:15 ` Tejun Heo
2010-06-16 14:34 ` Daniel Walker
2010-06-16 14:50 ` Tejun Heo
2010-06-16 15:11 ` Daniel Walker
2010-06-16 15:50 ` Tejun Heo
2010-06-16 16:30 ` Daniel Walker
2010-06-16 16:55 ` Tejun Heo
2010-06-16 18:22 ` Daniel Walker
2010-06-16 18:46 ` Tejun Heo
2010-06-16 19:20 ` Tejun Heo
2010-06-16 19:46 ` Daniel Walker
2010-06-16 19:58 ` Tejun Heo
2010-06-17 5:29 ` Florian Mickler
2010-06-17 6:21 ` Florian Mickler
2010-06-17 8:28 ` Tejun Heo
2010-06-17 18:03 ` Daniel Walker
2010-06-18 6:36 ` Florian Mickler
2010-06-18 16:38 ` Daniel Walker
2010-06-16 19:36 ` Daniel Walker
2010-06-16 19:52 ` Tejun Heo
2010-06-16 20:19 ` Daniel Walker
2010-06-16 20:24 ` Tejun Heo
2010-06-16 20:40 ` Daniel Walker
2010-06-16 21:41 ` Tejun Heo
2010-06-17 23:15 ` Andrew Morton
2010-06-18 8:03 ` Tejun Heo
2010-06-18 8:22 ` Tejun Heo
2010-06-18 17:29 ` Daniel Walker
2010-06-16 18:31 ` Stefan Richter
2010-06-16 18:41 ` Daniel Walker
2010-06-17 12:01 ` Andy Walls
2010-06-17 16:56 ` Daniel Walker
2010-06-17 23:16 ` Andrew Morton
2010-06-18 7:16 ` Tejun Heo
2010-06-18 7:31 ` Andrew Morton
2010-06-18 8:09 ` Tejun Heo
2010-06-18 17:02 ` Andrew Morton
2010-06-18 17:28 ` Tejun Heo
2010-06-19 15:53 ` [PATCH] kthread: implement kthread_worker Tejun Heo
2010-06-21 20:33 ` Randy Dunlap
2010-06-22 7:31 ` Tejun Heo
2010-06-19 8:38 ` Overview of concurrency managed workqueue Andi Kleen
2010-06-19 8:40 ` Tejun Heo
2010-06-19 8:55 ` Andi Kleen
2010-06-19 9:01 ` Tejun Heo
2010-06-19 9:08 ` Andi Kleen
2010-06-19 9:12 ` Tejun Heo
2010-06-19 9:15 ` Andi Kleen
2010-06-19 9:17 ` Tejun Heo
2010-06-19 9:27 ` Andi Kleen
2010-06-19 9:42 ` Tejun Heo
2010-06-19 12:20 ` Andi Kleen
2010-06-19 12:48 ` Tejun Heo
2010-06-17 22:28 ` Daniel Walker
2010-06-16 6:55 ` Florian Mickler
2010-06-16 12:22 ` Tejun Heo
2010-06-16 13:37 ` Johannes Berg
2010-06-16 13:39 ` Tejun Heo
2010-06-16 13:42 ` Johannes Berg
2010-06-17 23:14 ` Andrew Morton
2010-06-17 23:25 ` Joel Becker
2010-06-17 23:56 ` Andrew Morton
2010-06-18 7:15 ` Tejun Heo
2010-06-18 7:31 ` Tejun Heo
2010-06-15 18:29 ` [PATCHSET] workqueue: concurrency managed workqueue, take#5 Stefan Richter
2010-06-15 18:40 ` Tejun Heo
2010-06-15 20:29 ` Stefan Richter
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=1276551467-21246-26-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=ak@linux.intel.com \
--cc=akpm@linux-foundation.org \
--cc=arjan@linux.intel.com \
--cc=awalls@radix.net \
--cc=axboe@kernel.dk \
--cc=cl@linux-foundation.org \
--cc=dhowells@redhat.com \
--cc=jeff@garzik.org \
--cc=johannes@sipsolutions.net \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=oleg@redhat.com \
--cc=rusty@rustcorp.com.au \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
/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.