diff options
-rw-r--r-- | include/linux/workqueue.h | 8 | ||||
-rw-r--r-- | kernel/workqueue.c | 14 |
2 files changed, 16 insertions, 6 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index ab95fef38d56..f562674db404 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -68,9 +68,15 @@ enum { | |||
68 | WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + | 68 | WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + |
69 | WORK_STRUCT_COLOR_BITS, | 69 | WORK_STRUCT_COLOR_BITS, |
70 | 70 | ||
71 | /* data contains off-queue information when !WORK_STRUCT_CWQ */ | ||
72 | WORK_OFFQ_FLAG_BASE = WORK_STRUCT_FLAG_BITS, | ||
73 | WORK_OFFQ_FLAG_BITS = 0, | ||
74 | WORK_OFFQ_CPU_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS, | ||
75 | |||
76 | /* convenience constants */ | ||
71 | WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, | 77 | WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, |
72 | WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, | 78 | WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, |
73 | WORK_STRUCT_NO_CPU = WORK_CPU_NONE << WORK_STRUCT_FLAG_BITS, | 79 | WORK_STRUCT_NO_CPU = (unsigned long)WORK_CPU_NONE << WORK_OFFQ_CPU_SHIFT, |
74 | 80 | ||
75 | /* bit mask for work_busy() return values */ | 81 | /* bit mask for work_busy() return values */ |
76 | WORK_BUSY_PENDING = 1 << 0, | 82 | WORK_BUSY_PENDING = 1 << 0, |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0f50f4078e36..eeae77079483 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -533,9 +533,9 @@ static int work_next_color(int color) | |||
533 | } | 533 | } |
534 | 534 | ||
535 | /* | 535 | /* |
536 | * A work's data points to the cwq with WORK_STRUCT_CWQ set while the | 536 | * While queued, %WORK_STRUCT_CWQ is set and non flag bits of a work's data |
537 | * work is on queue. Once execution starts, WORK_STRUCT_CWQ is | 537 | * contain the pointer to the queued cwq. Once execution starts, the flag |
538 | * cleared and the work data contains the cpu number it was last on. | 538 | * is cleared and the high bits contain OFFQ flags and CPU number. |
539 | * | 539 | * |
540 | * set_work_cwq(), set_work_cpu_and_clear_pending() and clear_work_data() | 540 | * set_work_cwq(), set_work_cpu_and_clear_pending() and clear_work_data() |
541 | * can be used to set the cwq, cpu or clear work->data. These functions | 541 | * can be used to set the cwq, cpu or clear work->data. These functions |
@@ -565,7 +565,7 @@ static void set_work_cwq(struct work_struct *work, | |||
565 | static void set_work_cpu_and_clear_pending(struct work_struct *work, | 565 | static void set_work_cpu_and_clear_pending(struct work_struct *work, |
566 | unsigned int cpu) | 566 | unsigned int cpu) |
567 | { | 567 | { |
568 | set_work_data(work, cpu << WORK_STRUCT_FLAG_BITS, 0); | 568 | set_work_data(work, (unsigned long)cpu << WORK_OFFQ_CPU_SHIFT, 0); |
569 | } | 569 | } |
570 | 570 | ||
571 | static void clear_work_data(struct work_struct *work) | 571 | static void clear_work_data(struct work_struct *work) |
@@ -592,7 +592,7 @@ static struct global_cwq *get_work_gcwq(struct work_struct *work) | |||
592 | return ((struct cpu_workqueue_struct *) | 592 | return ((struct cpu_workqueue_struct *) |
593 | (data & WORK_STRUCT_WQ_DATA_MASK))->pool->gcwq; | 593 | (data & WORK_STRUCT_WQ_DATA_MASK))->pool->gcwq; |
594 | 594 | ||
595 | cpu = data >> WORK_STRUCT_FLAG_BITS; | 595 | cpu = data >> WORK_OFFQ_CPU_SHIFT; |
596 | if (cpu == WORK_CPU_NONE) | 596 | if (cpu == WORK_CPU_NONE) |
597 | return NULL; | 597 | return NULL; |
598 | 598 | ||
@@ -3724,6 +3724,10 @@ static int __init init_workqueues(void) | |||
3724 | unsigned int cpu; | 3724 | unsigned int cpu; |
3725 | int i; | 3725 | int i; |
3726 | 3726 | ||
3727 | /* make sure we have enough bits for OFFQ CPU number */ | ||
3728 | BUILD_BUG_ON((1LU << (BITS_PER_LONG - WORK_OFFQ_CPU_SHIFT)) < | ||
3729 | WORK_CPU_LAST); | ||
3730 | |||
3727 | cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP); | 3731 | cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP); |
3728 | cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN); | 3732 | cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN); |
3729 | 3733 | ||