aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/workqueue.h
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2009-11-15 11:09:48 -0500
committerTejun Heo <tj@kernel.org>2009-11-15 11:09:48 -0500
commitdc186ad741c12ae9ecac8b89e317ef706fdaf8f6 (patch)
treef118cc4972031c681b201d2b8ed95b21df41c1be /include/linux/workqueue.h
parenta9366e61b03f55a6e009e687ad10e706714c9907 (diff)
workqueue: Add debugobjects support
Add debugobject support to track the life time of work_structs. While at it, remove duplicate definition of INIT_DELAYED_WORK_ON_STACK(). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'include/linux/workqueue.h')
-rw-r--r--include/linux/workqueue.h38
1 files changed, 27 insertions, 11 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index cf24c20de9e4..9466e860d8c2 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -25,6 +25,7 @@ typedef void (*work_func_t)(struct work_struct *work);
25struct work_struct { 25struct work_struct {
26 atomic_long_t data; 26 atomic_long_t data;
27#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ 27#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */
28#define WORK_STRUCT_STATIC 1 /* static initializer (debugobjects) */
28#define WORK_STRUCT_FLAG_MASK (3UL) 29#define WORK_STRUCT_FLAG_MASK (3UL)
29#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) 30#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
30 struct list_head entry; 31 struct list_head entry;
@@ -35,6 +36,7 @@ struct work_struct {
35}; 36};
36 37
37#define WORK_DATA_INIT() ATOMIC_LONG_INIT(0) 38#define WORK_DATA_INIT() ATOMIC_LONG_INIT(0)
39#define WORK_DATA_STATIC_INIT() ATOMIC_LONG_INIT(2)
38 40
39struct delayed_work { 41struct delayed_work {
40 struct work_struct work; 42 struct work_struct work;
@@ -63,7 +65,7 @@ struct execute_work {
63#endif 65#endif
64 66
65#define __WORK_INITIALIZER(n, f) { \ 67#define __WORK_INITIALIZER(n, f) { \
66 .data = WORK_DATA_INIT(), \ 68 .data = WORK_DATA_STATIC_INIT(), \
67 .entry = { &(n).entry, &(n).entry }, \ 69 .entry = { &(n).entry, &(n).entry }, \
68 .func = (f), \ 70 .func = (f), \
69 __WORK_INIT_LOCKDEP_MAP(#n, &(n)) \ 71 __WORK_INIT_LOCKDEP_MAP(#n, &(n)) \
@@ -91,6 +93,14 @@ struct execute_work {
91#define PREPARE_DELAYED_WORK(_work, _func) \ 93#define PREPARE_DELAYED_WORK(_work, _func) \
92 PREPARE_WORK(&(_work)->work, (_func)) 94 PREPARE_WORK(&(_work)->work, (_func))
93 95
96#ifdef CONFIG_DEBUG_OBJECTS_WORK
97extern void __init_work(struct work_struct *work, int onstack);
98extern void destroy_work_on_stack(struct work_struct *work);
99#else
100static inline void __init_work(struct work_struct *work, int onstack) { }
101static inline void destroy_work_on_stack(struct work_struct *work) { }
102#endif
103
94/* 104/*
95 * initialize all of a work item in one go 105 * initialize all of a work item in one go
96 * 106 *
@@ -99,24 +109,36 @@ struct execute_work {
99 * to generate better code. 109 * to generate better code.
100 */ 110 */
101#ifdef CONFIG_LOCKDEP 111#ifdef CONFIG_LOCKDEP
102#define INIT_WORK(_work, _func) \ 112#define __INIT_WORK(_work, _func, _onstack) \
103 do { \ 113 do { \
104 static struct lock_class_key __key; \ 114 static struct lock_class_key __key; \
105 \ 115 \
116 __init_work((_work), _onstack); \
106 (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ 117 (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
107 lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\ 118 lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\
108 INIT_LIST_HEAD(&(_work)->entry); \ 119 INIT_LIST_HEAD(&(_work)->entry); \
109 PREPARE_WORK((_work), (_func)); \ 120 PREPARE_WORK((_work), (_func)); \
110 } while (0) 121 } while (0)
111#else 122#else
112#define INIT_WORK(_work, _func) \ 123#define __INIT_WORK(_work, _func, _onstack) \
113 do { \ 124 do { \
125 __init_work((_work), _onstack); \
114 (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ 126 (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
115 INIT_LIST_HEAD(&(_work)->entry); \ 127 INIT_LIST_HEAD(&(_work)->entry); \
116 PREPARE_WORK((_work), (_func)); \ 128 PREPARE_WORK((_work), (_func)); \
117 } while (0) 129 } while (0)
118#endif 130#endif
119 131
132#define INIT_WORK(_work, _func) \
133 do { \
134 __INIT_WORK((_work), (_func), 0); \
135 } while (0)
136
137#define INIT_WORK_ON_STACK(_work, _func) \
138 do { \
139 __INIT_WORK((_work), (_func), 1); \
140 } while (0)
141
120#define INIT_DELAYED_WORK(_work, _func) \ 142#define INIT_DELAYED_WORK(_work, _func) \
121 do { \ 143 do { \
122 INIT_WORK(&(_work)->work, (_func)); \ 144 INIT_WORK(&(_work)->work, (_func)); \
@@ -125,22 +147,16 @@ struct execute_work {
125 147
126#define INIT_DELAYED_WORK_ON_STACK(_work, _func) \ 148#define INIT_DELAYED_WORK_ON_STACK(_work, _func) \
127 do { \ 149 do { \
128 INIT_WORK(&(_work)->work, (_func)); \ 150 INIT_WORK_ON_STACK(&(_work)->work, (_func)); \
129 init_timer_on_stack(&(_work)->timer); \ 151 init_timer_on_stack(&(_work)->timer); \
130 } while (0) 152 } while (0)
131 153
132#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \ 154#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \
133 do { \ 155 do { \
134 INIT_WORK(&(_work)->work, (_func)); \ 156 INIT_WORK(&(_work)->work, (_func)); \
135 init_timer_deferrable(&(_work)->timer); \ 157 init_timer_deferrable(&(_work)->timer); \
136 } while (0) 158 } while (0)
137 159
138#define INIT_DELAYED_WORK_ON_STACK(_work, _func) \
139 do { \
140 INIT_WORK(&(_work)->work, (_func)); \
141 init_timer_on_stack(&(_work)->timer); \
142 } while (0)
143
144/** 160/**
145 * work_pending - Find out whether a work item is currently pending 161 * work_pending - Find out whether a work item is currently pending
146 * @work: The work item in question 162 * @work: The work item in question