Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 33356
b: refs/heads/master
c: 9b41ea7
h: refs/heads/master
v: v3
  • Loading branch information
Andrew Morton authored and Greg Kroah-Hartman committed Aug 14, 2006
1 parent 44699cf commit a459631
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2b25742556b1a351ce4821f6feddcba23bdd930b
refs/heads/master: 9b41ea7289a589993d3daabc61f999b4147872c4
33 changes: 21 additions & 12 deletions trunk/kernel/workqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct workqueue_struct {

/* All the per-cpu workqueues on the system, for hotplug cpu to add/remove
threads to each one as cpus come/go. */
static DEFINE_SPINLOCK(workqueue_lock);
static DEFINE_MUTEX(workqueue_mutex);
static LIST_HEAD(workqueues);

static int singlethread_cpu;
Expand Down Expand Up @@ -320,10 +320,10 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
} else {
int cpu;

lock_cpu_hotplug();
mutex_lock(&workqueue_mutex);
for_each_online_cpu(cpu)
flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
unlock_cpu_hotplug();
mutex_unlock(&workqueue_mutex);
}
}
EXPORT_SYMBOL_GPL(flush_workqueue);
Expand Down Expand Up @@ -371,8 +371,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
}

wq->name = name;
/* We don't need the distraction of CPUs appearing and vanishing. */
lock_cpu_hotplug();
mutex_lock(&workqueue_mutex);
if (singlethread) {
INIT_LIST_HEAD(&wq->list);
p = create_workqueue_thread(wq, singlethread_cpu);
Expand All @@ -381,9 +380,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
else
wake_up_process(p);
} else {
spin_lock(&workqueue_lock);
list_add(&wq->list, &workqueues);
spin_unlock(&workqueue_lock);
for_each_online_cpu(cpu) {
p = create_workqueue_thread(wq, cpu);
if (p) {
Expand All @@ -393,7 +390,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
destroy = 1;
}
}
unlock_cpu_hotplug();
mutex_unlock(&workqueue_mutex);

/*
* Was there any error during startup? If yes then clean up:
Expand Down Expand Up @@ -434,17 +431,15 @@ void destroy_workqueue(struct workqueue_struct *wq)
flush_workqueue(wq);

/* We don't need the distraction of CPUs appearing and vanishing. */
lock_cpu_hotplug();
mutex_lock(&workqueue_mutex);
if (is_single_threaded(wq))
cleanup_workqueue_thread(wq, singlethread_cpu);
else {
for_each_online_cpu(cpu)
cleanup_workqueue_thread(wq, cpu);
spin_lock(&workqueue_lock);
list_del(&wq->list);
spin_unlock(&workqueue_lock);
}
unlock_cpu_hotplug();
mutex_unlock(&workqueue_mutex);
free_percpu(wq->cpu_wq);
kfree(wq);
}
Expand Down Expand Up @@ -515,11 +510,13 @@ int schedule_on_each_cpu(void (*func)(void *info), void *info)
if (!works)
return -ENOMEM;

mutex_lock(&workqueue_mutex);
for_each_online_cpu(cpu) {
INIT_WORK(per_cpu_ptr(works, cpu), func, info);
__queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu),
per_cpu_ptr(works, cpu));
}
mutex_unlock(&workqueue_mutex);
flush_workqueue(keventd_wq);
free_percpu(works);
return 0;
Expand Down Expand Up @@ -635,6 +632,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,

switch (action) {
case CPU_UP_PREPARE:
mutex_lock(&workqueue_mutex);
/* Create a new workqueue thread for it. */
list_for_each_entry(wq, &workqueues, list) {
if (!create_workqueue_thread(wq, hotcpu)) {
Expand All @@ -653,6 +651,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
kthread_bind(cwq->thread, hotcpu);
wake_up_process(cwq->thread);
}
mutex_unlock(&workqueue_mutex);
break;

case CPU_UP_CANCELED:
Expand All @@ -664,13 +663,23 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
any_online_cpu(cpu_online_map));
cleanup_workqueue_thread(wq, hotcpu);
}
mutex_unlock(&workqueue_mutex);
break;

case CPU_DOWN_PREPARE:
mutex_lock(&workqueue_mutex);
break;

case CPU_DOWN_FAILED:
mutex_unlock(&workqueue_mutex);
break;

case CPU_DEAD:
list_for_each_entry(wq, &workqueues, list)
cleanup_workqueue_thread(wq, hotcpu);
list_for_each_entry(wq, &workqueues, list)
take_over_work(wq, hotcpu);
mutex_unlock(&workqueue_mutex);
break;
}

Expand Down

0 comments on commit a459631

Please sign in to comment.