diff options
| author | Grant Likely <grant.likely@secretlab.ca> | 2011-02-28 01:36:21 -0700 | 
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2011-02-28 01:36:21 -0700 | 
| commit | 38a5d6736e7f714cc56d58692001e66dcbb98799 (patch) | |
| tree | 337d32375e10b04642013710c2c424514474b32c /kernel/workqueue.c | |
| parent | 0bfd95a2a104dfc2469d68de52df99939371c0d4 (diff) | |
| parent | f5412be599602124d2bdd49947b231dd77c0bf99 (diff) | |
Merge commit 'v2.6.38-rc6' into devicetree/next
Conflicts:
	drivers/spi/pxa2xx_spi_pci.c
Diffstat (limited to 'kernel/workqueue.c')
| -rw-r--r-- | kernel/workqueue.c | 37 | 
1 files changed, 24 insertions, 13 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 11869faa681..ee6578b578a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -79,7 +79,9 @@ enum {  	MAX_IDLE_WORKERS_RATIO	= 4,		/* 1/4 of busy can be idle */  	IDLE_WORKER_TIMEOUT	= 300 * HZ,	/* keep idle ones for 5 mins */ -	MAYDAY_INITIAL_TIMEOUT	= HZ / 100,	/* call for help after 10ms */ +	MAYDAY_INITIAL_TIMEOUT  = HZ / 100 >= 2 ? HZ / 100 : 2, +						/* call for help after 10ms +						   (min two ticks) */  	MAYDAY_INTERVAL		= HZ / 10,	/* and then every 100ms */  	CREATE_COOLDOWN		= HZ,		/* time to breath after fail */  	TRUSTEE_COOLDOWN	= HZ / 10,	/* for trustee draining */ @@ -2047,6 +2049,15 @@ repeat:  				move_linked_works(work, scheduled, &n);  		process_scheduled_works(rescuer); + +		/* +		 * Leave this gcwq.  If keep_working() is %true, notify a +		 * regular worker; otherwise, we end up with 0 concurrency +		 * and stalling the execution. +		 */ +		if (keep_working(gcwq)) +			wake_up_worker(gcwq); +  		spin_unlock_irq(&gcwq->lock);  	} @@ -2956,7 +2967,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name,  	 */  	spin_lock(&workqueue_lock); -	if (workqueue_freezing && wq->flags & WQ_FREEZEABLE) +	if (workqueue_freezing && wq->flags & WQ_FREEZABLE)  		for_each_cwq_cpu(cpu, wq)  			get_cwq(cpu, wq)->max_active = 0; @@ -3068,7 +3079,7 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)  		spin_lock_irq(&gcwq->lock); -		if (!(wq->flags & WQ_FREEZEABLE) || +		if (!(wq->flags & WQ_FREEZABLE) ||  		    !(gcwq->flags & GCWQ_FREEZING))  			get_cwq(gcwq->cpu, wq)->max_active = max_active; @@ -3318,7 +3329,7 @@ static int __cpuinit trustee_thread(void *__gcwq)  	 * want to get it over with ASAP - spam rescuers, wake up as  	 * many idlers as necessary and create new ones till the  	 * worklist is empty.  Note that if the gcwq is frozen, there -	 * may be frozen works in freezeable cwqs.  Don't declare +	 * may be frozen works in freezable cwqs.  Don't declare  	 * completion while frozen.  	 */  	while (gcwq->nr_workers != gcwq->nr_idle || @@ -3576,9 +3587,9 @@ EXPORT_SYMBOL_GPL(work_on_cpu);  /**   * freeze_workqueues_begin - begin freezing workqueues   * - * Start freezing workqueues.  After this function returns, all - * freezeable workqueues will queue new works to their frozen_works - * list instead of gcwq->worklist. + * Start freezing workqueues.  After this function returns, all freezable + * workqueues will queue new works to their frozen_works list instead of + * gcwq->worklist.   *   * CONTEXT:   * Grabs and releases workqueue_lock and gcwq->lock's. @@ -3604,7 +3615,7 @@ void freeze_workqueues_begin(void)  		list_for_each_entry(wq, &workqueues, list) {  			struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); -			if (cwq && wq->flags & WQ_FREEZEABLE) +			if (cwq && wq->flags & WQ_FREEZABLE)  				cwq->max_active = 0;  		} @@ -3615,7 +3626,7 @@ void freeze_workqueues_begin(void)  }  /** - * freeze_workqueues_busy - are freezeable workqueues still busy? + * freeze_workqueues_busy - are freezable workqueues still busy?   *   * Check whether freezing is complete.  This function must be called   * between freeze_workqueues_begin() and thaw_workqueues(). @@ -3624,8 +3635,8 @@ void freeze_workqueues_begin(void)   * Grabs and releases workqueue_lock.   *   * RETURNS: - * %true if some freezeable workqueues are still busy.  %false if - * freezing is complete. + * %true if some freezable workqueues are still busy.  %false if freezing + * is complete.   */  bool freeze_workqueues_busy(void)  { @@ -3645,7 +3656,7 @@ bool freeze_workqueues_busy(void)  		list_for_each_entry(wq, &workqueues, list) {  			struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); -			if (!cwq || !(wq->flags & WQ_FREEZEABLE)) +			if (!cwq || !(wq->flags & WQ_FREEZABLE))  				continue;  			BUG_ON(cwq->nr_active < 0); @@ -3690,7 +3701,7 @@ void thaw_workqueues(void)  		list_for_each_entry(wq, &workqueues, list) {  			struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); -			if (!cwq || !(wq->flags & WQ_FREEZEABLE)) +			if (!cwq || !(wq->flags & WQ_FREEZABLE))  				continue;  			/* restore max_active and repopulate worklist */  | 
