[PATCH 3/2] fix flush_workqueue() vs CPU_DEAD race
- From: Oleg Nesterov <oleg@xxxxxxxxxx>
- Date: Sat, 30 Dec 2006 19:10:31 +0300
"[PATCH 1/2] reimplement flush_workqueue()" fixed one race when CPU goes down
while flush_cpu_workqueue() plays with it. But there is another problem, CPU
can die before flush_workqueue() has a chance to call flush_cpu_workqueue().
In that case pending work_structs can migrate to CPU which was already checked,
so we should redo the "for_each_online_cpu(cpu)" loop.
Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>
--- mm-6.20-rc2/kernel/workqueue.c~3_race 2006-12-29 18:37:31.000000000 +0300
+++ mm-6.20-rc2/kernel/workqueue.c 2006-12-30 18:09:07.000000000 +0300
@@ -65,6 +65,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 long hotplug_sequence __read_mostly;
static DEFINE_MUTEX(workqueue_mutex);
static LIST_HEAD(workqueues);
@@ -454,10 +455,16 @@ void fastcall flush_workqueue(struct wor
/* Always use first cpu's area. */
flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, singlethread_cpu));
} else {
+ long sequence;
int cpu;
+again:
+ sequence = hotplug_sequence;
for_each_online_cpu(cpu)
flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
+
+ if (unlikely(sequence != hotplug_sequence))
+ goto again;
}
mutex_unlock(&workqueue_mutex);
}
@@ -874,6 +881,7 @@ static int __devinit workqueue_cpu_callb
cleanup_workqueue_thread(wq, hotcpu);
list_for_each_entry(wq, &workqueues, list)
take_over_work(wq, hotcpu);
+ hotplug_sequence++;
break;
case CPU_LOCK_RELEASE:
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
- Prev by Date: [RFC][PATCH] A new memory algorithm for the embedded linux system
- Next by Date: Re: fuse, get_user_pages, flush_anon_page, aliasing caches and all that again
- Previous by thread: [RFC][PATCH] A new memory algorithm for the embedded linux system
- Next by thread: ip_tables init broken
- Index(es):
Relevant Pages
- Re: rc4: lukewarm irq warning during boot
... This should fix that particular bogon: ... if someone unplugs the CPU identified
by ... static int singlethread_cpu; ... if (!create_workqueue_thread(wq, hotcpu))
{ ... (Linux-Kernel) - Re: 2.6.18-rc3-g3b445eea BUG: warning at /usr/src/linux-git/kernel/cpu.c:51/unlock_cpu_h
... if someone unplugs the CPU identified by ... static int singlethread_cpu;
... if (!create_workqueue_thread(wq, hotcpu)) { ... (Linux-Kernel) - Re: [RFC][PATCH][EXPERIMENTAL] CPU hotplug with frozen tasks
... we have a problem with using the CPU hotplug for suspending ... do you mean
frozen due to suspend? ... switch { ... printk("ksoftirqd for %i failed\n",
hotcpu); ... (Linux-Kernel) - [RFC][PATCH][EXPERIMENTAL] CPU hotplug with frozen tasks
... One obvious solution of this problem would be to make the notifiers behave ...
The appended patch introduces such "FROZEN" notfifications, modifies the CPU ... switch
{ ... printk("ksoftirqd for %i failed\n", hotcpu); ... (Linux-Kernel) - [RFC][PATCH 2/4] Revert Changes to kernel/workqueue.c
... "Freedom comes with a price tag of responsibility, which is still a bargain, ...
static int singlethread_cpu; ... cleanup_workqueue_thread(wq, cpu); ...
if (!create_workqueue_thread(wq, hotcpu)) { ... (Linux-Kernel)