aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/workqueue.h
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-07-22 08:14:25 -0400
committerTejun Heo <tj@kernel.org>2010-07-22 16:39:22 -0400
commite120153ddf8620fd0a194d301e9c5a8b28483bb5 (patch)
tree953ef1a61ca29d0486a6c8c3bb72dd8bbc080419 /include/linux/workqueue.h
parentf2e005aaff4878a8ea93d5fb033a21389b72579a (diff)
workqueue: fix how cpu number is stored in work->data
Once a work starts execution, its data contains the cpu number it was on instead of pointing to cwq. This is added by commit 7a22ad75 (workqueue: carry cpu number in work data once execution starts) to reliably determine the work was last on even if the workqueue itself was destroyed inbetween. Whether data points to a cwq or contains a cpu number was distinguished by comparing the value against PAGE_OFFSET. The assumption was that a cpu number should be below PAGE_OFFSET while a pointer to cwq should be above it. However, on architectures which use separate address spaces for user and kernel spaces, this doesn't hold as PAGE_OFFSET is zero. Fix it by using an explicit flag, WORK_STRUCT_CWQ, to mark what the data field contains. If the flag is set, it's pointing to a cwq; otherwise, it contains a cpu number. Reported on s390 and microblaze during linux-next testing. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Sachin Sant <sachinp@in.ibm.com> Reported-by: Michal Simek <michal.simek@petalogix.com> Reported-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Tested-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Tested-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'include/linux/workqueue.h')
-rw-r--r--include/linux/workqueue.h14
1 files changed, 8 insertions, 6 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index d74a529ed13e..5f76001c4e6d 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -25,17 +25,19 @@ typedef void (*work_func_t)(struct work_struct *work);
25 25
26enum { 26enum {
27 WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ 27 WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */
28 WORK_STRUCT_LINKED_BIT = 1, /* next work is linked to this one */ 28 WORK_STRUCT_CWQ_BIT = 1, /* data points to cwq */
29 WORK_STRUCT_LINKED_BIT = 2, /* next work is linked to this one */
29#ifdef CONFIG_DEBUG_OBJECTS_WORK 30#ifdef CONFIG_DEBUG_OBJECTS_WORK
30 WORK_STRUCT_STATIC_BIT = 2, /* static initializer (debugobjects) */ 31 WORK_STRUCT_STATIC_BIT = 3, /* static initializer (debugobjects) */
31 WORK_STRUCT_COLOR_SHIFT = 3, /* color for workqueue flushing */ 32 WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */
32#else 33#else
33 WORK_STRUCT_COLOR_SHIFT = 2, /* color for workqueue flushing */ 34 WORK_STRUCT_COLOR_SHIFT = 3, /* color for workqueue flushing */
34#endif 35#endif
35 36
36 WORK_STRUCT_COLOR_BITS = 4, 37 WORK_STRUCT_COLOR_BITS = 4,
37 38
38 WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, 39 WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT,
40 WORK_STRUCT_CWQ = 1 << WORK_STRUCT_CWQ_BIT,
39 WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, 41 WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT,
40#ifdef CONFIG_DEBUG_OBJECTS_WORK 42#ifdef CONFIG_DEBUG_OBJECTS_WORK
41 WORK_STRUCT_STATIC = 1 << WORK_STRUCT_STATIC_BIT, 43 WORK_STRUCT_STATIC = 1 << WORK_STRUCT_STATIC_BIT,
@@ -56,8 +58,8 @@ enum {
56 WORK_CPU_LAST = WORK_CPU_NONE, 58 WORK_CPU_LAST = WORK_CPU_NONE,
57 59
58 /* 60 /*
59 * Reserve 6 bits off of cwq pointer w/ debugobjects turned 61 * Reserve 7 bits off of cwq pointer w/ debugobjects turned
60 * off. This makes cwqs aligned to 64 bytes which isn't too 62 * off. This makes cwqs aligned to 128 bytes which isn't too
61 * excessive while allowing 15 workqueue flush colors. 63 * excessive while allowing 15 workqueue flush colors.
62 */ 64 */
63 WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + 65 WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT +