66 lines
1.9 KiB
Diff
66 lines
1.9 KiB
Diff
From 9f6ccae9560c825e86d38d8af21630080b0b677e Mon Sep 17 00:00:00 2001
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Fri, 24 Jun 2011 20:39:24 +0200
|
|
Subject: [PATCH 125/279] workqueue-avoid-the-lock-in-cpu-dying.patch
|
|
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
---
|
|
kernel/workqueue.c | 30 ++++++++++++++++++++----------
|
|
1 file changed, 20 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
|
|
index 42f7949..fd605fe 100644
|
|
--- a/kernel/workqueue.c
|
|
+++ b/kernel/workqueue.c
|
|
@@ -3512,6 +3512,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 */
|
|
@@ -3531,16 +3550,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 */
|
|
@@ -3574,6 +3583,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
|
|
|
|
spin_unlock_irqrestore(&gcwq->lock, flags);
|
|
|
|
+out:
|
|
return notifier_from_errno(0);
|
|
}
|
|
|