From a5b56b167b6ab29875294ee11ccca801611eb065 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 24 Aug 2010 14:22:47 +0200 Subject: [PATCH] --- yaml --- r: 210278 b: refs/heads/master c: e41e704bc4f49057fc68b643108366e6e6781aa3 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/workqueue.h | 2 ++ trunk/kernel/workqueue.c | 7 ++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 37a3ce87918e..0d4535bb0c97 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 972fa1c5316d18c8297123e08e9b6930ca34f888 +refs/heads/master: e41e704bc4f49057fc68b643108366e6e6781aa3 diff --git a/trunk/include/linux/workqueue.h b/trunk/include/linux/workqueue.h index 4f9d277bcd9a..c959666eafca 100644 --- a/trunk/include/linux/workqueue.h +++ b/trunk/include/linux/workqueue.h @@ -241,6 +241,8 @@ enum { WQ_HIGHPRI = 1 << 4, /* high priority */ WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ + WQ_DYING = 1 << 6, /* internal: workqueue is dying */ + WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2, diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index cc3456f96c56..362b50d092e2 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -87,7 +87,8 @@ enum { /* * Structure fields follow one of the following exclusion rules. * - * I: Set during initialization and read-only afterwards. + * I: Modifiable by initialization/destruction paths and read-only for + * everyone else. * * P: Preemption protected. Disabling preemption is enough and should * only be modified and accessed from the local cpu. @@ -944,6 +945,9 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, debug_work_activate(work); + if (WARN_ON_ONCE(wq->flags & WQ_DYING)) + return; + /* determine gcwq to use */ if (!(wq->flags & WQ_UNBOUND)) { struct global_cwq *last_gcwq; @@ -2828,6 +2832,7 @@ void destroy_workqueue(struct workqueue_struct *wq) { unsigned int cpu; + wq->flags |= WQ_DYING; flush_workqueue(wq); /*