diff options
author | Tejun Heo <tj@kernel.org> | 2010-06-29 04:07:13 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-06-29 04:07:13 -0400 |
commit | 502ca9d819792e7d79b6e002afe9094c641fe410 (patch) | |
tree | 5f06a8845643f1007ce9807636cde4057f8761a9 /include/linux/workqueue.h | |
parent | db7bccf45cb87522096b8f43144e31ca605a9f24 (diff) |
workqueue: make single thread workqueue shared worker pool friendly
Reimplement st (single thread) workqueue so that it's friendly to
shared worker pool. It was originally implemented by confining st
workqueues to use cwq of a fixed cpu and always having a worker for
the cpu. This implementation isn't very friendly to shared worker
pool and suboptimal in that it ends up crossing cpu boundaries often.
Reimplement st workqueue using dynamic single cpu binding and
cwq->limit. WQ_SINGLE_THREAD is replaced with WQ_SINGLE_CPU. In a
single cpu workqueue, at most single cwq is bound to the wq at any
given time. Arbitration is done using atomic accesses to
wq->single_cpu when queueing a work. Once bound, the binding stays
till the workqueue is drained.
Note that the binding is never broken while a workqueue is frozen.
This is because idle cwqs may have works waiting in delayed_works
queue while frozen. On thaw, the cwq is restarted if there are any
delayed works or unbound otherwise.
When combined with max_active limit of 1, single cpu workqueue has
exactly the same execution properties as the original single thread
workqueue while allowing sharing of per-cpu workers.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'include/linux/workqueue.h')
-rw-r--r-- | include/linux/workqueue.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index ab0b7fb99bc2..10611f7fc809 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -221,7 +221,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } | |||
221 | 221 | ||
222 | enum { | 222 | enum { |
223 | WQ_FREEZEABLE = 1 << 0, /* freeze during suspend */ | 223 | WQ_FREEZEABLE = 1 << 0, /* freeze during suspend */ |
224 | WQ_SINGLE_THREAD = 1 << 1, /* no per-cpu worker */ | 224 | WQ_SINGLE_CPU = 1 << 1, /* only single cpu at a time */ |
225 | }; | 225 | }; |
226 | 226 | ||
227 | extern struct workqueue_struct * | 227 | extern struct workqueue_struct * |
@@ -250,9 +250,9 @@ __create_workqueue_key(const char *name, unsigned int flags, int max_active, | |||
250 | #define create_workqueue(name) \ | 250 | #define create_workqueue(name) \ |
251 | __create_workqueue((name), 0, 1) | 251 | __create_workqueue((name), 0, 1) |
252 | #define create_freezeable_workqueue(name) \ | 252 | #define create_freezeable_workqueue(name) \ |
253 | __create_workqueue((name), WQ_FREEZEABLE | WQ_SINGLE_THREAD, 1) | 253 | __create_workqueue((name), WQ_FREEZEABLE | WQ_SINGLE_CPU, 1) |
254 | #define create_singlethread_workqueue(name) \ | 254 | #define create_singlethread_workqueue(name) \ |
255 | __create_workqueue((name), WQ_SINGLE_THREAD, 1) | 255 | __create_workqueue((name), WQ_SINGLE_CPU, 1) |
256 | 256 | ||
257 | extern void destroy_workqueue(struct workqueue_struct *wq); | 257 | extern void destroy_workqueue(struct workqueue_struct *wq); |
258 | 258 | ||