summaryrefslogtreecommitdiff
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-06-24 20:39:24 +0200
committerClark Williams <williams@redhat.com>2012-01-16 13:00:19 -0600
commit57589fcf4ec94946f1cd32e98b341bea7d7cf629 (patch)
tree3a020320ef17a8b72ae65e6d326536e399d002a9 /kernel/workqueue.c
parent5bda3abd439784dfc40da88b535dd9f271296189 (diff)
workqueue-avoid-the-lock-in-cpu-dying.patch
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 94eadf426eb3..700b9ac4dfa3 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3507,6 +3507,25 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
kthread_stop(new_trustee);
return NOTIFY_BAD;
}
+ break;
+ case CPU_POST_DEAD:
+ case CPU_UP_CANCELED:
+ case CPU_DOWN_FAILED:
+ case CPU_ONLINE:
+ break;
+ case CPU_DYING:
+ /*
+ * We access this lockless. We are on the dying CPU
+ * and called from stomp machine.
+ *
+ * Before this, the trustee and all workers except for
+ * the ones which are still executing works from
+ * before the last CPU down must be on the cpu. After
+ * this, they'll all be diasporas.
+ */
+ gcwq->flags |= GCWQ_DISASSOCIATED;
+ default:
+ goto out;
}
/* some are called w/ irq disabled, don't disturb irq status */
@@ -3526,16 +3545,6 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
gcwq->first_idle = new_worker;
break;
- case CPU_DYING:
- /*
- * Before this, the trustee and all workers except for
- * the ones which are still executing works from
- * before the last CPU down must be on the cpu. After
- * this, they'll all be diasporas.
- */
- gcwq->flags |= GCWQ_DISASSOCIATED;
- break;
-
case CPU_POST_DEAD:
gcwq->trustee_state = TRUSTEE_BUTCHER;
/* fall through */
@@ -3569,6 +3578,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
spin_unlock_irqrestore(&gcwq->lock, flags);
+out:
return notifier_from_errno(0);
}