[PATCH 25/30] workqueue: increase max_active of keventd and kill current_is_keventd()

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Tejun Heo
Date: Monday, June 14, 2010 - 2:37 pm

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

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 01/30] kthread: implement kthread_data(), Tejun Heo, (Mon Jun 14, 2:37 pm)
[PATCH 09/30] workqueue: kill cpu_populated_map, Tejun Heo, (Mon Jun 14, 2:37 pm)
[PATCH 10/30] workqueue: update cwq alignement, Tejun Heo, (Mon Jun 14, 2:37 pm)
[PATCH 12/30] workqueue: introduce worker, Tejun Heo, (Mon Jun 14, 2:37 pm)
[PATCH 17/30] workqueue: implement worker states, Tejun Heo, (Mon Jun 14, 2:37 pm)
[PATCH 22/30] workqueue: implement WQ_NON_REENTRANT, Tejun Heo, (Mon Jun 14, 2:37 pm)
[PATCH 25/30] workqueue: increase max_active of keventd an ..., Tejun Heo, (Mon Jun 14, 2:37 pm)
[PATCH 30/30] async: use workqueue for worker pool, Tejun Heo, (Mon Jun 14, 2:37 pm)
Re: [PATCH 27/30] workqueue: implement DEBUGFS/workqueue, Frederic Weisbecker, (Tue Jun 15, 6:54 am)
Re: [PATCH] SubmittingPatches: add more about patch descri ..., Christoph Lameter, (Tue Jun 15, 9:33 am)
Overview of concurrency managed workqueue, Tejun Heo, (Tue Jun 15, 11:25 am)
Re: Overview of concurrency managed workqueue, Christoph Lameter, (Tue Jun 15, 11:40 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Tue Jun 15, 11:44 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Tue Jun 15, 12:43 pm)
Re: Overview of concurrency managed workqueue, Florian Mickler, (Tue Jun 15, 11:55 pm)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 5:10 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 5:22 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 6:27 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 6:30 am)
Re: Overview of concurrency managed workqueue, Johannes Berg, (Wed Jun 16, 6:37 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 6:39 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 6:41 am)
Re: Overview of concurrency managed workqueue, Johannes Berg, (Wed Jun 16, 6:42 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 6:45 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 7:05 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 7:15 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 7:34 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 7:50 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 8:11 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 8:50 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 9:30 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 9:55 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 11:22 am)
Re: Overview of concurrency managed workqueue, Stefan Richter, (Wed Jun 16, 11:31 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 11:41 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 11:46 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 12:20 pm)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 12:36 pm)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 12:46 pm)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 12:52 pm)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 12:58 pm)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 1:19 pm)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 1:24 pm)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Wed Jun 16, 1:40 pm)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Wed Jun 16, 2:41 pm)
Re: Overview of concurrency managed workqueue, Florian Mickler, (Wed Jun 16, 10:29 pm)
Re: Overview of concurrency managed workqueue, Florian Mickler, (Wed Jun 16, 11:21 pm)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Thu Jun 17, 1:28 am)
Re: Overview of concurrency managed workqueue, Andy Walls, (Thu Jun 17, 5:01 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Thu Jun 17, 9:56 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Thu Jun 17, 11:03 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Thu Jun 17, 3:28 pm)
Re: Overview of concurrency managed workqueue, Andrew Morton, (Thu Jun 17, 4:14 pm)
Re: Overview of concurrency managed workqueue, Andrew Morton, (Thu Jun 17, 4:15 pm)
Re: Overview of concurrency managed workqueue, Andrew Morton, (Thu Jun 17, 4:16 pm)
Re: Overview of concurrency managed workqueue, Joel Becker, (Thu Jun 17, 4:25 pm)
Re: Overview of concurrency managed workqueue, Andrew Morton, (Thu Jun 17, 4:56 pm)
Re: Overview of concurrency managed workqueue, Florian Mickler, (Thu Jun 17, 11:36 pm)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Fri Jun 18, 12:15 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Fri Jun 18, 12:16 am)
Re: Overview of concurrency managed workqueue, Andrew Morton, (Fri Jun 18, 12:31 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Fri Jun 18, 12:31 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Fri Jun 18, 1:03 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Fri Jun 18, 1:09 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Fri Jun 18, 1:22 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Fri Jun 18, 9:38 am)
Re: Overview of concurrency managed workqueue, Andrew Morton, (Fri Jun 18, 10:02 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Fri Jun 18, 10:28 am)
Re: Overview of concurrency managed workqueue, Daniel Walker, (Fri Jun 18, 10:29 am)
Re: Overview of concurrency managed workqueue, Andi Kleen, (Sat Jun 19, 1:38 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Sat Jun 19, 1:40 am)
Re: Overview of concurrency managed workqueue, Andi Kleen, (Sat Jun 19, 1:55 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Sat Jun 19, 2:01 am)
Re: Overview of concurrency managed workqueue, Andi Kleen, (Sat Jun 19, 2:08 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Sat Jun 19, 2:12 am)
Re: Overview of concurrency managed workqueue, Andi Kleen, (Sat Jun 19, 2:15 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Sat Jun 19, 2:17 am)
Re: Overview of concurrency managed workqueue, Andi Kleen, (Sat Jun 19, 2:27 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Sat Jun 19, 2:42 am)
Re: Overview of concurrency managed workqueue, Andi Kleen, (Sat Jun 19, 5:20 am)
Re: Overview of concurrency managed workqueue, Tejun Heo, (Sat Jun 19, 5:48 am)
[PATCH] kthread: implement kthread_worker, Tejun Heo, (Sat Jun 19, 8:53 am)
Re: [PATCH] kthread: implement kthread_worker, Randy Dunlap, (Mon Jun 21, 1:33 pm)
Re: [PATCH] kthread: implement kthread_worker, Tejun Heo, (Tue Jun 22, 12:31 am)