aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/workqueue.h
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-06-29 04:07:13 -0400
committerTejun Heo <tj@kernel.org>2010-06-29 04:07:13 -0400
commit502ca9d819792e7d79b6e002afe9094c641fe410 (patch)
tree5f06a8845643f1007ce9807636cde4057f8761a9 /include/linux/workqueue.h
parentdb7bccf45cb87522096b8f43144e31ca605a9f24 (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.h6
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
222enum { 222enum {
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
227extern struct workqueue_struct * 227extern 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
257extern void destroy_workqueue(struct workqueue_struct *wq); 257extern void destroy_workqueue(struct workqueue_struct *wq);
258 258