Hi, On Friday, 23 February 2007 21:23, Johannes Berg wrote: > Hi, > > > In that case the fastest fix would be to revert the commit in question (and > > some others too), > > Yeah, the same thing exists for uswsusp and regular suspend-to-ram > afaict. Exactly. > > but I don't think it will be satisfactory for the people with > > the ACPI issues related to the resume code ordering. Moreover, it really > > is more reasonable to disable nonboot CPUs after tasks have been frozen > > (I think it's also necessary for the CPU hotplugging with the help of the > > freezer; see below). > > > > I'll try to find a better solution later today. > > Great. I'm looking at it right now, but this is quite complicated. Could you please try the appended patch? It's somewhat hackish, but may work. The idea is to do nothing on CPU unplug if the CPU's worker thread is frozen and later check in the thread itself if it has been replaced by another one. Greetings, Rafael kernel/workqueue.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) Index: linux-2.6.20-mm2/kernel/workqueue.c =================================================================== --- linux-2.6.20-mm2.orig/kernel/workqueue.c 2007-02-23 22:48:50.000000000 +0100 +++ linux-2.6.20-mm2/kernel/workqueue.c 2007-02-24 00:58:57.000000000 +0100 @@ -316,7 +316,13 @@ static int worker_thread(void *__cwq) do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0); for (;;) { - try_to_freeze(); + if (try_to_freeze()) { + /* We've just exited the refrigerator. If our CPU is + * a nonboot one, we might have been replaced. + */ + if (cwq->thread != current) + break; + } prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE); if (!cwq->should_stop && list_empty(&cwq->worklist)) @@ -713,7 +719,7 @@ static void cleanup_workqueue_thread(str int alive = 0; spin_lock_irq(&cwq->lock); - if (cwq->thread != NULL) { + if (cwq->thread != NULL && !frozen(cwq->thread)) { insert_wq_barrier(cwq, &barr, 1); cwq->should_stop = 1; alive = 1;