aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-06-29 04:07:11 -0400
committerTejun Heo <tj@kernel.org>2010-06-29 04:07:11 -0400
commit0f900049cbe2767d47c2a62b54f0e822e1d66840 (patch)
treeb7d2ce3e00ef49c038d0641a860b98b4c24fb203 /include
parent1537663f5763892cacf1409ac0efef1b4f332d1e (diff)
workqueue: update cwq alignement
work->data field is used for two purposes. It points to cwq it's queued on and the lower bits are used for flags. Currently, two bits are reserved which is always safe as 4 byte alignment is guaranteed on every architecture. However, future changes will need more flag bits. On SMP, the percpu allocator is capable of honoring larger alignment (there are other users which depend on it) and larger alignment works just fine. On UP, percpu allocator is a thin wrapper around kzalloc/kfree() and don't honor alignment request. This patch introduces WORK_STRUCT_FLAG_BITS and implements alloc/free_cwqs() which guarantees max(1 << WORK_STRUCT_FLAG_BITS, __alignof__(unsigned long long) alignment both on SMP and UP. On SMP, simply wrapping percpu allocator is enough. On UP, extra space is allocated so that cwq can be aligned and the original pointer can be stored after it which is used in the free path. * Alignment problem on UP is reported by Michal Simek. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Frederic Weisbecker <fweisbec@gmail.com> Reported-by: Michal Simek <michal.simek@petalogix.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/workqueue.h5
1 files changed, 4 insertions, 1 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index d60c5701ab45..b90958a037dc 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -26,6 +26,9 @@ enum {
26 WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ 26 WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */
27#ifdef CONFIG_DEBUG_OBJECTS_WORK 27#ifdef CONFIG_DEBUG_OBJECTS_WORK
28 WORK_STRUCT_STATIC_BIT = 1, /* static initializer (debugobjects) */ 28 WORK_STRUCT_STATIC_BIT = 1, /* static initializer (debugobjects) */
29 WORK_STRUCT_FLAG_BITS = 2,
30#else
31 WORK_STRUCT_FLAG_BITS = 1,
29#endif 32#endif
30 33
31 WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, 34 WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT,
@@ -35,7 +38,7 @@ enum {
35 WORK_STRUCT_STATIC = 0, 38 WORK_STRUCT_STATIC = 0,
36#endif 39#endif
37 40
38 WORK_STRUCT_FLAG_MASK = 3UL, 41 WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1,
39 WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, 42 WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
40}; 43};
41 44